Browse Source

New material

Panagiotis Christopoulos Charitos 14 years ago
parent
commit
6ac0b14399

+ 87 - 0
src/Resources/BuildinMaterialVariable.cpp

@@ -0,0 +1,87 @@
+#include "BuildinMaterialVariable.h"
+#include "Util/Exception.h"
+#include <cstring>
+#include <boost/lexical_cast.hpp>
+
+
+//==============================================================================
+// Statics                                                                     =
+//==============================================================================
+
+boost::array<BuildinMaterialVariable::BuildinVarInfo,
+	BuildinMaterialVariable::BV_NUM> BuildinMaterialVariable::infos =
+{{
+	{"position", GL_FLOAT_VEC3},
+	{"tangent", GL_FLOAT_VEC4},
+	{"normal", GL_FLOAT_VEC3},
+	{"texCoords", GL_FLOAT_VEC2},
+	{"modelMat", GL_FLOAT_MAT4},
+	{"viewMat", GL_FLOAT_MAT4},
+	{"projectionMat", GL_FLOAT_MAT4},
+	{"modelViewMat", GL_FLOAT_MAT4},
+	{"viewProjectionMat", GL_FLOAT_MAT4},
+	{"normalMat", GL_FLOAT_MAT3},
+	{"modelViewProjectionMat", GL_FLOAT_MAT4},
+	{"msNormalFai", GL_SAMPLER_2D},
+	{"msDiffuseFai", GL_SAMPLER_2D},
+	{"msSpecularFai", GL_SAMPLER_2D},
+	{"msDepthFai", GL_SAMPLER_2D},
+	{"isFai", GL_SAMPLER_2D},
+	{"ppsPrePassFai", GL_SAMPLER_2D},
+	{"ppsPostPassFai", GL_SAMPLER_2D},
+	{"rendererSize", GL_FLOAT_VEC2},
+	{"sceneAmbientColor", GL_FLOAT_VEC3},
+	{"blurring", GL_FLOAT},
+}};
+
+
+//==============================================================================
+// Constructor                                                                 =
+//==============================================================================
+BuildinMaterialVariable::BuildinMaterialVariable(
+	const SProgVar* cpSProgVar, const SProgVar* dpSProgVar,
+	const char* name)
+:	MaterialVariable(T_BUILDIN, cpSProgVar, dpSProgVar),
+ 	var(BV_NUM)
+{
+	GLenum dataType;
+	// Sanity checks
+	if(!isBuildin(name, &var, &dataType))
+	{
+		throw EXCEPTION("The variable is not buildin: " + name);
+	}
+
+	if(dataType != getGlDataType())
+	{
+		throw EXCEPTION("The buildin variable \"" + name +
+			"\" sould be of type: " +
+			boost::lexical_cast<std::string>(dataType));
+	}
+}
+
+
+//==============================================================================
+// isBuildin                                                                   =
+//==============================================================================
+bool BuildinMaterialVariable::isBuildin(const char* name,
+	BuildinVariable* var, GLenum* dataType)
+{
+	for(uint i = 0; i < BV_NUM; i++)
+	{
+		if(!strcmp(infos[i].name, name))
+		{
+			if(var)
+			{
+				*var = static_cast<BuildinVariable>(i);
+			}
+
+			if(dataType)
+			{
+				*dataType = infos[i].dataType;
+			}
+			return true;
+		}
+	}
+
+	return false;
+}

+ 67 - 0
src/Resources/BuildinMaterialVariable.h

@@ -0,0 +1,67 @@
+#ifndef BUILDIN_MATERIAL_VARIABLE_H
+#define BUILDIN_MATERIAL_VARIABLE_H
+
+#include "MaterialVariable.h"
+#include <boost/array.hpp>
+
+
+/// XXX
+class BuildinMaterialVariable: public MaterialVariable
+{
+	public:
+		/// Standard attribute variables that are acceptable inside the @ref
+		/// ShaderProg
+		enum BuildinVariable
+		{
+			// Attributes
+			BV_POSITION,
+			BV_TANGENT,
+			BV_NORMAL,
+			BV_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,
+			// 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,
+			// Other
+			BV_RENDERER_SIZE,
+			BV_SCENE_AMBIENT_COLOR,
+			BV_BLURRING,
+			// num
+			BV_NUM ///< The number of all variables
+		};
+
+		/// Information for the build-in shader program variables
+		struct BuildinVarInfo
+		{
+			const char* name; ///< Variable name
+			GLenum dataType; ///< aka GL data type
+		};
+
+		BuildinMaterialVariable(const SProgVar* cpSProgVar,
+			const SProgVar* dpSProgVar, const char* name);
+
+		GETTER_R_BY_VAL(BuildinVariable, var, getVariableEnum)
+
+		static bool isBuildin(const char* name, BuildinVariable* var = NULL,
+			GLenum* dataType = NULL);
+
+	private:
+		static boost::array<BuildinVarInfo, BV_NUM> infos;
+		BuildinVariable var;
+};
+
+
+#endif

+ 39 - 37
src/Resources/Material2.cpp

@@ -1,5 +1,5 @@
 #include "Material2.h"
-#include "MaterialInputVariable.h"
+#include "MaterialVariable.h"
 #include "Util/Scanner/Scanner.h"
 #include "Misc/Parser.h"
 #include "Misc/PropertyTree.h"
@@ -13,39 +13,6 @@
 // Statics                                                                     =
 //==============================================================================
 
-boost::array<Material2::StdVarNameAndGlDataTypePair, Material2::SAV_NUM>
-	Material2::stdAttribVarInfos =
-{{
-	{"position", GL_FLOAT_VEC3},
-	{"tangent", GL_FLOAT_VEC4},
-	{"normal", GL_FLOAT_VEC3},
-	{"texCoords", GL_FLOAT_VEC2}
-}};
-
-
-boost::array<Material2::StdVarNameAndGlDataTypePair, Material2::SUV_NUM>
-	Material2::stdUniVarInfos =
-{{
-	{"modelMat", GL_FLOAT_MAT4},
-	{"viewMat", GL_FLOAT_MAT4},
-	{"projectionMat", GL_FLOAT_MAT4},
-	{"modelViewMat", GL_FLOAT_MAT4},
-	{"viewProjectionMat", GL_FLOAT_MAT4},
-	{"normalMat", GL_FLOAT_MAT3},
-	{"modelViewProjectionMat", GL_FLOAT_MAT4},
-	{"msNormalFai", GL_SAMPLER_2D},
-	{"msDiffuseFai", GL_SAMPLER_2D},
-	{"msSpecularFai", GL_SAMPLER_2D},
-	{"msDepthFai", GL_SAMPLER_2D},
-	{"isFai", GL_SAMPLER_2D},
-	{"ppsPrePassFai", GL_SAMPLER_2D},
-	{"ppsPostPassFai", GL_SAMPLER_2D},
-	{"rendererSize", GL_FLOAT_VEC2},
-	{"sceneAmbientColor", GL_FLOAT_VEC3},
-	{"blurring", GL_FLOAT},
-}};
-
-
 Material2::BlendParam Material2::blendingParams[] =
 {
 	{GL_ZERO, "GL_ZERO"},
@@ -472,17 +439,52 @@ void Material2::parseShaderProgramTag(const boost::property_tree::ptree& pt)
 	//
 	// <ins></ins>
 	//
+	Vec<std::string> uniformsLines; // Store the source of the uniform vars
+
 	boost::optional<const ptree&> insPt = pt.get_child_optional("ins");
 	if(insPt)
 	{
 		BOOST_FOREACH(const ptree::value_type& v, insPt.get())
 		{
-			if(v.first != "include")
+			if(v.first != "in")
+			{
+				throw EXCEPTION("Expected in and not: " + v.first);
+			}
+
+			const ptree& inPt = v.second;
+
+			const std::string& name = inPt.get<std::string>("name");
+
+			std::string line;
+
+			if(inPt.get_child_optional("float"))
+			{
+				line += "float";
+			}
+			else if(inPt.get_child_optional("vec2"))
 			{
-				throw EXCEPTION("Expected include and not: " + v.first);
+				line += "vec2";
 			}
+			else if(inPt.get_child_optional("vec3"))
+			{
+			}
+			else if(inPt.get_child_optional("vec4"))
+			{
+			}
+			else if(inPt.get_child_optional("sampler2D"))
+			{
+			}
+			else
+			{
+				BuildinMaterialVariable::BuildinVariable tmp;
+				GLenum dataType;
 
-			const std::string& name = v.second.data();
+				if(BuildinMaterialVariable::isBuildin(name.c_str(),
+					&tmp, &dataType))
+				{
+					throw EXCEPTION("The variable is not build in: " + name);
+				}
+			}
 		}
 	}
 

+ 19 - 65
src/Resources/Material2.h

@@ -2,6 +2,9 @@
 #define MATERIAL_2_H
 
 #include "Util/Accessors.h"
+#include "Util/CharPtrHashMap.h"
+#include "UserMaterialVariable.h"
+#include "BuildinMaterialVariable.h"
 #include "RsrcPtr.h"
 #include <GL/glew.h>
 #include <boost/ptr_container/ptr_vector.hpp>
@@ -13,7 +16,6 @@
 class SProgAttribVar;
 class SProgUniVar;
 class ShaderProg;
-class MaterialInputVariable;
 namespace Scanner {
 class Scanner;
 }
@@ -60,12 +62,11 @@ struct MaterialProperties
 /// 			<in>
 /// 				<name>xx</name>
 /// 				<value>
-/// 					<fai>msDepthFai | isFai | ppsPrePassFai |
-/// 					     ppsPostPassFai</fai> |
 /// 					<float>0.0</float> |
 /// 					<vec2><x>0.0</x><y>0.0</y></vec2> |
 /// 					<vec3><x>0.0</x><y>0.0</y><z>0.0</z></vec3> |
-/// 					<vec4><x>0.0</x><y>0.0</y><z>0.0</z><w>0.0</w></vec4>
+/// 					<vec4><x>0.0</x><y>0.0</y><z>0.0</z><w>0.0</w></vec4> |
+/// 					<sampler2D>path/to/image.tga</sampler2D>
 /// 				</value>
 /// 			</in>
 /// 		</ins>
@@ -87,48 +88,6 @@ struct MaterialProperties
 class Material2: private MaterialProperties
 {
 	public:
-		/// Standard attribute variables that are acceptable inside the @ref
-		/// ShaderProg
-		enum StandardAtributeVariables
-		{
-			SAV_POSITION,
-			SAV_TANGENT,
-			SAV_NORMAL,
-			SAV_TEX_COORDS,
-			SAV_NUM
-		};
-
-		/// Standard uniform variables. The Renderer sees what are applicable
-		/// and sets them
-		/// After changing the enum update also:
-		/// - Some statics in Material.cpp
-		/// - Renderer::setupShaderProg
-		enum StandardUniformVariables
-		{
-			// Matrices
-			SUV_MODEL_MAT,
-			SUV_VIEW_MAT,
-			SUV_PROJECTION_MAT,
-			SUV_MODELVIEW_MAT,
-			SUV_VIEWPROJECTION_MAT,
-			SUV_NORMAL_MAT,
-			SUV_MODELVIEWPROJECTION_MAT,
-			// FAIs (for materials in blending stage)
-			SUV_MS_NORMAL_FAI,
-			SUV_MS_DIFFUSE_FAI,
-			SUV_MS_SPECULAR_FAI,
-			SUV_MS_DEPTH_FAI,
-			SUV_IS_FAI,
-			SUV_PPS_PRE_PASS_FAI,
-			SUV_PPS_POST_PASS_FAI,
-			// Other
-			SUV_RENDERER_SIZE,
-			SUV_SCENE_AMBIENT_COLOR,
-			SUV_BLURRING,
-			// num
-			SUV_NUM ///< The number of standard uniform variables
-		};
-
 		/// Initialize with default values
 		Material2();
 
@@ -142,8 +101,8 @@ class Material2: private MaterialProperties
 		GETTER_R_BY_VAL(int, blendingDfactor, getBlendingDfactor)
 		GETTER_R_BY_VAL(bool, depthTesting, isDepthTestingEnabled)
 		GETTER_R_BY_VAL(bool, wireframe, isWireframeEnabled)
-		GETTER_R(boost::ptr_vector<MaterialInputVariable>, inVars,
-			getMaterialInputVariables)
+		GETTER_R(boost::ptr_vector<MaterialVariable>, mtlVars,
+			getMaterialVariables)
 
 		/// Access the base class just for copying in other classes
 		GETTER_R(MaterialProperties, *this, accessMaterialPropertiesBaseClass)
@@ -154,13 +113,13 @@ class Material2: private MaterialProperties
 		const ShaderProg& getDepthPassShaderProgram() const
 			{return *dpShaderProg;}
 
-		/// Return NULL if the variable is not present in the shader program
+		/*/// Return NULL if the variable is not present in the shader program
 		const SProgAttribVar* getStandardAttributeVariable(
 			StandardAtributeVariables id) const;
 
 		/// Return NULL if the variable is not present in the shader program
 		const SProgUniVar* getStandardUniformVariable(
-			StandardUniformVariables id) const;
+			StandardUniformVariables id) const;*/
 		/// @}
 
 		/// Return false if blendingSfactor is equal to GL_ONE and
@@ -211,8 +170,8 @@ class Material2: private MaterialProperties
 			ArgDataType returnArg;
 		};
 
-		/// Information for the standard shader program variables
-		struct StdVarNameAndGlDataTypePair
+		/// Information for the build-in shader program variables
+		struct BuildinVar
 		{
 			const char* varName;
 			GLenum dataType; ///< aka GL data type
@@ -229,18 +188,13 @@ class Material2: private MaterialProperties
 		// Members                                                             =
 		//======================================================================
 
-		/// The input variables
-		boost::ptr_vector<MaterialInputVariable> inVars;
+		/// All the material variables. Both buildins and user
+		boost::ptr_vector<MaterialVariable> mtlVars;
 
-		/// Used to check if a var exists in the shader program
-		static boost::array<StdVarNameAndGlDataTypePair, SAV_NUM>
-			stdAttribVarInfos;
-		/// Used to check if a var exists in the shader program
-		static boost::array<StdVarNameAndGlDataTypePair, SUV_NUM>
-			stdUniVarInfos;
-		/// The standard attribute variables
-		boost::array<const SProgAttribVar*, SAV_NUM> stdAttribVars;
-		boost::array<const SProgUniVar*, SUV_NUM> stdUniVars;
+		boost::unordered_map<BuildinMaterialVariable::BuildinVariable,
+			BuildinMaterialVariable*> enumToBuildinMtlVar;
+
+		Vec<UserMaterialVariable*> userMtlVars;
 
 		/// The most important aspect of materials. Shader program for color
 		/// passes
@@ -291,7 +245,7 @@ inline bool Material2::isBlendingEnabled() const
 }
 
 
-inline const SProgAttribVar* Material2::getStandardAttributeVariable(
+/*inline const SProgAttribVar* Material2::getStandardAttributeVariable(
 	StandardAtributeVariables id) const
 {
 	return stdAttribVars[id];
@@ -302,7 +256,7 @@ inline const SProgUniVar* Material2::getStandardUniformVariable(
 	StandardUniformVariables id) const
 {
 	return stdUniVars[id];
-}
+}*/
 
 
 #endif

+ 0 - 136
src/Resources/MaterialInputVariable.cpp

@@ -1,136 +0,0 @@
-#include "MaterialInputVariable.h"
-#include "SProgUniVar.h"
-#include "Texture.h"
-#include "Util/Assert.h"
-
-
-//==============================================================================
-// Constructor                                                                 =
-//==============================================================================
-
-MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar, float val)
-:	sProgVar(svar)
-{
-	ASSERT(svar.getGlDataType() == GL_FLOAT);
-	scalar = val;
-	type = T_FLOAT;
-}
-
-
-MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
-	const Vec2& val)
-:	sProgVar(svar)
-{
-	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC2);
-	vec2 = val;
-	type = T_VEC2;
-}
-
-
-MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
-	const Vec3& val)
-:	sProgVar(svar)
-{
-	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC3);
-	vec3 = val;
-	type = T_VEC3;
-}
-
-
-MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
-	const Vec4& val)
-:	sProgVar(svar)
-{
-	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC4);
-	vec4 = val;
-	type = T_VEC4;
-}
-
-
-MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar, Fai val)
-:	sProgVar(svar)
-{
-	ASSERT(svar.getGlDataType() == GL_SAMPLER_2D);
-	fai = val;
-	type = T_FAI;
-}
-
-
-MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
-	const char* texFilename)
-:	sProgVar(svar)
-{
-	ASSERT(svar.getGlDataType() == GL_SAMPLER_2D);
-	texture.loadRsrc(texFilename);
-	type = T_TEXTURE;
-}
-
-
-//==============================================================================
-// Destructor                                                                  =
-//==============================================================================
-MaterialInputVariable::~MaterialInputVariable()
-{}
-
-
-//==============================================================================
-// Accessors                                                                   =
-//==============================================================================
-
-float MaterialInputVariable::getFloat() const
-{
-	ASSERT(sProgVar.getGlDataType() == GL_FLOAT);
-	return scalar;
-}
-
-
-const Vec2& MaterialInputVariable::getVec2() const
-{
-	ASSERT(sProgVar.getGlDataType() == GL_FLOAT_VEC2);
-	return vec2;
-}
-
-
-const Vec3& MaterialInputVariable::getVec3() const
-{
-	ASSERT(sProgVar.getGlDataType() == GL_FLOAT_VEC3);
-	return vec3;
-}
-
-
-const Vec4& MaterialInputVariable::getVec4() const
-{
-	ASSERT(sProgVar.getGlDataType() == GL_FLOAT_VEC4);
-	return vec4;
-}
-
-
-MaterialInputVariable::Fai MaterialInputVariable::getFai() const
-{
-	ASSERT(sProgVar.getGlDataType() == GL_SAMPLER_2D);
-	return fai;
-}
-
-
-const Texture& MaterialInputVariable::getTexture() const
-{
-	ASSERT(sProgVar.getGlDataType() == GL_SAMPLER_2D);
-	return *texture;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

+ 0 - 79
src/Resources/MaterialInputVariable.h

@@ -1,79 +0,0 @@
-#ifndef MATERIAL_INPUT_VARIABLE_H
-#define MATERIAL_INPUT_VARIABLE_H
-
-#include "Math/Math.h"
-#include "RsrcPtr.h"
-#include "Util/Accessors.h"
-
-
-class Texture;
-class SProgUniVar;
-
-
-/// @todo
-class MaterialInputVariable
-{
-	public:
-		/// The type of the variable
-		enum Type
-		{
-			T_FAI,
-			T_TEXTURE,
-			T_FLOAT,
-			T_VEC2,
-			T_VEC3,
-			T_VEC4,
-			T_NUM
-		};
-
-		/// The renderer's FAIs
-		enum Fai
-		{
-			MS_DEPTH_FAI, ///< Avoid it in MS
-			IS_FAI, ///< Use it anywhere
-			PPS_PRE_PASS_FAI, ///< Avoid it in BS
-			PPS_POST_PASS_FAI ///< Use it anywhere
-		};
-
-		/// @name Constructors
-		/// @{
-		MaterialInputVariable(const SProgUniVar& sProgVar, float val);
-		MaterialInputVariable(const SProgUniVar& sProgVar, const Vec2& val);
-		MaterialInputVariable(const SProgUniVar& sProgVar, const Vec3& val);
-		MaterialInputVariable(const SProgUniVar& sProgVar, const Vec4& val);
-		MaterialInputVariable(const SProgUniVar& sProgVar, Fai val);
-		MaterialInputVariable(const SProgUniVar& sProgVar,
-			const char* texFilename);
-		/// @}
-
-		~MaterialInputVariable();
-
-		/// @name Accessors
-		/// @{
-		float getFloat() const;
-		const Vec2& getVec2() const;
-		const Vec3& getVec3() const;
-		const Vec4& getVec4() const;
-		Fai getFai() const;
-		const Texture& getTexture() const;
-
-		GETTER_R(SProgUniVar, sProgVar, getShaderProgramUniformVariable)
-		GETTER_R_BY_VAL(Type, type, getType)
-		/// @}
-
-	private:
-		const SProgUniVar& sProgVar; ///< The shader program's uniform
-		Type type;
-
-		/// @name Data
-		/// @{
-		float scalar;
-		Vec2 vec2;
-		Vec3 vec3;
-		Vec4 vec4;
-		Fai fai;
-		RsrcPtr<Texture> texture;
-		/// @}
-};
-
-#endif

+ 83 - 0
src/Resources/MaterialVariable.cpp

@@ -0,0 +1,83 @@
+#include "MaterialVariable.h"
+#include "SProgVar.h"
+#include "Util/Assert.h"
+#include "Util/Exception.h"
+
+
+//==============================================================================
+// Constructor                                                                 =
+//==============================================================================
+MaterialVariable::MaterialVariable(Type type_, const SProgVar* cpSProgVar_,
+	const SProgVar* dpSProgVar_)
+:	type(type_),
+ 	cpSProgVar(cpSProgVar_),
+ 	dpSProgVar(dpSProgVar_)
+{
+	// Sanity checks
+	if(cpSProgVar && dpSProgVar)
+	{
+		if(cpSProgVar->getName() != dpSProgVar->getName() ||
+			cpSProgVar->getType() != dpSProgVar->getType() ||
+			cpSProgVar->getGlDataType() != dpSProgVar->getGlDataType())
+		{
+			throw EXCEPTION("Incompatible shader program variables");
+		}
+	}
+
+	if(!cpSProgVar && !dpSProgVar)
+	{
+		throw EXCEPTION("Both variables NULL");
+	}
+}
+
+
+//==============================================================================
+// getColorPassShaderProgramVariable                                           =
+//==============================================================================
+const SProgVar& MaterialVariable::getColorPassShaderProgramVariable() const
+{
+	ASSERT(isColorPass());
+	return *cpSProgVar;
+}
+
+
+//==============================================================================
+// getDepthPassShaderProgramVariable                                           =
+//==============================================================================
+const SProgVar& 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();
+	}
+}

+ 48 - 0
src/Resources/MaterialVariable.h

@@ -0,0 +1,48 @@
+#ifndef MATERIAL_VARIABLE_H
+#define MATERIAL_VARIABLE_H
+
+#include "Util/Accessors.h"
+#include <GL/glew.h>
+#include <string>
+
+
+class SProgVar;
+
+
+/// XXX
+class MaterialVariable
+{
+	public:
+		/// The type
+		enum Type
+		{
+			T_USER,
+			T_BUILDIN,
+			T_NUM
+		};
+
+		/// XXX
+		MaterialVariable(Type type, const SProgVar* cpSProgVar,
+			const SProgVar* dpSProgVar);
+
+		/// @name Accessors
+		/// @{
+		GETTER_R_BY_VAL(Type, type, getType)
+		const SProgVar& getColorPassShaderProgramVariable() const;
+		const SProgVar& 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;
+		/// @}
+
+	private:
+		Type type;
+		const SProgVar* cpSProgVar; ///< The color pass shader program variable
+		const SProgVar* dpSProgVar; ///< The depth pass shader program variable
+};
+
+
+#endif

+ 91 - 0
src/Resources/UserMaterialVariable.cpp

@@ -0,0 +1,91 @@
+#include "UserMaterialVariable.h"
+#include "SProgUniVar.h"
+#include "Texture.h"
+
+
+//==============================================================================
+// Constructors                                                                =
+//==============================================================================
+
+UserMaterialVariable::UserMaterialVariable(const SProgUniVar* cpSProgUniVar,
+	const SProgUniVar* dpSProgUniVar, float val)
+:	MaterialVariable(T_USER, cpSProgUniVar, dpSProgUniVar)
+{
+	ASSERT(getGlDataType() == GL_FLOAT);
+	data.scalar = val;
+}
+
+
+UserMaterialVariable::UserMaterialVariable(const SProgUniVar* cpSProgUniVar,
+	const SProgUniVar* dpSProgUniVar, const Vec2& val)
+:	MaterialVariable(T_USER, cpSProgUniVar, dpSProgUniVar)
+{
+	ASSERT(getGlDataType() == GL_FLOAT_VEC2);
+	data.vec2 = val;
+}
+
+
+UserMaterialVariable::UserMaterialVariable(const SProgUniVar* cpSProgUniVar,
+	const SProgUniVar* dpSProgUniVar, const Vec3& val)
+:	MaterialVariable(T_USER, cpSProgUniVar, dpSProgUniVar)
+{
+	ASSERT(getGlDataType() == GL_FLOAT_VEC3);
+	data.vec3 = val;
+}
+
+
+UserMaterialVariable::UserMaterialVariable(const SProgUniVar* cpSProgUniVar,
+	const SProgUniVar* dpSProgUniVar, const Vec4& val)
+:	MaterialVariable(T_USER, cpSProgUniVar, dpSProgUniVar)
+{
+	ASSERT(getGlDataType() == GL_FLOAT_VEC4);
+	data.vec4 = val;
+}
+
+
+UserMaterialVariable::UserMaterialVariable(const SProgUniVar* cpSProgUniVar,
+	const SProgUniVar* dpSProgUniVar, const char* texFilename)
+:	MaterialVariable(T_USER, cpSProgUniVar, dpSProgUniVar)
+{
+	ASSERT(getGlDataType() == GL_SAMPLER_2D);
+	data.texture.loadRsrc(texFilename);
+}
+
+
+//==============================================================================
+// Accessors                                                                   =
+//==============================================================================
+
+float UserMaterialVariable::getFloat() const
+{
+	ASSERT(getGlDataType() == GL_FLOAT);
+	return data.scalar;
+}
+
+
+const Vec2& UserMaterialVariable::getVec2() const
+{
+	ASSERT(getGlDataType() == GL_FLOAT_VEC2);
+	return data.vec2;
+}
+
+
+const Vec3& UserMaterialVariable::getVec3() const
+{
+	ASSERT(getGlDataType() == GL_FLOAT_VEC3);
+	return data.vec3;
+}
+
+
+const Vec4& UserMaterialVariable::getVec4() const
+{
+	ASSERT(getGlDataType() == GL_FLOAT_VEC4);
+	return data.vec4;
+}
+
+
+const Texture& UserMaterialVariable::getTexture() const
+{
+	ASSERT(getGlDataType() == GL_SAMPLER_2D);
+	return *data.texture;
+}

+ 55 - 0
src/Resources/UserMaterialVariable.h

@@ -0,0 +1,55 @@
+#ifndef USER_MATERIAL_VARIABLE_H
+#define USER_MATERIAL_VARIABLE_H
+
+#include "MaterialVariable.h"
+#include "Math/Math.h"
+#include "RsrcPtr.h"
+
+
+class Texture;
+class SProgUniVar;
+
+
+/// XXX
+class UserMaterialVariable: public MaterialVariable
+{
+	public:
+		/// XXX
+		struct Data
+		{
+			float scalar;
+			Vec2 vec2;
+			Vec3 vec3;
+			Vec4 vec4;
+			RsrcPtr<Texture> texture;
+		};
+
+		/// @name Constructors
+		/// @{
+		UserMaterialVariable(const SProgUniVar* cpSProgUniVar,
+			const SProgUniVar* dpSProgUniVar, float val);
+		UserMaterialVariable(const SProgUniVar* cpSProgUniVar,
+			const SProgUniVar* dpSProgUniVar, const Vec2& val);
+		UserMaterialVariable(const SProgUniVar* cpSProgUniVar,
+			const SProgUniVar* dpSProgUniVar, const Vec3& val);
+		UserMaterialVariable(const SProgUniVar* cpSProgUniVar,
+			const SProgUniVar* dpSProgUniVar, const Vec4& val);
+		UserMaterialVariable(const SProgUniVar* cpSProgUniVar,
+			const SProgUniVar* dpSProgUniVar, const char* texFilename);
+		/// @}
+
+		/// @name Accessors
+		/// @{
+		float getFloat() const;
+		const Vec2& getVec2() const;
+		const Vec3& getVec3() const;
+		const Vec4& getVec4() const;
+		const Texture& getTexture() const;
+		/// @}
+
+	private:
+		Data data;
+};
+
+
+#endif