Panagiotis Christopoulos Charitos 14 gadi atpakaļ
vecāks
revīzija
5414a8c977

+ 57 - 58
src/Resources/BuildinMaterialVariable.cpp

@@ -10,77 +10,76 @@
 // Statics                                                                     =
 //==============================================================================
 
-ConstCharPtrHashMap<BuildinMaterialVariable::BuildinVariable>::Type
+ConstCharPtrHashMap<BuildinMaterialVariable::BuildinEnum>::Type
 	BuildinMaterialVariable::buildinNameToEnum = boost::assign::map_list_of
-	("position", BV_POSITION)
-	("tangent", BV_TANGENT)
-	("normal", BV_NORMAL)
-	("texCoords", BV_TEX_COORDS)
-	("modelMat", BV_MODEL_MAT)
-	("viewMat", BV_VIEW_MAT)
-	("projectionMat", BV_PROJECTION_MAT)
-	("modelViewMat", BV_MODELVIEW_MAT)
-	("viewProjectionMat", BV_VIEWPROJECTION_MAT)
-	("normalMat", BV_NORMAL_MAT)
-	("modelViewProjectionMat", BV_MODELVIEWPROJECTION_MAT)
-	("msNormalFai", BV_MS_NORMAL_FAI)
-	("msDiffuseFai", BV_MS_DIFFUSE_FAI)
-	("msSpecularFai", BV_MS_SPECULAR_FAI)
-	("msDepthFai", BV_MS_DEPTH_FAI)
-	("isFai", BV_IS_FAI)
-	("ppsPrePassFai", BV_PPS_PRE_PASS_FAI)
-	("ppsPostPassFai", BV_PPS_POST_PASS_FAI)
-	("rendererSize", BV_RENDERER_SIZE)
-	("sceneAmbientColor", BV_SCENE_AMBIENT_COLOR)
-	("blurring", BV_BLURRING);
-
-
-boost::unordered_map<BuildinMaterialVariable::BuildinVariable, GLenum>
+	("position", POSITION)
+	("tangent", TANGENT)
+	("normal", NORMAL)
+	("texCoords", TEX_COORDS)
+	("modelMat", MODEL_MAT)
+	("viewMat", VIEW_MAT)
+	("projectionMat", PROJECTION_MAT)
+	("modelViewMat", MODELVIEW_MAT)
+	("viewProjectionMat", VIEWPROJECTION_MAT)
+	("normalMat", NORMAL_MAT)
+	("modelViewProjectionMat", MODELVIEWPROJECTION_MAT)
+	("msNormalFai", MS_NORMAL_FAI)
+	("msDiffuseFai", MS_DIFFUSE_FAI)
+	("msSpecularFai", MS_SPECULAR_FAI)
+	("msDepthFai", MS_DEPTH_FAI)
+	("isFai", IS_FAI)
+	("ppsPrePassFai", PPS_PRE_PASS_FAI)
+	("ppsPostPassFai", PPS_POST_PASS_FAI)
+	("rendererSize", RENDERER_SIZE)
+	("sceneAmbientColor", SCENE_AMBIENT_COLOR)
+	("blurring", BLURRING);
+
+
+boost::unordered_map<BuildinMaterialVariable::BuildinEnum, GLenum>
 	BuildinMaterialVariable::buildinToGlType = boost::assign::map_list_of
-	(BV_POSITION, GL_FLOAT_VEC3)
-	(BV_TANGENT, GL_FLOAT_VEC4)
-	(BV_NORMAL, GL_FLOAT_VEC3)
-	(BV_TEX_COORDS, GL_FLOAT_VEC2)
-	(BV_MODEL_MAT, GL_FLOAT_MAT4)
-	(BV_VIEW_MAT, GL_FLOAT_MAT4)
-	(BV_PROJECTION_MAT, GL_FLOAT_MAT4)
-	(BV_PROJECTION_MAT, GL_FLOAT_MAT4)
-	(BV_VIEWPROJECTION_MAT, GL_FLOAT_MAT4)
-	(BV_NORMAL_MAT, GL_FLOAT_MAT3)
-	(BV_MODELVIEWPROJECTION_MAT, GL_FLOAT_MAT4)
-	(BV_MS_NORMAL_FAI, GL_SAMPLER_2D)
-	(BV_MS_DIFFUSE_FAI, GL_SAMPLER_2D)
-	(BV_MS_SPECULAR_FAI, GL_SAMPLER_2D)
-	(BV_MS_DEPTH_FAI, GL_SAMPLER_2D)
-	(BV_IS_FAI, GL_SAMPLER_2D)
-	(BV_PPS_PRE_PASS_FAI, GL_SAMPLER_2D)
-	(BV_PPS_POST_PASS_FAI, GL_SAMPLER_2D)
-	(BV_RENDERER_SIZE, GL_FLOAT_VEC2)
-	(BV_SCENE_AMBIENT_COLOR, GL_FLOAT_VEC3)
-	(BV_BLURRING, GL_FLOAT);
+	(POSITION, GL_FLOAT_VEC3)
+	(TANGENT, GL_FLOAT_VEC4)
+	(NORMAL, GL_FLOAT_VEC3)
+	(TEX_COORDS, GL_FLOAT_VEC2)
+	(MODEL_MAT, GL_FLOAT_MAT4)
+	(VIEW_MAT, GL_FLOAT_MAT4)
+	(PROJECTION_MAT, GL_FLOAT_MAT4)
+	(PROJECTION_MAT, GL_FLOAT_MAT4)
+	(VIEWPROJECTION_MAT, GL_FLOAT_MAT4)
+	(NORMAL_MAT, GL_FLOAT_MAT3)
+	(MODELVIEWPROJECTION_MAT, GL_FLOAT_MAT4)
+	(MS_NORMAL_FAI, GL_SAMPLER_2D)
+	(MS_DIFFUSE_FAI, GL_SAMPLER_2D)
+	(MS_SPECULAR_FAI, GL_SAMPLER_2D)
+	(MS_DEPTH_FAI, GL_SAMPLER_2D)
+	(IS_FAI, GL_SAMPLER_2D)
+	(PPS_PRE_PASS_FAI, GL_SAMPLER_2D)
+	(PPS_POST_PASS_FAI, GL_SAMPLER_2D)
+	(RENDERER_SIZE, GL_FLOAT_VEC2)
+	(SCENE_AMBIENT_COLOR, GL_FLOAT_VEC3)
+	(BLURRING, GL_FLOAT);
 
 
 //==============================================================================
 // Constructor                                                                 =
 //==============================================================================
 BuildinMaterialVariable::BuildinMaterialVariable(
-	const ShaderProgramVariable* cpSProgVar,
-	const ShaderProgramVariable* dpSProgVar,
-	const char* name)
-:	MaterialVariable(T_BUILDIN, cpSProgVar, dpSProgVar),
- 	var(BV_NUM)
+	const char* shaderProgVarName,
+	const ShaderPrograms& shaderProgsArr)
+:	MaterialVariable(BUILDIN, shaderProgVarName, shaderProgsArr),
+ 	bEnum(BUILDINS_NUM)
 {
 	GLenum dataType;
 	// Sanity checks
-	if(!isBuildin(name, &var, &dataType))
+	if(!isBuildin(shaderProgVarName, &bEnum, &dataType))
 	{
-		throw EXCEPTION("The variable is not buildin: " + name);
+		throw EXCEPTION("The variable is not buildin: " + shaderProgVarName);
 	}
 
 	if(dataType != getGlDataType())
 	{
-		throw EXCEPTION("The buildin variable \"" + name +
-			"\" sould be of type: " +
+		throw EXCEPTION("The buildin variable \"" + shaderProgVarName +
+			"\" should be of type: " +
 			boost::lexical_cast<std::string>(dataType));
 	}
 }
@@ -90,9 +89,9 @@ BuildinMaterialVariable::BuildinMaterialVariable(
 // isBuildin                                                                   =
 //==============================================================================
 bool BuildinMaterialVariable::isBuildin(const char* name,
-	BuildinVariable* var, GLenum* dataType)
+	BuildinEnum* var, GLenum* dataType)
 {
-	ConstCharPtrHashMap<BuildinVariable>::Type::const_iterator it =
+	ConstCharPtrHashMap<BuildinEnum>::Type::const_iterator it =
 		buildinNameToEnum.find(name);
 
 	if(it == buildinNameToEnum.end())
@@ -107,7 +106,7 @@ bool BuildinMaterialVariable::isBuildin(const char* name,
 
 	if(dataType)
 	{
-		boost::unordered_map<BuildinVariable, GLenum>::const_iterator it2 =
+		boost::unordered_map<BuildinEnum, GLenum>::const_iterator it2 =
 			buildinToGlType.find(it->second);
 
 		ASSERT(it2 != buildinToGlType.end());

+ 33 - 32
src/Resources/BuildinMaterialVariable.h

@@ -10,56 +10,57 @@
 class BuildinMaterialVariable: public MaterialVariable
 {
 	public:
-		/// Standard attribute variables that are acceptable inside the @ref
-		/// ShaderProg
-		enum BuildinVariable
+		/// Standard attribute variables that are acceptable inside the
+		/// ShaderProgram
+		enum BuildinEnum
 		{
 			// Attributes
-			BV_POSITION,
-			BV_TANGENT,
-			BV_NORMAL,
-			BV_TEX_COORDS,
+			POSITION,
+			TANGENT,
+			NORMAL,
+			TEX_COORDS,
 			// Uniforms
 			// Matrices
-			BV_MODEL_MAT,
-			BV_VIEW_MAT,
-			BV_PROJECTION_MAT,
-			BV_MODELVIEW_MAT,
-			BV_VIEWPROJECTION_MAT,
-			BV_NORMAL_MAT,
-			BV_MODELVIEWPROJECTION_MAT,
+			MODEL_MAT,
+			VIEW_MAT,
+			PROJECTION_MAT,
+			MODELVIEW_MAT,
+			VIEWPROJECTION_MAT,
+			NORMAL_MAT,
+			MODELVIEWPROJECTION_MAT,
 			// FAIs (for materials in blending stage)
-			BV_MS_NORMAL_FAI,
-			BV_MS_DIFFUSE_FAI,
-			BV_MS_SPECULAR_FAI,
-			BV_MS_DEPTH_FAI,
-			BV_IS_FAI,
-			BV_PPS_PRE_PASS_FAI,
-			BV_PPS_POST_PASS_FAI,
+			MS_NORMAL_FAI,
+			MS_DIFFUSE_FAI,
+			MS_SPECULAR_FAI,
+			MS_DEPTH_FAI,
+			IS_FAI,
+			PPS_PRE_PASS_FAI,
+			PPS_POST_PASS_FAI,
 			// Other
-			BV_RENDERER_SIZE,
-			BV_SCENE_AMBIENT_COLOR,
-			BV_BLURRING,
+			RENDERER_SIZE,
+			SCENE_AMBIENT_COLOR,
+			BLURRING,
 			// num
-			BV_NUM ///< The number of all variables
+			BUILDINS_NUM ///< The number of all buildin variables
 		};
 
-		BuildinMaterialVariable(const ShaderProgramVariable* cpSProgVar,
-			const ShaderProgramVariable* dpSProgVar, const char* name);
+		BuildinMaterialVariable(
+			const char* shaderProgVarName,
+			const ShaderPrograms& shaderProgsArr);
 
-		GETTER_R_BY_VAL(BuildinVariable, var, getVariableEnum)
+		GETTER_R_BY_VAL(BuildinEnum, bEnum, getVariableEnum)
 
-		static bool isBuildin(const char* name, BuildinVariable* var = NULL,
+		static bool isBuildin(const char* name, BuildinEnum* var = NULL,
 			GLenum* dataType = NULL);
 
 	private:
 		/// Given a name of a variable find its BuildinVariable enum
-		static ConstCharPtrHashMap<BuildinVariable>::Type buildinNameToEnum;
+		static ConstCharPtrHashMap<BuildinEnum>::Type buildinNameToEnum;
 
 		/// Given a BuildinVariable enum it gives the GL type
-		static boost::unordered_map<BuildinVariable, GLenum> buildinToGlType;
+		static boost::unordered_map<BuildinEnum, GLenum> buildinToGlType;
 
-		BuildinVariable var;
+		BuildinEnum bEnum;
 };
 
 

+ 43 - 20
src/Resources/Material.cpp

@@ -10,6 +10,7 @@
 #include <boost/property_tree/xml_parser.hpp>
 #include <boost/assign/list_of.hpp>
 #include <boost/functional/hash.hpp>
+#include <algorithm>
 
 
 //==============================================================================
@@ -47,6 +48,9 @@ Material::Material()
 	depthTesting = true;
 	wireframe = false;
 	castsShadowFlag = true;
+
+	// Reset tha array
+	std::fill(buildinsArr.begin(), buildinsArr.end(), NULL);
 }
 
 
@@ -174,14 +178,13 @@ void Material::parseMaterialTag(const boost::property_tree::ptree& pt)
 	std::string cfile = createShaderProgSourceToCache(cpSrc);
 	std::string dfile = createShaderProgSourceToCache(dpSrc);
 
-	cpShaderProg.loadRsrc(cfile.c_str());
-	dpShaderProg.loadRsrc(dfile.c_str());
+	sProgs[MaterialVariable::COLOR_PASS].loadRsrc(cfile.c_str());
+	sProgs[MaterialVariable::DEPTH_PASS].loadRsrc(dfile.c_str());
 
-	INFO(cpShaderProg->getShaderInfoString());
-	INFO(dpShaderProg->getShaderInfoString());
+	/*INFO(cpShaderProg->getShaderInfoString());
+	INFO(dpShaderProg->getShaderInfoString());*/
 
-	//boost::optional<>
-	getVariables(pt.get_child("shaderProgram.inputs"));
+	populateVariables(pt.get_child("shaderProgram.inputs"));
 }
 
 
@@ -220,18 +223,29 @@ std::string Material::createShaderProgSourceToCache(const std::string& source)
 
 
 //==============================================================================
-// getVariables                                                                =
+// populateVariables                                                           =
 //==============================================================================
-void Material::getVariables(const boost::property_tree::ptree& pt)
+void Material::populateVariables(const boost::property_tree::ptree& pt)
 {
 	using namespace boost::property_tree;
 
+	//
+	// Get all names of all shader prog vars. Dont duplicate
+	//
+	std::map<std::string, bool> allVarNames;
+
+	BOOST_FOREACH(const RsrcPtr<ShaderProgram>& sProg, sProgs)
+	{
+		BOOST_FOREACH(const ShaderProgramVariable)
+	}
+
+	// Iterate shader program variables
 	BOOST_FOREACH(const ShaderProgramVariable& sv,
-		cpShaderProg->getVariables())
+		cpShaderProg->populateVariables())
 	{
 		const char* svName = sv.getName().c_str();
 
-		// XXX
+		// Get (if exists) the depth pass shader variable
 		const ShaderProgramVariable* dpSv = NULL;
 		if(dpShaderProg->variableExists(svName))
 		{
@@ -240,17 +254,22 @@ void Material::getVariables(const boost::property_tree::ptree& pt)
 
 		MaterialVariable* mv = NULL;
 
-		// Buildin or user defined?
+		// Buildin?
 		if(BuildinMaterialVariable::isBuildin(svName))
 		{
-			mv = new BuildinMaterialVariable(&sv, dpSv, svName);
+			BuildinMaterialVariable* v =
+				new BuildinMaterialVariable(&sv, dpSv, svName);
+
+			mtlVars.push_back(v);
+			buildinsArr[v->getVariableEnum()] = v;
 		}
+		// User defined
 		else
 		{
 			// Get uniforms
 			if(sv.getType() != ShaderProgramVariable::SVT_UNIFORM)
 			{
-				throw EXCEPTION("XXX"); // XXX
+				throw EXCEPTION("Variable should be uniform: " + sv.getName());
 			}
 
 			const UniformShaderProgramVariable* uniC =
@@ -270,7 +289,7 @@ void Material::getVariables(const boost::property_tree::ptree& pt)
 			{
 				if(v.first != "input")
 				{
-					throw EXCEPTION("XXX"); // XXX
+					throw EXCEPTION("Error parsing the property_tree");
 				}
 
 				if(v.second.get<std::string>("name") == svName)
@@ -286,38 +305,42 @@ void Material::getVariables(const boost::property_tree::ptree& pt)
 					svName);
 			}
 
+			UserMaterialVariable* v = NULL;
 			// Get the value
 			switch(sv.getGlDataType())
 			{
 				// sampler2D
 				case GL_SAMPLER_2D:
-					mv = new UserMaterialVariable(uniC, uniD,
+					v = new UserMaterialVariable(uniC, uniD,
 						valuePt->get<std::string>("sampler2D").c_str());
 					break;
 				// float
 				case GL_FLOAT:
-					mv = new UserMaterialVariable(uniC, uniD,
+					v = new UserMaterialVariable(uniC, uniD,
 						PropertyTree::getFloat(*valuePt));
 					break;
 				// vec2
 				case GL_FLOAT_VEC2:
-					mv = new UserMaterialVariable(uniC, uniD,
+					v = new UserMaterialVariable(uniC, uniD,
 						PropertyTree::getVec2(*valuePt));
 					break;
 				// vec3
 				case GL_FLOAT_VEC3:
-					mv = new UserMaterialVariable(uniC, uniD,
+					v = new UserMaterialVariable(uniC, uniD,
 						PropertyTree::getVec3(*valuePt));
 					break;
 				// vec4
 				case GL_FLOAT_VEC4:
-					mv = new UserMaterialVariable(uniC, uniD,
+					v = new UserMaterialVariable(uniC, uniD,
 						PropertyTree::getVec4(*valuePt));
 					break;
 				// default is error
 				default:
 					ASSERT(0);
 			}
+
+			mtlVars.push_back(v);
+			userMtlVars.push_back(v);
 		}
-	}
+	} // end for all sprog vars
 }

+ 29 - 15
src/Resources/Material.h

@@ -111,6 +111,8 @@ class Material: private MaterialProperties
 		typedef boost::unordered_map<BuildinMaterialVariable::BuildinVariable,
 			BuildinMaterialVariable*> BuildinEnumToBuildinHashMap;
 
+		typedef Vec<RsrcPtr<ShaderProgram> > ShaderProgams;
+
 		//======================================================================
 		// Methods                                                             =
 		//======================================================================
@@ -129,9 +131,6 @@ class Material: private MaterialProperties
 		GETTER_R_BY_VAL(bool, depthTesting, isDepthTestingEnabled)
 		GETTER_R_BY_VAL(bool, wireframe, isWireframeEnabled)
 
-		GETTER_R(VarsContainer, mtlVars, getVariables)
-		GETTER_R(Vec<UserMaterialVariable*>, userMtlVars, getUserVariables)
-
 		/// Access the base class just for copying in other classes
 		GETTER_R(MaterialProperties, *this, accessMaterialPropertiesBaseClass)
 
@@ -140,6 +139,12 @@ class Material: private MaterialProperties
 
 		const ShaderProgram& getDepthPassShaderProgram() const
 			{return *dpShaderProg;}
+
+		// Variable accessors
+		GETTER_R(VarsContainer, mtlVars, getVariables)
+		GETTER_R(Vec<UserMaterialVariable*>, userMtlVars, getUserVariables)
+		const BuildinMaterialVariable& getBuildinVariable(
+			BuildinMaterialVariable::BuildinVariable e) const;
 		/// @}
 
 		/// Return false if blendingSfactor is equal to GL_ONE and
@@ -149,27 +154,28 @@ class Material: private MaterialProperties
 		/// Load a material file
 		void load(const char* filename);
 
-	public: /// XXX
+		/// Check if a buildin variable exists
+		bool buildinVariableExits(BuildinMaterialVariable::BuildinVariable e)
+			const {return buildinsArr[e] != NULL;}
+
+	private:
 		//======================================================================
 		// Members                                                             =
 		//======================================================================
 
+		/// From "GL_ZERO" return GL_ZERO
+		static ConstCharPtrHashMap<GLenum>::Type txtToBlengGlEnum;
+
 		/// All the material variables. Both buildins and user
 		VarsContainer mtlVars;
 
-		BuildinEnumToBuildinHashMap enumToBuildinMtlVar; ///< To find
+		boost::array<BuildinMaterialVariable*, BuildinMaterialVariable::BV_NUM>
+			buildinsArr; ///< To find. Initialize to int
 
 		Vec<UserMaterialVariable*> userMtlVars; ///< To iterate
 
-		/// The most important aspect of materials. Shader program for color
-		/// passes
-		RsrcPtr<ShaderProgram> cpShaderProg;
-
-		/// Shader program for depth passes
-		RsrcPtr<ShaderProgram> dpShaderProg;
-
-		/// From "GL_ZERO" return GL_ZERO
-		static ConstCharPtrHashMap<GLenum>::Type txtToBlengGlEnum;
+		/// The most important aspect of materials
+		ShaderPrograms sProgs;
 
 		//======================================================================
 		// Methods                                                             =
@@ -182,7 +188,7 @@ class Material: private MaterialProperties
 		std::string createShaderProgSourceToCache(const std::string& source);
 
 		/// XXX
-		void getVariables(const boost::property_tree::ptree& pt);
+		void populateVariables(const boost::property_tree::ptree& pt);
 };
 
 
@@ -192,4 +198,12 @@ inline bool Material::isBlendingEnabled() const
 }
 
 
+inline const BuildinMaterialVariable& Material::getBuildinVariable(
+	BuildinMaterialVariable::BuildinVariable e) const
+{
+	ASSERT(buildinVariableExits(e));
+	return *buildinsArr[e];
+}
+
+
 #endif

+ 27 - 67
src/Resources/MaterialVariable.cpp

@@ -1,5 +1,6 @@
 #include "MaterialVariable.h"
 #include "ShaderProgramVariable.h"
+#include "ShaderProgram.h"
 #include "Util/Assert.h"
 #include "Util/Exception.h"
 
@@ -7,80 +8,39 @@
 //==============================================================================
 // Constructor                                                                 =
 //==============================================================================
-MaterialVariable::MaterialVariable(Type type_,
-	const ShaderProgramVariable* cpSProgVar_,
-	const ShaderProgramVariable* dpSProgVar_)
+MaterialVariable::MaterialVariable(
+	Type type_,
+	const char* shaderProgVarName,
+	const ShaderPrograms& shaderProgsArr)
 :	type(type_),
- 	cpSProgVar(cpSProgVar_),
- 	dpSProgVar(dpSProgVar_)
+ 	oneSProgVar(NULL)
 {
-	// Sanity checks
-	if(cpSProgVar && dpSProgVar)
+	// For all shader progs point to the variables
+	for(uint i = 0; i < shaderProgsArr.size(); i++)
 	{
-		if(cpSProgVar->getName() != dpSProgVar->getName() ||
-			cpSProgVar->getType() != dpSProgVar->getType() ||
-			cpSProgVar->getGlDataType() != dpSProgVar->getGlDataType())
+		if(shaderProgsArr[i]->variableExists(shaderProgVarName))
 		{
-			throw EXCEPTION("Incompatible shader program variables");
+			sProgsVars[i] = &shaderProgsArr[i]->getVariable(shaderProgVarName);
+
+			if(!oneSProgVar)
+			{
+				oneSProgVar = sProgsVars[i];
+			}
+
+			// All the sprog vars need to have same GL data type
+			if(oneSProgVar->getGlDataType() != sProgsVars[i]->getGlDataType() ||
+				oneSProgVar->getType() != sProgsVars[i]->getType())
+			{
+				throw EXCEPTION("Incompatible shader program variables: " +
+					shaderProgVarName);
+			}
 		}
 	}
 
-	if(!cpSProgVar && !dpSProgVar)
+	// Extra sanity checks
+	if(!oneSProgVar)
 	{
-		throw EXCEPTION("Both variables NULL");
-	}
-}
-
-
-//==============================================================================
-// getColorPassShaderProgramVariable                                           =
-//==============================================================================
-const ShaderProgramVariable&
-	MaterialVariable::getColorPassShaderProgramVariable() const
-{
-	ASSERT(isColorPass());
-	return *cpSProgVar;
-}
-
-
-//==============================================================================
-// getDepthPassShaderProgramVariable                                           =
-//==============================================================================
-const ShaderProgramVariable&
-	MaterialVariable::getDepthPassShaderProgramVariable() const
-{
-	ASSERT(isDepthPass());
-	return *dpSProgVar;
-}
-
-
-//==============================================================================
-// getGlDataType                                                               =
-//==============================================================================
-GLenum MaterialVariable::getGlDataType() const
-{
-	if(isColorPass())
-	{
-		return cpSProgVar->getGlDataType();
-	}
-	else
-	{
-		return dpSProgVar->getGlDataType();
-	}
-}
-
-
-//==============================================================================
-// getName                                                                     =
-//==============================================================================
-const std::string& MaterialVariable::getName() const
-{
-	if(isColorPass())
-	{
-		return cpSProgVar->getName();
-	}
-	else
-	{
-		return dpSProgVar->getName();
+		throw EXCEPTION("Variable not found in any of the shader programs: " +
+					shaderProgVarName);
 	}
 }

+ 52 - 19
src/Resources/MaterialVariable.h

@@ -2,10 +2,14 @@
 #define MATERIAL_VARIABLE_H
 
 #include "Util/Accessors.h"
+#include "ShaderProgramVariable.h"
+#include "Util/Assert.h"
 #include <GL/glew.h>
 #include <string>
+#include <boost/array.hpp>
 
 
+class ShaderProgram;
 class ShaderProgramVariable;
 
 
@@ -16,37 +20,66 @@ class MaterialVariable
 		/// The type
 		enum Type
 		{
-			T_USER,
-			T_BUILDIN,
-			T_NUM
+			USER,
+			BUILDIN
 		};
 
 		/// XXX
-		MaterialVariable(Type type, const ShaderProgramVariable* cpSProgVar,
-			const ShaderProgramVariable* dpSProgVar);
+		enum PassType
+		{
+			COLOR_PASS,
+			DEPTH_PASS,
+			PASS_TYPES_NUM
+		};
+
+		/// XXX Used for initialization in the constructor
+		typedef boost::array<const ShaderProgram*, PASS_TYPES_NUM>
+			ShaderPrograms;
+
+		/// XXX
+		typedef boost::array<const ShaderProgramVariable*,
+			PASS_TYPES_NUM> ShaderProgramVariables;
+
+		/// XXX
+		MaterialVariable(
+			Type type,
+			const char* shaderProgVarName,
+			const ShaderPrograms& shaderProgsArr);
 
 		/// @name Accessors
 		/// @{
 		GETTER_R_BY_VAL(Type, type, getType)
-		/// @exception If the material variable is for depth only
-		const ShaderProgramVariable& getColorPassShaderProgramVariable() const;
-		/// @exception If the material variable is for color only
-		const ShaderProgramVariable& getDepthPassShaderProgramVariable() const;
-		/// Applies to the color pass shader program
-		bool isColorPass() const {return cpSProgVar != NULL;}
-		/// Applies to the depth pass shader program
-		bool isDepthPass() const {return dpSProgVar != NULL;}
-		GLenum getGlDataType() const;
-		const std::string& getName() const;
+
+		/// XXX
+		const ShaderProgramVariable& getShaderProgramVariable(
+			PassType p) const;
+
+		/// XXX
+		bool inPass(PassType p) const {return sProgsVars[p] != NULL;}
+
+		/// Get the GL data type of all the shader program variables
+		GLenum getGlDataType() const {return oneSProgVar->getGlDataType();}
+
+		/// Get the name of all the shader program variables
+		const char* getName() const {return oneSProgVar->getName().c_str();}
 		/// @}
 
 	private:
 		Type type;
-		/// The color pass shader program variable
-		const ShaderProgramVariable* cpSProgVar;
-		/// The depth pass shader program variable
-		const ShaderProgramVariable* dpSProgVar;
+		ShaderProgramVariables sProgsVars;
+
+		/// Keep one ShaderProgramVariable here for easy access of the common
+		/// variable stuff like name or GL data type etc
+		const ShaderProgramVariable* oneSProgVar;
 };
 
 
+inline const ShaderProgramVariable& MaterialVariable::getShaderProgramVariable(
+	PassType p) const
+{
+	ASSERT(inPass(p));
+	return *sProgsVars[p];
+}
+
+
 #endif

+ 4 - 8
src/Resources/Model.cpp

@@ -34,22 +34,18 @@ void Model::load(const char* filename)
 		{
 			const std::string& mesh = v.second.get<std::string>("mesh");
 			const std::string& material = v.second.get<std::string>("material");
-			const std::string& dpMaterial =
-				v.second.get<std::string>("dpMaterial");
 
 			ModelPatch* patch = new ModelPatch();
 			modelPatches.push_back(patch);
-			patch->load(mesh.c_str(), material.c_str(), dpMaterial.c_str());
-
-			visibilityShape = visibilityShape.getCompoundShape(
-				patch->getMesh().getVisibilityShape());
+			patch->load(mesh.c_str(), material.c_str());
 		}
 
 		// Bounding volume
 		visibilityShape = modelPatches[0].getMesh().getVisibilityShape();
-		BOOST_FOREACH(const ModelPatch& patch,
+		BOOST_FOREACH(
+			const ModelPatch& patch,
 			boost::make_iterator_range(modelPatches.begin() + 1,
-				modelPatches.end()))
+			modelPatches.end()))
 		{
 			visibilityShape = visibilityShape.getCompoundShape(
 				patch.getMesh().getVisibilityShape());

+ 0 - 2
src/Resources/Model.h

@@ -32,8 +32,6 @@
 class Model
 {
 	public:
-		Model() {}
-
 		void load(const char* filename);
 
 		/// @name Accessors

+ 2 - 69
src/Resources/ModelPatch.cpp

@@ -15,79 +15,12 @@ ModelPatch::~ModelPatch()
 {}
 
 
-//==============================================================================
-// supportsHardwareSkinning                                                    =
-//==============================================================================
-bool ModelPatch::supportsHwSkinning() const
-{
-	return mesh->hasVertWeights();
-}
-
-
-//==============================================================================
-// supportsNormals                                                             =
-//==============================================================================
-bool ModelPatch::supportsNormals() const
-{
-	return cpMtl->getStdAttribVar(Material::SAV_NORMAL) != NULL;
-}
-
-
-//==============================================================================
-// supportsTangents                                                            =
-//==============================================================================
-bool ModelPatch::supportsTangents() const
-{
-	return cpMtl->getStdAttribVar(Material::SAV_TANGENT) != NULL;
-}
-
-
 //==============================================================================
 // load                                                                        =
 //==============================================================================
-void ModelPatch::load(const char* meshFName, const char* cpMtlFName,
-	const char* dpMtlFName)
+void ModelPatch::load(const char* meshFName, const char* mtlFName)
 {
 	// Load
 	mesh.loadRsrc(meshFName);
-	cpMtl.loadRsrc(cpMtlFName);
-	dpMtl.loadRsrc(dpMtlFName);
-
-	// Sanity checks
-	doMeshAndMtlSanityChecks(*mesh, *cpMtl);
-	doMeshAndMtlSanityChecks(*mesh, *dpMtl);
-}
-
-
-//==============================================================================
-// doMeshAndMtlSanityChecks                                                    =
-//==============================================================================
-void ModelPatch::doMeshAndMtlSanityChecks(const Mesh& mesh, const Material& mtl)
-{
-	try
-	{
-		// if mtl needs tex coords then mesh should have
-		if(mtl.hasTexCoords() && !mesh.hasTexCoords())
-		{
-			throw EXCEPTION("Texture coords");
-		}
-
-		// Normals
-		if(mtl.getStdAttribVar(Material::SAV_NORMAL) != NULL &&
-			!mesh.hasNormalsAndTangents())
-		{
-			throw EXCEPTION("Normals");
-		}
-
-		// Tangents
-		if(mtl.getStdAttribVar(Material::SAV_TANGENT) != NULL &&
-			!mesh.hasNormalsAndTangents())
-		{
-			throw EXCEPTION("Tangents");
-		}
-	}
-	catch(std::exception& e)
-	{
-		throw EXCEPTION("Mesh and material are incompatible: " + e.what());
-	}
+	mtl.loadRsrc(mtlFName);
 }

+ 2 - 15
src/Resources/ModelPatch.h

@@ -21,25 +21,12 @@ class ModelPatch
 		/// @name Accessors
 		/// @{
 		const Mesh& getMesh() const {return *mesh;}
-		const Material& getMaterial() const {return *cpMtl;}
+		const Material& getMaterial() const {return *mtl;}
 		/// @}
 
-		/// This only checks the mesh for vertex weights
-		bool supportsHwSkinning() const;
-
-		/// This checks if any of the materials need normals
-		bool supportsNormals() const;
-
-		/// This checks if any of the materials need tangents
-		bool supportsTangents() const;
-
 	private:
 		RsrcPtr<Mesh> mesh; ///< The geometry
-		RsrcPtr<Material> cpMtl; ///< Material for MS and BS
-
-		/// Checks if a mesh and a material are compatible
-		static void doMeshAndMtlSanityChecks(const Mesh& mesh,
-			const Material& mtl);
+		RsrcPtr<Material> mtl; ///< Material for MS and BS
 };
 
 

+ 15 - 15
src/Resources/UserMaterialVariable.cpp

@@ -8,10 +8,10 @@
 //==============================================================================
 
 UserMaterialVariable::UserMaterialVariable(
-	const UniformShaderProgramVariable* cpUni,
-	const UniformShaderProgramVariable* dpUni,
+	const char* shaderProgVarName,
+	const ShaderPrograms& shaderProgsArr,
 	float val)
-:	MaterialVariable(T_USER, cpUni, dpUni)
+:	MaterialVariable(USER, shaderProgVarName, shaderProgsArr)
 {
 	ASSERT(getGlDataType() == GL_FLOAT);
 	data = val;
@@ -19,10 +19,10 @@ UserMaterialVariable::UserMaterialVariable(
 
 
 UserMaterialVariable::UserMaterialVariable(
-	const UniformShaderProgramVariable* cpUni,
-	const UniformShaderProgramVariable* dpUni,
+	const char* shaderProgVarName,
+	const ShaderPrograms& shaderProgsArr,
 	const Vec2& val)
-:	MaterialVariable(T_USER, cpUni, dpUni)
+:	MaterialVariable(USER, shaderProgVarName, shaderProgsArr)
 {
 	ASSERT(getGlDataType() == GL_FLOAT_VEC2);
 	data = val;
@@ -30,10 +30,10 @@ UserMaterialVariable::UserMaterialVariable(
 
 
 UserMaterialVariable::UserMaterialVariable(
-	const UniformShaderProgramVariable* cpUni,
-	const UniformShaderProgramVariable* dpUni,
+	const char* shaderProgVarName,
+	const ShaderPrograms& shaderProgsArr,
 	const Vec3& val)
-:	MaterialVariable(T_USER, cpUni, dpUni)
+:	MaterialVariable(USER, shaderProgVarName, shaderProgsArr)
 {
 	ASSERT(getGlDataType() == GL_FLOAT_VEC3);
 	data = val;
@@ -41,10 +41,10 @@ UserMaterialVariable::UserMaterialVariable(
 
 
 UserMaterialVariable::UserMaterialVariable(
-	const UniformShaderProgramVariable* cpUni,
-	const UniformShaderProgramVariable* dpUni,
+	const char* shaderProgVarName,
+	const ShaderPrograms& shaderProgsArr,
 	const Vec4& val)
-:	MaterialVariable(T_USER, cpUni, dpUni)
+:	MaterialVariable(USER, shaderProgVarName, shaderProgsArr)
 {
 	ASSERT(getGlDataType() == GL_FLOAT_VEC4);
 	data = val;
@@ -52,10 +52,10 @@ UserMaterialVariable::UserMaterialVariable(
 
 
 UserMaterialVariable::UserMaterialVariable(
-	const UniformShaderProgramVariable* cpUni,
-	const UniformShaderProgramVariable* dpUni,
+	const char* shaderProgVarName,
+	const ShaderPrograms& shaderProgsArr,
 	const char* texFilename)
-:	MaterialVariable(T_USER, cpUni, dpUni)
+:	MaterialVariable(USER, shaderProgVarName, shaderProgsArr)
 {
 	ASSERT(getGlDataType() == GL_SAMPLER_2D);
 	data = RsrcPtr<Texture>();

+ 24 - 10
src/Resources/UserMaterialVariable.h

@@ -21,16 +21,30 @@ class UserMaterialVariable: public MaterialVariable
 
 		/// @name Constructors & destructor
 		/// @{
-		UserMaterialVariable(const UniformShaderProgramVariable* cpUni,
-			const UniformShaderProgramVariable* dpUni, float val);
-		UserMaterialVariable(const UniformShaderProgramVariable* cpUni,
-			const UniformShaderProgramVariable* dpUni, const Vec2& val);
-		UserMaterialVariable(const UniformShaderProgramVariable* cpUni,
-			const UniformShaderProgramVariable* dpUni, const Vec3& val);
-		UserMaterialVariable(const UniformShaderProgramVariable* cpUni,
-			const UniformShaderProgramVariable* dpUni, const Vec4& val);
-		UserMaterialVariable(const UniformShaderProgramVariable* cpUni,
-			const UniformShaderProgramVariable* dpUni, const char* texFilename);
+		UserMaterialVariable(
+			const char* shaderProgVarName,
+			const ShaderPrograms& shaderProgsArr,
+			float val);
+
+		UserMaterialVariable(
+			const char* shaderProgVarName,
+			const ShaderPrograms& shaderProgsArr,
+			const Vec2& val);
+
+		UserMaterialVariable(
+			const char* shaderProgVarName,
+			const ShaderPrograms& shaderProgsArr,
+			const Vec3& val);
+
+		UserMaterialVariable(
+			const char* shaderProgVarName,
+			const ShaderPrograms& shaderProgsArr,
+			const Vec4& val);
+
+		UserMaterialVariable(
+			const char* shaderProgVarName,
+			const ShaderPrograms& shaderProgsArr,
+			const char* texFilename);
 
 		~UserMaterialVariable();
 		/// @}

+ 1 - 6
src/Scene/PatchNode.h

@@ -26,13 +26,8 @@ class PatchNode: public RenderableNode
 
 		/// @name Accessors
 		/// @{
-		const Material& getCpMtl() const {return rsrc.getCpMtl();}
-		const Material& getDpMtl() const {return rsrc.getDpMtl();}
-
-		MaterialRuntime& getCpMtlRun() {return *cpMtlRun;}
-		MaterialRuntime& getDpMtlRun() {return *dpMtlRun;}
+		MaterialRuntime& getMaterialRuntime() {return *mtlRun;}
 		const MaterialRuntime& getCpMtlRun() const {return *cpMtlRun;}
-		const MaterialRuntime& getDpMtlRun() const {return *dpMtlRun;}
 
 		const ModelPatch& getModelPatchRsrc() const {return rsrc;}
 		const Vao& getCpVao() const {return cpVao;}