Browse Source

New material code

Panagiotis Christopoulos Charitos 14 years ago
parent
commit
4424778aaf

+ 235 - 0
src/Resources/Material2.cpp

@@ -0,0 +1,235 @@
+#include "Material2.h"
+#include "Util/Scanner/Scanner.h"
+#include "Misc/Parser.h"
+
+
+//==============================================================================
+// 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},
+}};
+
+
+//==============================================================================
+// parseShaderFileForFunctionDefinitions                                       =
+//==============================================================================
+void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
+	boost::ptr_vector<FuncDefinition>& out)
+{
+	Scanner::Scanner scanner(filename);
+	const Scanner::Token* token;
+
+	while(true)
+	{
+		// EOF
+		if(token->getCode() == Scanner::TC_EOF)
+		{
+			break;
+		}
+
+		FuncDefinition* funcDef = new FuncDefinition;
+		out.push_back(funcDef);
+
+		// Type
+		token = &scanner.getNextToken();
+		if(token->getCode() == Scanner::TC_IDENTIFIER)
+		{
+			if(!strcmp(token->getValue().getString(), "float"))
+			{
+				funcDef->returnArg = AT_FLOAT;
+			}
+			else if(!strcmp(token->getValue().getString(), "vec2"))
+			{
+				funcDef->returnArg = AT_VEC2;
+			}
+			else if(!strcmp(token->getValue().getString(), "vec3"))
+			{
+				funcDef->returnArg = AT_VEC3;
+			}
+			else if(!strcmp(token->getValue().getString(), "vec4"))
+			{
+				funcDef->returnArg = AT_VEC4;
+			}
+			else if(!strcmp(token->getValue().getString(), "void"))
+			{
+				funcDef->returnArg = AT_VOID;
+			}
+			else
+			{
+				throw PARSER_EXCEPTION_EXPECTED("float or vec2 or vec3"
+					" or vec4 or void");
+			}
+		}
+		else
+		{
+			throw PARSER_EXCEPTION_EXPECTED("identifier");
+		}
+
+		// Function name
+		scanner.getNextToken();
+		if(token->getCode() != Scanner::TC_IDENTIFIER)
+		{
+			throw PARSER_EXCEPTION_EXPECTED("identifier");
+		}
+
+		funcDef->name = token->getValue().getString();
+
+		// (
+		scanner.getNextToken();
+		if(token->getCode() != Scanner::TC_LPAREN)
+		{
+			throw PARSER_EXCEPTION_EXPECTED("(");
+		}
+
+		// Arguments
+		while(true)
+		{
+			ArgDefinition* argDef = new ArgDefinition;
+			funcDef->argDefinitions.push_back(argDef);
+
+			// Call type
+			scanner.getNextToken();
+			if(token->getCode() != Scanner::TC_IDENTIFIER)
+			{
+				throw PARSER_EXCEPTION_EXPECTED("identifier");
+			}
+
+			if(!strcmp(token->getValue().getString(), "in"))
+			{
+				argDef->callType = ACT_IN;
+			}
+			else if(!strcmp(token->getValue().getString(), "out"))
+			{
+				argDef->callType = ACT_OUT;
+			}
+			else if(!strcmp(token->getValue().getString(), "inout"))
+			{
+				argDef->callType = ACT_INOUT;
+			}
+			else
+			{
+				throw PARSER_EXCEPTION_EXPECTED("in or out or inout");
+			}
+
+			// Type
+			scanner.getNextToken();
+			if(token->getCode() != Scanner::TC_IDENTIFIER)
+			{
+				throw PARSER_EXCEPTION_EXPECTED("identifier");
+			}
+
+			if(!strcmp(token->getValue().getString(), "float"))
+			{
+				argDef->dataType = AT_FLOAT;
+			}
+			else if(!strcmp(token->getValue().getString(), "vec2"))
+			{
+				argDef->dataType = AT_VEC2;
+			}
+			else if(!strcmp(token->getValue().getString(), "vec3"))
+			{
+				argDef->dataType = AT_VEC3;
+			}
+			else if(!strcmp(token->getValue().getString(), "vec4"))
+			{
+				argDef->dataType = AT_VEC4;
+			}
+			else if(!strcmp(token->getValue().getString(), "sampler2D"))
+			{
+				argDef->dataType = AT_TEXTURE;
+			}
+			else
+			{
+				throw PARSER_EXCEPTION_EXPECTED("float or vec2 or vec3 or"
+					" vec4 or sampler2D");
+			}
+
+			// Name
+			scanner.getNextToken();
+			if(token->getCode() != Scanner::TC_IDENTIFIER)
+			{
+				throw PARSER_EXCEPTION_EXPECTED("identifier");
+			}
+
+			argDef->name = token->getValue().getString();
+
+			// ,
+			scanner.getNextToken();
+			if(token->getCode() == Scanner::TC_COMMA)
+			{
+				continue;
+			}
+			// )
+			else if(token->getCode() == Scanner::TC_RPAREN)
+			{
+				break;
+			}
+			else
+			{
+				throw PARSER_EXCEPTION_UNEXPECTED();
+			}
+		} // End arguments
+
+
+		// {
+		scanner.getNextToken();
+		if(token->getCode() != Scanner::TC_LBRACKET)
+		{
+			throw PARSER_EXCEPTION_EXPECTED("{");
+		}
+
+		// Skip until closing bracket
+		int bracketsNum = 0;
+		while(true)
+		{
+			scanner.getNextToken();
+
+			if(token->getCode() == Scanner::TC_RBRACKET)
+			{
+				if(bracketsNum == 0)
+				{
+					break;
+				}
+				--bracketsNum;
+			}
+			else if(token->getCode() == Scanner::TC_LBRACKET)
+			{
+				++bracketsNum;
+			}
+			else
+			{
+				continue;
+			}
+		} // End until closing bracket
+	} // End for all functions
+}

+ 260 - 0
src/Resources/Material2.h

@@ -0,0 +1,260 @@
+#ifndef MATERIAL_2_H
+#define MATERIAL_2_H
+
+#include "Util/Accessors.h"
+#include "RsrcPtr.h"
+#include <GL/glew.h>
+#include <boost/ptr_container/ptr_vector.hpp>
+#include <boost/array.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/property_tree/ptree_fwd.hpp>
+
+
+class SProgAttribVar;
+class SProgUniVar;
+class ShaderProg;
+class MaterialUserInputVariable;
+
+
+/// Contains a few properties that other classes may use
+struct MaterialProperties
+{
+	///< Used in depth passes of shadowmapping and not in other depth passes
+	/// like EarlyZ
+	bool castsShadowFlag;
+	/// The entities with blending are being rendered in blending stage and
+	/// those without in material stage
+	bool renderInBlendingStageFlag;
+	int blendingSfactor; ///< Default GL_ONE
+	int blendingDfactor; ///< Default GL_ZERO
+	bool depthTesting;
+	bool wireframe;
+};
+
+
+/// @code
+/// <material>
+/// 	<renderInBlendingStage>true | false</renderInBlendingStage>
+///
+/// 	<blendFuncs>
+/// 		<sFactor>GL_SOMETHING</sFactor>
+/// 		<dFactor>GL_SOMETHING</dFactor>
+/// 	</blendFuncs>
+///
+/// 	<depthTesting>true | false</depthTesting>
+///
+/// 	<wireframe>true | false</wireframe>
+///
+/// 	<castsShadow>true | false</castsShadow>
+///
+/// 	<shaderProgram>
+/// 		<include>file.glsl</include>
+///
+/// 		<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>
+/// 			</value>
+/// 		</in>
+///
+/// 		<operation>
+/// 			<id>x</id>
+/// 			<function>functionName</function>
+/// 			<parameters>
+/// 				<parameter>xx</parameter>
+/// 				<parameter>yy</parameter>
+/// 			</parameters>
+/// 		</operation>
+///
+/// 	</shaderProgram>
+/// </material>
+/// @endcode
+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();
+
+		~Material2();
+
+		/// @name Accessors
+		/// @{
+		GETTER_R_BY_VAL(bool, castsShadowFlag, castsShadow)
+		GETTER_R_BY_VAL(bool, renderInBlendingStageFlag, renderInBlendingStage)
+		GETTER_R_BY_VAL(int, blendingSfactor, getBlendingSfactor)
+		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<MaterialUserInputVariable>, inVars,
+			getMaterialUserInputVariables)
+
+		/// Access the base class just for copying in other classes
+		GETTER_R(MaterialProperties, *this, accessMaterialPropertiesBaseClass)
+
+		const ShaderProg& getShaderProgram() const {return *shaderProg;}
+
+		/// 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;
+		/// @}
+
+		/// Return false if blendingSfactor is equal to GL_ONE and
+		/// blendingDfactor to GL_ZERO
+		bool isBlendingEnabled() const;
+
+		/// Load a material file
+		void load(const char* filename);
+
+	private:
+		//======================================================================
+		// Nested                                                              =
+		//======================================================================
+
+		/// Function argument data type
+		enum ArgDataType
+		{
+			AT_TEXTURE,
+			AT_FLOAT,
+			AT_VEC2,
+			AT_VEC3,
+			AT_VEC4,
+			AT_VOID
+		};
+
+		/// Function argument data call type
+		enum ArgCallType
+		{
+			ACT_IN,
+			ACT_OUT,
+			ACT_INOUT
+		};
+
+		/// Function argument definition
+		struct ArgDefinition
+		{
+			std::string name;
+			ArgDataType dataType;
+			ArgCallType callType;
+		};
+
+		/// Function definition. It contains information about a function (eg
+		/// return type and the arguments)
+		struct FuncDefinition
+		{
+			std::string name; ///< Function name
+			boost::ptr_vector<ArgDefinition> argDefinitions;
+			ArgDataType returnArg;
+		};
+
+		/// Information for the standard shader program variables
+		struct StdVarNameAndGlDataTypePair
+		{
+			const char* varName;
+			GLenum dataType; ///< aka GL data type
+		};
+
+		//======================================================================
+		// Members                                                             =
+		//======================================================================
+
+		/// The input variables
+		boost::ptr_vector<MaterialUserInputVariable> inVars;
+
+		/// 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;
+
+		/// The most important aspect of materials
+		RsrcPtr<ShaderProg> shaderProg;
+
+		//======================================================================
+		// Methods                                                             =
+		//======================================================================
+
+		/// XXX
+		static void parseShaderFileForFunctionDefinitions(const char* filename,
+			boost::ptr_vector<FuncDefinition>& out);
+
+		/// Parse what is within the @code <material></material> @endcode
+		void parseMaterialTag(const boost::property_tree::ptree& pt);
+};
+
+
+inline bool Material2::isBlendingEnabled() const
+{
+	return blendingSfactor != GL_ONE || blendingDfactor != GL_ZERO;
+}
+
+
+inline const SProgAttribVar* Material2::getStandardAttributeVariable(
+	StandardAtributeVariables id) const
+{
+	return stdAttribVars[id];
+}
+
+
+inline const SProgUniVar* Material2::getStandardUniformVariable(
+	StandardUniformVariables id) const
+{
+	return stdUniVars[id];
+}
+
+
+#endif

+ 130 - 0
src/Resources/MaterialInputVariable.cpp

@@ -0,0 +1,130 @@
+#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;
+}
+
+
+MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
+	const Vec2& val)
+:	sProgVar(svar)
+{
+	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC2);
+	vec2 = val;
+}
+
+
+MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
+	const Vec3& val)
+:	sProgVar(svar)
+{
+	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC3);
+	vec3 = val;
+}
+
+
+MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
+	const Vec4& val)
+:	sProgVar(svar)
+{
+	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC4);
+	vec4 = val;
+}
+
+
+MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar, Fai val)
+:	sProgVar(svar)
+{
+	ASSERT(svar.getGlDataType() == GL_SAMPLER_2D);
+	fai = val;
+}
+
+
+MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
+	const char* texFilename)
+:	sProgVar(svar)
+{
+	ASSERT(svar.getGlDataType() == GL_SAMPLER_2D);
+	texture.loadRsrc(texFilename);
+}
+
+
+//==============================================================================
+// 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;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 65 - 0
src/Resources/MaterialInputVariable.h

@@ -0,0 +1,65 @@
+#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 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)
+		/// @}
+
+	private:
+		const SProgUniVar& sProgVar; ///< The shader program's uniform
+
+		/// @name Data
+		/// @{
+		float scalar;
+		Vec2 vec2;
+		Vec3 vec3;
+		Vec4 vec4;
+		Fai fai;
+		RsrcPtr<Texture> texture;
+		/// @}
+};
+
+#endif