소스 검색

Changing the Material behavior and structure so it can be more simplified and easy maintainable

Panagiotis Christopoulos Charitos 15 년 전
부모
커밋
af114f53cc

+ 3 - 3
build/README

@@ -71,9 +71,9 @@ build system that generates GNU makefiles.
 
 	And the build process will begin. 
 
-	WARNING: Sometimes I forget to update all the targets. The debug is always
-	updated though.
-
 	The gen.cfg.py files contain the build options of every target. Their format
 	is pretty straightforward and minimal.
+
+	WARNING: Sometimes I forget to update all the targets. The debug is always
+	updated though.
 	

+ 0 - 1
build/debug/gen.cfg.py

@@ -1,7 +1,6 @@
 sourcePaths = [ "../../src/Math/", "../../src/Util/Tokenizer/", "../../src/Misc/", "../../src/", "../../src/Renderer/", "../../src/Scene/", "../../src/Ui/", "../../src/Resources/", "../../src/Util/", "../../src/Scene/Controllers/", "../../src/Physics/", "../../src/Renderer/BufferObjects/", "../../src/Resources/Helpers/" ]
 
 includePaths = list(sourcePaths)
-#includePaths.extend( [ "../../../bullet_svn/src/", "/usr/include/SDL" ] )
 includePaths.extend( [ "../../../bullet_svn/src/", "../../../SDL-hg/include", "../../glew/include" ] )
 
 precompiledHeaders = []

BIN
docs/renderer-flow.odg


+ 3 - 50
src/Renderer/Renderer.cpp

@@ -119,44 +119,12 @@ void Renderer::setupMaterial( const Material& mtl )
 	uint textureUnit = 0;
 	for( uint i=0; i<mtl.userDefinedVars.size(); i++ )
 	{
-		const Material::UserDefinedVar* udv = &mtl.userDefinedVars[i];
+		const Material::UserDefinedUniVar* udv = &mtl.userDefinedVars[i];
 		switch( udv->sProgVar->getGlDataType() )
 		{
 			// texture
 			case GL_SAMPLER_2D:
-				switch( udv->specialValue )
-				{
-					case Material::SV_NONE:
-						udv->sProgVar->setTexture( *udv->value.texture, textureUnit++ );
-						break;
-
-					case Material::SV_MS_NORMAL_FAI:
-						udv->sProgVar->setTexture( ms.normalFai, textureUnit++ );
-						break;
-
-					case Material::SV_MS_DIFFUSE_FAI:
-						udv->sProgVar->setTexture( ms.diffuseFai, textureUnit++ );
-						break;
-
-					case Material::SV_MS_SPECULAR_FAI:
-						udv->sProgVar->setTexture( ms.specularFai, textureUnit++ );
-						break;
-
-					case Material::SV_MS_DEPTH_FAI:
-						udv->sProgVar->setTexture( ms.depthFai, textureUnit++ );
-						break;
-
-					case Material::SV_IS_FAI:
-						udv->sProgVar->setTexture( is.fai, textureUnit++ );
-						break;
-
-					case Material::SV_PPS_FAI:
-						udv->sProgVar->setTexture( pps.fai, textureUnit++ );
-						break;
-
-					default:
-						DEBUG_ERR( 1 );
-				}
+				udv->sProgVar->setTexture( *udv->value.texture, textureUnit++ );
 				break;
 			// float
 			case GL_FLOAT:
@@ -164,22 +132,7 @@ void Renderer::setupMaterial( const Material& mtl )
 				break;
 			// vec2
 			case GL_FLOAT_VEC2:
-				switch( udv->specialValue )
-				{
-					case Material::SV_NONE:
-						udv->sProgVar->setVec2( &udv->value.vec2 );
-						break;
-
-					case Material::SV_RENDERER_SIZE:
-					{
-						Vec2 v( width, height );
-						udv->sProgVar->setVec2( &v );
-						break;
-					}
-
-					default:
-						DEBUG_ERR( 1 );
-				}
+				udv->sProgVar->setVec2( &udv->value.vec2 );
 				break;
 			// vec3
 			case GL_FLOAT_VEC3:

+ 1 - 1
src/Renderer/Renderer.h

@@ -324,7 +324,7 @@ class Renderer
 	PROPERTY_R( uint, width, getWidth ) ///< Width of the rendering. Dont confuse with the window width
 	PROPERTY_R( uint, height, getHeight ) ///< Height of the rendering. Dont confuse with the window width
 	PROPERTY_R( uint, framesNum, getFramesNum )
-	PROPERTY_R( float, aspectRatio, getAspectRatio )
+	PROPERTY_R( float, aspectRatio, getAspectRatio ) ///< Just a precalculated value
 
 	protected:
 		// the rest

+ 95 - 88
src/Resources/Material.cpp

@@ -13,6 +13,38 @@
 #define MTL_ERROR( x ) ERROR( "Material (" << getRsrcPath() << getRsrcName() << "): " << x );
 
 
+//=====================================================================================================================================
+// Statics                                                                                                                            =
+//=====================================================================================================================================
+Material::StdVarInfo Material::stdAttribVarInfos[ SAV_NUM ] =
+{
+	{ "position", GL_FLOAT_VEC3 },
+	{ "tangent", GL_FLOAT_VEC4 },
+	{ "normal", GL_FLOAT_VEC3 },
+	{ "texCoords", GL_FLOAT_VEC2 },
+	{ "vertWeightBonesNum", GL_FLOAT },
+	{ "vertWeightBoneIds", GL_FLOAT_VEC4},
+	{ "vertWeightWeights", GL_FLOAT_VEC4 }
+};
+
+Material::StdVarInfo Material::stdUniVarInfos[ SUV_NUM ] =
+{
+	{ "skinningRotations", GL_FLOAT_MAT3},
+	{ "skinningTranslations", GL_FLOAT_VEC3 },
+	{ "modelViewMat", GL_FLOAT_MAT4 },
+	{ "projectionMat", GL_FLOAT_MAT4 },
+	{ "modelViewProjectionMat", GL_FLOAT_MAT4 },
+	{ "normalMat", GL_FLOAT_MAT3 },
+	{ "msNormalFai", GL_TEXTURE_2D },
+	{ "msDiffuseFai", GL_TEXTURE_2D },
+	{ "msSpecularFai", GL_TEXTURE_2D },
+	{ "msDepthFai", GL_TEXTURE_2D },
+	{ "isFai", GL_TEXTURE_2D },
+	{ "ppsFai", GL_TEXTURE_2D },
+	{ "rendererSize", GL_FLOAT_VEC2 }
+};
+
+
 //=====================================================================================================================================
 // Blending stuff                                                                                                                     =
 //=====================================================================================================================================
@@ -215,8 +247,8 @@ bool Material::load( const char* filename )
 				string varName;
 				varName = token->getValue().getString();
 
-				userDefinedVars.push_back( UserDefinedVar() ); // create new var
-				UserDefinedVar& var = userDefinedVars.back();
+				userDefinedVars.push_back( UserDefinedUniVar() ); // create new var
+				UserDefinedUniVar& var = userDefinedVars.back();
 
 				// check if the uniform exists
 				if( !shaderProg->uniVarExists( varName.c_str() ) )
@@ -237,33 +269,9 @@ bool Material::load( const char* filename )
 						{
 							var.value.texture = Rsrc::textures.load( token->getValue().getString() );
 						}
-						else if( token->getCode() == Scanner::TC_IDENTIFIER && !strcmp( token->getValue().getString(), "MS_NORMAL_FAI" ) )
-						{
-							var.specialValue = SV_MS_NORMAL_FAI;
-						}
-						else if( token->getCode() == Scanner::TC_IDENTIFIER && !strcmp( token->getValue().getString(), "MS_DIFFUSE_FAI" ) )
-						{
-							var.specialValue = SV_MS_DIFFUSE_FAI;
-						}
-						else if( token->getCode() == Scanner::TC_IDENTIFIER && !strcmp( token->getValue().getString(), "MS_SPECULAR_FAI" ) )
-						{
-							var.specialValue = SV_MS_SPECULAR_FAI;
-						}
-						else if( token->getCode() == Scanner::TC_IDENTIFIER && !strcmp( token->getValue().getString(), "MS_DEPTH_FAI" ) )
-						{
-							var.specialValue = SV_MS_DEPTH_FAI;
-						}
-						else if( token->getCode() == Scanner::TC_IDENTIFIER && !strcmp( token->getValue().getString(), "IS_FAI" ) )
-						{
-							var.specialValue = SV_IS_FAI;
-						}
-						else if( token->getCode() == Scanner::TC_IDENTIFIER && !strcmp( token->getValue().getString(), "PPS_FAI" ) )
-						{
-							var.specialValue = SV_PPS_FAI;
-						}
 						else
 						{
-							PARSE_ERR_EXPECTED( "string or MS_NORMAL_FAI or MS_DIFFUSE_FAI or MS_SPECULAR_FAI or MS_DEPTH_FAI or IS_FAI or PPS_FAI" );
+							PARSE_ERR_EXPECTED( "string" );
 							return false;
 						}
 						break;
@@ -280,30 +288,7 @@ bool Material::load( const char* filename )
 						break;
 					// vec2
 					case GL_FLOAT_VEC2:
-						// {
-						token = &scanner.getNextToken();
-						if( token->getCode() == Scanner::TC_LBRACKET )
-						{
-							if( !Parser::parseArrOfNumbers<float>( scanner, false, true, 2, &var.value.vec2[0] ) )
-								return false;
-
-							// }
-							token = &scanner.getNextToken();
-							if( token->getCode() != Scanner::TC_RBRACKET )
-							{
-								PARSE_ERR_EXPECTED( "}" );
-								return false;
-							}
-						}
-						else if( token->getCode() == Scanner::TC_IDENTIFIER && !strcmp( token->getValue().getString(), "RENDERER_SIZE" ) )
-						{
-							var.specialValue = SV_RENDERER_SIZE;
-						}
-						else
-						{
-							PARSE_ERR_EXPECTED( "{ or RENDERER_SIZE" );
-							return false;
-						}
+						if( !Parser::parseArrOfNumbers<float>( scanner, true, true, 2, &var.value.vec2[0] ) ) return false;
 						break;
 					// vec3
 					case GL_FLOAT_VEC3:
@@ -332,14 +317,14 @@ bool Material::load( const char* filename )
 
 	}while( true );
 
-	return additionalInit();
+	return initStdShaderVars();
 }
 
 
 //=====================================================================================================================================
-// additionalInit                                                                                                                     =
+// initStdShaderVars                                                                                                                  =
 //=====================================================================================================================================
-bool Material::additionalInit()
+bool Material::initStdShaderVars()
 {
 	// sanity checks
 	if( !shaderProg )
@@ -348,51 +333,59 @@ bool Material::additionalInit()
 		return false;
 	}
 
-	// init the attribute locations
-	attribLocs.tanget = shaderProg->attribVarExists( "tangent" ) ?  shaderProg->findAttribVar( "tangent" )->getLoc() : -1;
-	attribLocs.position = shaderProg->attribVarExists( "position" ) ?  shaderProg->findAttribVar( "position" )->getLoc() : -1;
-	attribLocs.normal = shaderProg->attribVarExists( "normal" ) ?  shaderProg->findAttribVar( "normal" )->getLoc() : -1;
-	attribLocs.texCoords = shaderProg->attribVarExists( "texCoords" ) ?  shaderProg->findAttribVar( "texCoords" )->getLoc() : -1;
-
-	// vertex weights
-	if( shaderProg->attribVarExists( "vertWeightBonesNum" ) )
+	// the attributes
+	for( uint i=0; i<SAV_NUM; i++ )
 	{
-		attribLocs.vertWeightBonesNum = shaderProg->findAttribVar( "vertWeightBonesNum" )->getLoc();
-		attribLocs.vertWeightBoneIds = shaderProg->findAttribVar( "vertWeightBoneIds" )->getLoc();
-		attribLocs.vertWeightWeights = shaderProg->findAttribVar( "vertWeightWeights" )->getLoc();
-		uniLocs.skinningRotations = shaderProg->findUniVar( "skinningRotations" )->getLoc();
-		uniLocs.skinningTranslations = shaderProg->findUniVar( "skinningTranslations" )->getLoc();
+		// if the var is not in the sProg then... bye
+		if( !shaderProg->attribVarExists( stdAttribVarInfos[i].varName ) )
+		{
+			stdAttribVars[ i ] = NULL;
+			continue;
+		}
+
+		// set the std var
+		stdAttribVars[ i ] = shaderProg->findAttribVar( stdAttribVarInfos[i].varName );
+
+		// check if the shader has different GL data type from that it suppose to have
+		if( stdAttribVars[ i ]->getGlDataType() != stdAttribVarInfos[i].dataType )
+		{
+			MTL_ERROR( "The \"" << stdAttribVarInfos[i].varName << "\" attribute var has incorrect GL data type from the expected (0x" <<
+			           hex << stdAttribVars[ i ]->getGlDataType() << ")" );
+			return false;
+		}
 	}
-	else
+
+	// the uniforms
+	for( uint i=0; i<SUV_NUM; i++ )
 	{
-		attribLocs.vertWeightBonesNum = attribLocs.vertWeightBoneIds = attribLocs.vertWeightWeights = uniLocs.skinningRotations =
-		uniLocs.skinningTranslations = -1;
-	}
+		// if the var is not in the sProg then... bye
+		if( !shaderProg->uniVarExists( stdUniVarInfos[i].varName ) )
+		{
+			stdUniVars[ i ] = NULL;
+			continue;
+		}
 
-	return true;
-}
+		// set the std var
+		stdUniVars[ i ] = shaderProg->findUniVar( stdUniVarInfos[i].varName );
 
+		// check if the shader has different GL data type from that it suppose to have
+		if( stdUniVars[ i ]->getGlDataType() != stdUniVarInfos[i].dataType )
+		{
+			MTL_ERROR( "The \"" << stdUniVarInfos[i].varName << "\" uniform var has incorrect GL data type from the expected (0x" <<
+			           hex << stdUniVars[ i ]->getGlDataType() << ")" );
+			return false;
+		}
+	}
 
-//=====================================================================================================================================
-// unload                                                                                                                             =
-//=====================================================================================================================================
-void Material::unload()
-{
-	Rsrc::shaders.unload( shaderProg );
 
-	// loop all user defined vars and unload the textures
-	for( uint i=0; i<userDefinedVars.size(); i++ )
-	{
-		if( userDefinedVars[i].sProgVar->getGlDataType() == GL_SAMPLER_2D && userDefinedVars[i].specialValue != SV_NONE )
-			Rsrc::textures.unload( userDefinedVars[i].value.texture );
-	}
+	return true;
 }
 
 
 //=====================================================================================================================================
-// setToDefault                                                                                                                       =
+// Constructor                                                                                                                        =
 //=====================================================================================================================================
-void Material::setToDefault()
+Material::Material()
 {
 	shaderProg = NULL;
 	blends = false;
@@ -405,6 +398,20 @@ void Material::setToDefault()
 	dpMtl = NULL;
 }
 
+//=====================================================================================================================================
+// unload                                                                                                                             =
+//=====================================================================================================================================
+void Material::unload()
+{
+	Rsrc::shaders.unload( shaderProg );
+
+	// loop all user defined vars and unload the textures
+	for( uint i=0; i<userDefinedVars.size(); i++ )
+	{
+		Rsrc::textures.unload( userDefinedVars[i].value.texture );
+	}
+}
+
 
 //=====================================================================================================================================
 // setup                                                                                                                              =
@@ -432,7 +439,7 @@ void Material::setup()
 
 	// now loop all the user defined vars and set them
 	uint texture_Unit = 0;
-	Vec<UserDefinedVar>::iterator udv;
+	Vec<UserDefinedUniVar>::iterator udv;
 	for( udv=userDefinedVars.begin(); udv!=userDefinedVars.end(); udv++ )
 	{
 		switch( udv->sProgVar->getGlDataType() )

+ 70 - 55
src/Resources/Material.h

@@ -8,7 +8,11 @@
 
 
 /**
- * Mesh material @ref Resource resource
+ * Mesh material @ref Resource
+ *
+ * Every material keeps among other things the locations of the attribute and uniform variables. The attributes come from a selection
+ * of standard vertex attributes. We dont have to write these attribs in the .mtl file. The uniforms on the other hand are in two
+ * categories. The standard uniforms that we dont have to write in the file and the user defined.
  */
 class Material: public Resource
 {
@@ -17,32 +21,61 @@ class Material: public Resource
 
 	protected:
 		/**
-		 *
+		 * Standard attribute variables that are acceptable inside the @ref ShaderProg
 		 */
-		enum SpecialVar
+		enum StdAttribVars
 		{
-			SV_NONE,           ///< SV_NONE
-			// Texture
-			SV_MS_NORMAL_FAI,  ///< SV_MS_NORMAL_FAI
-			SV_MS_DIFFUSE_FAI, ///< SV_MS_DIFFUSE_FAI
-			SV_MS_SPECULAR_FAI,///< SV_MS_SPECULAR_FAI
-			SV_MS_DEPTH_FAI,   ///< SV_MS_DEPTH_FAI
-			SV_IS_FAI,         ///< SV_IS_FAI
-			SV_PPS_FAI,        ///< SV_PPS_FAI
-			// Vec2
-			SV_RENDERER_SIZE, ///< Active renderer's width and height
-			// Mat3
-			SV_NORMAL_MAT,
-			// Mat4
-			SV_MODELVIEW_MAT,
-			SV_PROJECTION_MAT,
-			SV_MODELVIEWPROJECTION_MAT
+			SAV_POSITION,
+			SAV_TANGENT,
+			SAV_NORMAL,
+			SAV_TEX_COORDS,
+			SAV_VERT_WEIGHT_BONES_NUM,
+			SAV_VERT_WEIGHT_BONE_IDS,
+			SAV_VERT_WEIGHT_WEIGHTS,
+			SAV_NUM
 		};
 
+
+		/**
+		 * Standard uniform variables
+		 */
+		enum StdUniVars
+		{
+			// Skinning
+			SUV_SKINNING_ROTATIONS,
+			SUV_SKINNING_TRANSLATIONS,
+			// Matrices
+			SUV_MODELVIEW_MAT,
+			SUV_PROJECTION_MAT,
+			SUV_MODELVIEWPROJECTION_MAT,
+			SUV_NORMAL_MAT,
+			// FAIs
+			SUV_MS_NORMAL_FAI,
+			SUV_MS_DIFFUSE_FAI,
+			SUV_MS_SPECULAR_FAI,
+			SUV_MS_DEPTH_FAI,
+			SUV_IS_FAI,
+			SUV_PPS_FAI,
+			// Other
+			SUV_RENDERER_SIZE,
+			SUV_NUM ///< The number of standard uniform variables
+		};
+
+
+		/**
+		 * Information for the standard shader program variables
+		 */
+		struct StdVarInfo
+		{
+			const char* varName;
+			GLenum dataType; ///< aka GL data type
+		};
+
+
 		/**
 		 * Class for user defined material variables that will be passes in to the shader
 		 */
-		struct UserDefinedVar
+		struct UserDefinedUniVar
 		{
 			struct Value  // unfortunately we cannot use union because of Vec3 and Vec4
 			{
@@ -56,59 +89,41 @@ class Material: public Resource
 			};
 
 			Value value;
-			SpecialVar specialValue;
 			const ShaderProg::UniVar* sProgVar;
-
-			UserDefinedVar(): specialValue( SV_NONE ) {}
 		}; // end UserDefinedVar
 
-		static map<string, SpecialVar> keywordToSpecial;
 
+		static StdVarInfo stdAttribVarInfos[ SAV_NUM ];
+		static StdVarInfo stdUniVarInfos[ SUV_NUM ];
+		const ShaderProg::AttribVar* stdAttribVars[ SAV_NUM ];
+		const ShaderProg::UniVar* stdUniVars[ SUV_NUM ];
 		ShaderProg* shaderProg; ///< The most important aspect of materials
-
+		Material* dpMtl; ///< The material for depth passes. To be removed when skinning is done using tranform feedback
+		Vec<UserDefinedUniVar> userDefinedVars;
 		bool blends; ///< The entities with blending are being rendered in blending stage and those without in material stage
-		int  blendingSfactor;
-		int  blendingDfactor;
+		int blendingSfactor;
+		int blendingDfactor;
 		bool refracts;
 		bool depthTesting;
 		bool wireframe;
 		bool castsShadow; ///< Used in shadowmapping passes but not in EarlyZ
-		Vec<UserDefinedVar> userDefinedVars;
 
-		// vertex attributes
-		struct
-		{
-			int position;
-			int tanget;
-			int normal;
-			int texCoords;
-
-			// for hw skinning
-			int vertWeightBonesNum;
-			int vertWeightBoneIds;
-			int vertWeightWeights;
-		} attribLocs;
-
-		// uniforms
-		struct
-		{
-			int skinningRotations;
-			int skinningTranslations;
-		} uniLocs;
 
-		Material* dpMtl;
+		/**
+		 * The func sweeps all the variables of the shader program to find standard shader program variables. It updates the stdAttribVars
+		 * and stdUniVars arrays.
+		 * @return True on success
+		 */
+		bool initStdShaderVars();
 
-		void setToDefault();
-		bool additionalInit(); ///< The func is for not polluting load with extra code
-		
 	public:
-		Material() { setToDefault(); }
+		Material();
 		void setup();
 		bool load( const char* filename );
 		void unload();
 
-		bool hasHWSkinning() const { return attribLocs.vertWeightBonesNum != -1; }
-		bool hasAlphaTesting() const { return dpMtl!=NULL && dpMtl->attribLocs.texCoords!=-1; }
+		bool hasHWSkinning() const { return stdAttribVars[ SAV_VERT_WEIGHT_BONES_NUM ] != NULL; }
+		bool hasAlphaTesting() const { return dpMtl!=NULL && dpMtl->stdAttribVars[ SAV_TEX_COORDS ] != NULL; }
 };
 
 

+ 13 - 0
src/Resources/ShaderProg.cpp

@@ -26,36 +26,49 @@ string ShaderProg::stdSourceCode(
 void ShaderProg::UniVar::setFloat( float f ) const
 {
 	STD_SET_UNI_CHECK();
+	DEBUG_ERR( getGlDataType() != GL_FLOAT );
 	glUniform1f( getLoc(), f );
 }
 
 void ShaderProg::UniVar::setFloatVec( float f[], uint size ) const
 {
 	STD_SET_UNI_CHECK();
+	DEBUG_ERR( getGlDataType() != GL_FLOAT );
 	glUniform1fv( getLoc(), size, f );
 }
 
 void ShaderProg::UniVar::setVec2( const Vec2 v2[], uint size ) const
 {
 	STD_SET_UNI_CHECK();
+	DEBUG_ERR( getGlDataType() != GL_FLOAT_VEC2 );
 	glUniform2fv( getLoc(), size, &( const_cast<Vec2&>(v2[0]) )[0] );
 }
 
 void ShaderProg::UniVar::setVec3( const Vec3 v3[], uint size ) const
 {
 	STD_SET_UNI_CHECK();
+	DEBUG_ERR( getGlDataType() != GL_FLOAT_VEC3 );
 	glUniform3fv( getLoc(), size, &( const_cast<Vec3&>(v3[0]) )[0] );
 }
 
 void ShaderProg::UniVar::setVec4( const Vec4 v4[], uint size ) const
 {
 	STD_SET_UNI_CHECK();
+	DEBUG_ERR( getGlDataType() != GL_FLOAT_VEC4 );
 	glUniform4fv( getLoc(), size, &( const_cast<Vec4&>(v4[0]) )[0] );
 }
 
+void ShaderProg::UniVar::setMat3( const Mat3 m3[], uint size ) const
+{
+	STD_SET_UNI_CHECK();
+	DEBUG_ERR( getGlDataType() != GL_FLOAT_MAT3 );
+	glUniformMatrix3fv( getLoc(), size, true, &(m3[0])[0] );
+}
+
 void ShaderProg::UniVar::setMat4( const Mat4 m4[], uint size ) const
 {
 	STD_SET_UNI_CHECK();
+	DEBUG_ERR( getGlDataType() != GL_FLOAT_MAT4 );
 	glUniformMatrix4fv( getLoc(), size, true, &(m4[0])[0] );
 }
 

+ 1 - 0
src/Resources/ShaderProg.h

@@ -74,6 +74,7 @@ class ShaderProg: public Resource
 				void setVec2( const Vec2 v2[], uint size = 1 ) const;
 				void setVec3( const Vec3 v3[], uint size = 1 ) const;
 				void setVec4( const Vec4 v4[], uint size = 1 ) const;
+				void setMat3( const Mat3 m3[], uint size = 1 ) const;
 				void setMat4( const Mat4 m4[], uint size = 1 ) const;
 				void setTexture( const Texture& tex, uint texUnit ) const;
 		};

+ 49 - 35
src/Scene/MeshNode.cpp

@@ -19,7 +19,7 @@ void MeshNode::init( const char* filename )
 	material = Rsrc::materials.load( mesh->materialName.c_str() );
 
 	// sanity checks
-	if( material->attribLocs.texCoords != -1 && mesh->vbos.texCoords.getGlId() == 0 )
+	if( material->stdAttribVars[Material::SAV_TEX_COORDS]==NULL && mesh->vbos.texCoords.getGlId() == 0 )
 	{
 		ERROR( "The shader program needs information that the mesh do not have" );
 	}
@@ -39,59 +39,80 @@ void MeshNode::deinit()
 //=====================================================================================================================================
 // render                                                                                                                             =
 //=====================================================================================================================================
-/// Called in material or blending stages
 void MeshNode::render( Material* mtl ) const
 {
+	GLint loc;
+	GLint locs[ 64 ];
+	int locsNum = 0;
+
 	glPushMatrix();
 	app->getMainRenderer()->multMatrix( Mat4(getWorldTransform()) );
 
 	// if we have skeleton controller
 	if( meshSkelCtrl )
 	{
+		DEBUG_ERR( !mtl->hasHWSkinning() ); // it has skel controller but no skinning
+
 		// first the uniforms
-		glUniformMatrix3fv( mtl->uniLocs.skinningRotations, meshSkelCtrl->skelNode->skeleton->bones.size(), 1,
-		                    &(meshSkelCtrl->skelNode->skelAnimCtrl->boneRotations[0])[0] );
-		glUniform3fv( mtl->uniLocs.skinningTranslations, meshSkelCtrl->skelNode->skeleton->bones.size(),
-		              &(meshSkelCtrl->skelNode->skelAnimCtrl->boneTranslations[0])[0] );
+		mtl->stdUniVars[ Material::SUV_SKINNING_ROTATIONS ]->setMat3( &meshSkelCtrl->skelNode->skelAnimCtrl->boneRotations[0],
+		                                                              meshSkelCtrl->skelNode->skeleton->bones.size() );
 
-		// then the attributes
-		DEBUG_ERR( !mtl->hasHWSkinning() ); // it has skel controller but no skinning
+		mtl->stdUniVars[ Material::SUV_SKINNING_TRANSLATIONS ]->setVec3( &meshSkelCtrl->skelNode->skelAnimCtrl->boneTranslations[0],
+		                                                                 meshSkelCtrl->skelNode->skeleton->bones.size() );
 
+		// then the attributes
 		mesh->vbos.vertWeights.bind();
-		glEnableVertexAttribArray( mtl->attribLocs.vertWeightBonesNum );
-		glVertexAttribPointer( mtl->attribLocs.vertWeightBonesNum, 1, GL_FLOAT, GL_FALSE, sizeof(Mesh::VertexWeight), BUFFER_OFFSET(0) );
-		glEnableVertexAttribArray( mtl->attribLocs.vertWeightBoneIds );
-		glVertexAttribPointer( mtl->attribLocs.vertWeightBoneIds, 4, GL_FLOAT, GL_FALSE, sizeof(Mesh::VertexWeight), BUFFER_OFFSET(4) );
-		glEnableVertexAttribArray( mtl->attribLocs.vertWeightWeights );
-		glVertexAttribPointer( mtl->attribLocs.vertWeightWeights, 4, GL_FLOAT, GL_FALSE, sizeof(Mesh::VertexWeight), BUFFER_OFFSET(20) );
+
+		loc = mtl->stdAttribVars[ Material::SAV_VERT_WEIGHT_BONES_NUM ]->getLoc();
+		glEnableVertexAttribArray( loc );
+		locs[ locsNum++ ] = loc;
+		glVertexAttribPointer( loc, 1, GL_FLOAT, GL_FALSE, sizeof(Mesh::VertexWeight), BUFFER_OFFSET(0) );
+
+		loc = mtl->stdAttribVars[ Material::SAV_VERT_WEIGHT_BONE_IDS ]->getLoc();
+		glEnableVertexAttribArray( loc );
+		locs[ locsNum++ ] = loc;
+		glVertexAttribPointer( loc, 4, GL_FLOAT, GL_FALSE, sizeof(Mesh::VertexWeight), BUFFER_OFFSET(4) );
+
+		loc = mtl->stdAttribVars[ Material::SAV_VERT_WEIGHT_WEIGHTS ]->getLoc();
+		glEnableVertexAttribArray( loc );
+		locs[ locsNum++ ] = loc;
+		glVertexAttribPointer( loc, 4, GL_FLOAT, GL_FALSE, sizeof(Mesh::VertexWeight), BUFFER_OFFSET(20) );
 	}
 
-	if( mtl->attribLocs.position != -1 )
+	if( mtl->stdAttribVars[ Material::SAV_POSITION ] != NULL )
 	{
 		mesh->vbos.vertCoords.bind();
-		glVertexAttribPointer( mtl->attribLocs.position, 3, GL_FLOAT, false, 0, NULL );
-		glEnableVertexAttribArray( mtl->attribLocs.position );
+		loc = mtl->stdAttribVars[ Material::SAV_POSITION ]->getLoc();
+		glVertexAttribPointer( loc, 3, GL_FLOAT, false, 0, NULL );
+		glEnableVertexAttribArray( loc );
+		locs[ locsNum++ ] = loc;
 	}
 
-	if( mtl->attribLocs.normal != -1 )
+	if( mtl->stdAttribVars[ Material::SAV_NORMAL ] != NULL )
 	{
 		mesh->vbos.vertNormals.bind();
-		glVertexAttribPointer( mtl->attribLocs.normal, 3, GL_FLOAT, false, 0, NULL );
-		glEnableVertexAttribArray( mtl->attribLocs.normal );
+		loc = mtl->stdAttribVars[ Material::SAV_NORMAL ]->getLoc();
+		glVertexAttribPointer( loc, 3, GL_FLOAT, false, 0, NULL );
+		glEnableVertexAttribArray( loc );
+		locs[ locsNum++ ] = loc;
 	}
 
-	if( mtl->attribLocs.texCoords != -1 )
+	if( mtl->stdAttribVars[ Material::SAV_TEX_COORDS ] != NULL )
 	{
 		mesh->vbos.texCoords.bind();
-		glVertexAttribPointer( mtl->attribLocs.texCoords, 2, GL_FLOAT, false, 0, NULL );
-		glEnableVertexAttribArray( mtl->attribLocs.texCoords );
+		loc = mtl->stdAttribVars[ Material::SAV_TEX_COORDS ]->getLoc();
+		glVertexAttribPointer( loc, 2, GL_FLOAT, false, 0, NULL );
+		glEnableVertexAttribArray( loc );
+		locs[ locsNum++ ] = loc;
 	}
 
-	if( mtl->attribLocs.tanget != -1 )
+	if( mtl->stdAttribVars[ Material::SAV_TANGENT ] != NULL )
 	{
 		mesh->vbos.vertTangents.bind();
-		glVertexAttribPointer( mtl->attribLocs.tanget, 4, GL_FLOAT, false, 0, NULL );
-		glEnableVertexAttribArray( mtl->attribLocs.tanget );
+		loc = mtl->stdAttribVars[ Material::SAV_TANGENT ]->getLoc();
+		glVertexAttribPointer( loc, 4, GL_FLOAT, false, 0, NULL );
+		glEnableVertexAttribArray( loc );
+		locs[ locsNum++ ] = loc;
 	}
 
 	mesh->vbos.vertIndeces.bind();
@@ -99,16 +120,9 @@ void MeshNode::render( Material* mtl ) const
 	glDrawElements( GL_TRIANGLES, mesh->vertIndeces.size(), GL_UNSIGNED_SHORT, 0 );
 
 	// disable
-	if( mtl->attribLocs.position != -1 ) glDisableVertexAttribArray( mtl->attribLocs.position );
-	if( mtl->attribLocs.normal != -1 ) glDisableVertexAttribArray( mtl->attribLocs.normal );
-	if( mtl->attribLocs.texCoords != -1 ) glDisableVertexAttribArray( mtl->attribLocs.texCoords );
-	if( mtl->attribLocs.tanget != -1 ) glDisableVertexAttribArray( mtl->attribLocs.tanget );
-
-	if( meshSkelCtrl )
+	for( int i=0; i<locsNum; i++ )
 	{
-		glDisableVertexAttribArray( mtl->attribLocs.vertWeightBonesNum );
-		glDisableVertexAttribArray( mtl->attribLocs.vertWeightBoneIds );
-		glDisableVertexAttribArray( mtl->attribLocs.vertWeightWeights );
+		glDisableVertexAttribArray( locs[i] );
 	}
 
 	Vbo::unbindAllTargets();

+ 2 - 2
src/Util/Tokenizer/Scanner.h

@@ -129,12 +129,12 @@ class Scanner
 		/// The Token class
 		struct Token
 		{
+			friend class Scanner;
+
 			PROPERTY_R( TokenCode, code, getCode ) ///< @ref PROPERTY_R : The first thing you shoud know about a token
 			PROPERTY_R( TokenDataType, dataType, getDataType ) ///< @ref PROPERTY_R : Additional info in case @ref code is @ref TC_NUMBER
 			PROPERTY_R( TokenDataVal, value, getValue ) ///< @ref PROPERTY_R : A value variant
 
-			friend class Scanner;
-
 			private:
 				char asString[ MAX_SCRIPT_LINE_LEN ];