Ver código fonte

New material

Panagiotis Christopoulos Charitos 14 anos atrás
pai
commit
a360cba8b1

+ 2 - 3
shaders/Dbg.glsl

@@ -1,5 +1,4 @@
-///
-#pragma anki vertShaderBegins
+#pragma anki start vertexShader
 
 
 layout(location = 0) in vec3 position;
 layout(location = 0) in vec3 position;
 layout(location = 1) in vec3 color;
 layout(location = 1) in vec3 color;
@@ -14,7 +13,7 @@ void main()
 	gl_Position = modelViewProjectionMat * vec4(position, 1.0);
 	gl_Position = modelViewProjectionMat * vec4(position, 1.0);
 }
 }
 
 
-#pragma anki fragShaderBegins
+#pragma anki start fragmentShader
 
 
 in vec3 vColor;
 in vec3 vColor;
 
 

+ 92 - 78
shaders/IsLpGeneric.glsl

@@ -2,19 +2,21 @@
 ///
 ///
 /// Illumination stage lighting pass general shader program
 /// Illumination stage lighting pass general shader program
 
 
-#pragma anki vertShaderBegins
+#pragma anki start vertexShader
 
 
 #pragma anki include "shaders/SimpleVert.glsl"
 #pragma anki include "shaders/SimpleVert.glsl"
 
 
-#pragma anki fragShaderBegins
+#pragma anki start fragmentShader
 
 
 #pragma anki include "shaders/Pack.glsl"
 #pragma anki include "shaders/Pack.glsl"
 
 
 /// @name Uniforms
 /// @name Uniforms
 /// @{
 /// @{
 uniform vec2 planes; ///< for the calculation of frag pos in view space
 uniform vec2 planes; ///< for the calculation of frag pos in view space
-uniform vec2 limitsOfNearPlane; ///< for the calculation of frag pos in view space
-uniform vec2 limitsOfNearPlane2; ///< This is an optimization see PpsSsao.glsl and r403 for the clean one
+/// for the calculation of frag pos in view space
+uniform vec2 limitsOfNearPlane; 
+/// This is an optimization see PpsSsao.glsl and r403 for the clean one
+uniform vec2 limitsOfNearPlane2; 
 uniform float zNear; ///< for the calculation of frag pos in view space
 uniform float zNear; ///< for the calculation of frag pos in view space
 
 
 uniform sampler2D msNormalFai, msDiffuseFai, msSpecularFai, msDepthFai;
 uniform sampler2D msNormalFai, msDiffuseFai, msSpecularFai, msDepthFai;
@@ -46,9 +48,9 @@ out vec3 fColor;
 const float MAX_SHININESS = 128.0;
 const float MAX_SHININESS = 128.0;
 
 
 
 
-//======================================================================================================================
-// getFragPosVSpace                                                                                                    =
-//======================================================================================================================
+//==============================================================================
+// getFragPosVSpace                                                            =
+//==============================================================================
 /// @return frag pos in view space
 /// @return frag pos in view space
 vec3 getFragPosVSpace()
 vec3 getFragPosVSpace()
 {
 {
@@ -71,10 +73,11 @@ vec3 getFragPosVSpace()
 }
 }
 
 
 
 
-//======================================================================================================================
-// getAttenuation                                                                                                      =
-//======================================================================================================================
-/// @return The attenuation factor given the distance from the frag to the light source
+//==============================================================================
+// getAttenuation                                                              =
+//==============================================================================
+/// @return The attenuation factor given the distance from the frag to the
+/// light source
 float getAttenuation(in float fragLightDist)
 float getAttenuation(in float fragLightDist)
 {
 {
 	return clamp(1.0 - sqrt(fragLightDist) / lightRadius, 0.0, 1.0);
 	return clamp(1.0 - sqrt(fragLightDist) / lightRadius, 0.0, 1.0);
@@ -82,9 +85,9 @@ float getAttenuation(in float fragLightDist)
 }
 }
 
 
 
 
-//======================================================================================================================
-// pcfLow                                                                                                              =
-//======================================================================================================================
+//==============================================================================
+// pcfLow                                                                      =
+//==============================================================================
 #if defined(SPOT_LIGHT_ENABLED) && defined(SHADOW_ENABLED)
 #if defined(SPOT_LIGHT_ENABLED) && defined(SHADOW_ENABLED)
 
 
 /// @return The blurred shadow
 /// @return The blurred shadow
@@ -118,9 +121,9 @@ float pcfLow(in vec3 shadowUv)
 #endif
 #endif
 
 
 
 
-//======================================================================================================================
-// doPhong                                                                                                             =
-//======================================================================================================================
+//==============================================================================
+// doPhong                                                                     =
+//==============================================================================
 /// Performs phong lighting using the MS FAIs and a few other things
 /// Performs phong lighting using the MS FAIs and a few other things
 /// @param fragPosVspace The fragment position in view space
 /// @param fragPosVspace The fragment position in view space
 /// @param fragLightDist Output needed for the attenuation calculation
 /// @param fragLightDist Output needed for the attenuation calculation
@@ -130,8 +133,8 @@ vec3 doPhong(in vec3 fragPosVspace, out float fragLightDist)
 	// get the vector from the frag to the light
 	// get the vector from the frag to the light
 	vec3 frag2LightVec = lightPos - fragPosVspace;
 	vec3 frag2LightVec = lightPos - fragPosVspace;
 
 
-	// Instead of using normalize(frag2LightVec) we brake the operation because we want fragLightDist for the calc of
-	// the attenuation
+	// Instead of using normalize(frag2LightVec) we brake the operation 
+	// because we want fragLightDist for the calc of the attenuation
 	fragLightDist = dot(frag2LightVec, frag2LightVec);
 	fragLightDist = dot(frag2LightVec, frag2LightVec);
 	vec3 lightDir = frag2LightVec * inversesqrt(fragLightDist);
 	vec3 lightDir = frag2LightVec * inversesqrt(fragLightDist);
 
 
@@ -153,7 +156,8 @@ vec3 doPhong(in vec3 fragPosVspace, out float fragLightDist)
 	vec3 color = diffuse * lambertTerm;
 	vec3 color = diffuse * lambertTerm;
 
 
 	// Specular
 	// Specular
-	vec4 specularMix = texture2D(msSpecularFai, vTexCoords); // the MS specular FAI has the color and the shininess
+	vec4 specularMix = texture2D(msSpecularFai, vTexCoords); // the MS specular
+	                                      // FAI has the color and the shininess
 	vec3 specular = specularMix.xyz;
 	vec3 specular = specularMix.xyz;
 	float shininess = specularMix.w * MAX_SHININESS;
 	float shininess = specularMix.w * MAX_SHININESS;
 
 
@@ -167,71 +171,81 @@ vec3 doPhong(in vec3 fragPosVspace, out float fragLightDist)
 }
 }
 
 
 
 
-//======================================================================================================================
-// main                                                                                                                =
-//======================================================================================================================
-void main()
+//==============================================================================
+// doPointLight                                                                =
+//==============================================================================
+vec3 doPointLight(in vec3 fragPosVspace)
 {
 {
-	// get frag pos in view space
-	vec3 fragPosVspace = getFragPosVSpace();
+	// The func doPhong calculates the frag to light distance 
+	// (fragLightDist) and be cause we need that distance latter for other 
+	// calculations we export it
+	float fragLightDist;
+	vec3 color = doPhong(fragPosVspace, fragLightDist);
+	return color * getAttenuation(fragLightDist);
+}
 
 
-	//
-	// Point light
-	//
-	#if defined(POINT_LIGHT_ENABLED)
-		// The func doPhong calculates the frag to light distance (fragLightDist) and be cause we need that distance
-		// latter for other calculations we export it
-		float fragLightDist;
-		vec3 color = doPhong(fragPosVspace, fragLightDist);
-		fColor = color * getAttenuation(fragLightDist);
-
-	//
-	// Spot light
-	//
-	#elif defined(SPOT_LIGHT_ENABLED)
-		vec4 texCoords2 = texProjectionMat * vec4(fragPosVspace, 1.0);
-		vec3 texCoords3 = texCoords2.xyz / texCoords2.w;
-
-		if(texCoords2.w > 0.0 &&
-		   texCoords3.x > 0.0 &&
-		   texCoords3.x < 1.0 &&
-		   texCoords3.y > 0.0 &&
-		   texCoords3.y < 1.0 &&
-		   texCoords2.w < lightRadius)
-		{
-			// Get shadow
-			#if defined(SHADOW_ENABLED)
-				#if defined(PCF_ENABLED)
-					float shadowCol = pcfLow(texCoords3);
-				#else
-					float shadowCol = shadow2D(shadowMap, texCoords3).r;
-				#endif
-
-				if(shadowCol == 0.0)
-				{
-					discard;
-				}
-			#endif
-
-			float fragLightDist;
-			vec3 color = doPhong(fragPosVspace, fragLightDist);
-
-			vec3 lightTexCol = texture2DProj(lightTex, texCoords2.xyz).rgb;
-			float att = getAttenuation(fragLightDist);
-
-			#if defined(SHADOW_ENABLED)
-				fColor = lightTexCol * color * (shadowCol * att);
-			#else
-				fColor = lightTexCol * color * att;
-			#endif
-		}
-		else
+
+//==============================================================================
+// doSpotLight                                                                 =
+//==============================================================================
+vec3 doSpotLight(in vec3 fragPosVspace)
+{
+	vec4 texCoords2 = texProjectionMat * vec4(fragPosVspace, 1.0);
+	vec3 texCoords3 = texCoords2.xyz / texCoords2.w;
+
+	if(texCoords2.w > 0.0 &&
+	   texCoords3.x > 0.0 &&
+	   texCoords3.x < 1.0 &&
+	   texCoords3.y > 0.0 &&
+	   texCoords3.y < 1.0 &&
+	   texCoords2.w < lightRadius)
+	{
+		// Get shadow
+#if defined(SHADOW_ENABLED)
+#	if defined(PCF_ENABLED)
+		float shadowCol = pcfLow(texCoords3);
+#	else
+		float shadowCol = shadow2D(shadowMap, texCoords3).r;
+#	endif
+
+		if(shadowCol == 0.0)
 		{
 		{
 			discard;
 			discard;
 		}
 		}
-	#endif // spot light
+#endif
+
+		float fragLightDist;
+		vec3 color = doPhong(fragPosVspace, fragLightDist);
 
 
+		vec3 lightTexCol = texture2DProj(lightTex, texCoords2.xyz).rgb;
+		float att = getAttenuation(fragLightDist);
+
+#if defined(SHADOW_ENABLED)
+		return lightTexCol * color * (shadowCol * att);
+#else
+		return lightTexCol * color * att;
+#endif
+	}
+	else
+	{
+		discard;
+	}
+}
+
+
+//==============================================================================
+// main                                                                        =
+//==============================================================================
+void main()
+{
+	// get frag pos in view space
+	vec3 fragPosVspace = getFragPosVSpace();
 
 
+#if defined(POINT_LIGHT_ENABLED)
+	fColor = doPointLight(fragLightDist);
+#elif defined(SPOT_LIGHT_ENABLED)
+	fColor = doSpotLight(fragLightDist);
+#endif // spot light
 
 
 	
 	
 	//fColor = fColor - fColor + vec3(1, 0, 1);
 	//fColor = fColor - fColor + vec3(1, 0, 1);

+ 77 - 82
shaders/MsMpGeneric.glsl

@@ -8,13 +8,14 @@
 /// ENVIRONMENT_MAPPING, ALPHA_TESTING
 /// ENVIRONMENT_MAPPING, ALPHA_TESTING
  
  
 #if defined(ALPHA_TESTING) && !defined(DIFFUSE_MAPPING)
 #if defined(ALPHA_TESTING) && !defined(DIFFUSE_MAPPING)
-	#error "Cannot have ALPHA_TESTING without DIFFUSE_MAPPING"
+#	error "Cannot have ALPHA_TESTING without DIFFUSE_MAPPING"
 #endif
 #endif
  
  
-#if defined(DIFFUSE_MAPPING) || defined(NORMAL_MAPPING) || defined(SPECULAR_MAPPING)
-	#define NEEDS_TEX_MAPPING 1
+#if defined(DIFFUSE_MAPPING) || defined(NORMAL_MAPPING) || \
+	defined(SPECULAR_MAPPING)
+#	define NEEDS_TEX_MAPPING 1
 #else
 #else
-	#define NEEDS_TEX_MAPPING 0
+#	define NEEDS_TEX_MAPPING 0
 #endif
 #endif
 
 
 
 
@@ -25,7 +26,7 @@
 #endif
 #endif
 
 
 
 
-#pragma anki vertShaderBegins
+#pragma anki start vertexShader
 
 
 /// @name Attributes
 /// @name Attributes
 /// @{
 /// @{
@@ -68,31 +69,26 @@ void main()
 	// calculate the vert pos, normal and tangent
 	// calculate the vert pos, normal and tangent
 	vNormal = normalMat * normal;
 	vNormal = normalMat * normal;
 
 
-	#if NEEDS_TANGENT
-		vTangent = normalMat * vec3(tangent);
-	#endif
-
 	gl_Position = modelViewProjectionMat * vec4(position, 1.0);
 	gl_Position = modelViewProjectionMat * vec4(position, 1.0);
 
 
 	// calculate the rest
 	// calculate the rest
 
 
-	#if NEEDS_TEX_MAPPING
-		vTexCoords = texCoords;
-	#endif
-
-
-	#if NEEDS_TANGENT
-		vTangentW = tangent.w;
-	#endif
+#if NEEDS_TEX_MAPPING
+	vTexCoords = texCoords;
+#endif
 
 
+#if NEEDS_TANGENT
+	vTangent = normalMat * vec3(tangent);
+	vTangentW = tangent.w;
+#endif
 
 
-	#if defined(ENVIRONMENT_MAPPING) || defined(PARALLAX_MAPPING)
-		vVertPosViewSpace = vec3(modelViewMat * vec4(position, 1.0));
-	#endif
+#if defined(ENVIRONMENT_MAPPING) || defined(PARALLAX_MAPPING)
+	vVertPosViewSpace = vec3(modelViewMat * vec4(position, 1.0));
+#endif
 }
 }
 
 
 
 
-#pragma anki fragShaderBegins
+#pragma anki start fragmentShader
 
 
 /// @note The process of calculating the diffuse color for the diffuse MSFAI is 
 /// @note The process of calculating the diffuse color for the diffuse MSFAI is 
 /// divided into two parts. The first happens before the normal calculation and 
 /// divided into two parts. The first happens before the normal calculation and 
@@ -108,26 +104,26 @@ void main()
 
 
 
 
 #if defined(DIFFUSE_MAPPING)
 #if defined(DIFFUSE_MAPPING)
-	uniform sampler2D diffuseMap;
+uniform sampler2D diffuseMap;
 #endif
 #endif
 #if defined(NORMAL_MAPPING)
 #if defined(NORMAL_MAPPING)
-	uniform sampler2D normalMap;
+uniform sampler2D normalMap;
 #endif
 #endif
 #if defined(SPECULAR_MAPPING)
 #if defined(SPECULAR_MAPPING)
-	uniform sampler2D specularMap;
+uniform sampler2D specularMap;
 #endif
 #endif
 #if defined(PARALLAX_MAPPING)
 #if defined(PARALLAX_MAPPING)
-	uniform sampler2D heightMap;
+uniform sampler2D heightMap;
 #endif
 #endif
 #if defined(ENVIRONMENT_MAPPING)
 #if defined(ENVIRONMENT_MAPPING)
-	uniform sampler2D environmentMap;
+uniform sampler2D environmentMap;
 #endif
 #endif
 uniform float shininess = 50.0;
 uniform float shininess = 50.0;
 uniform vec3 diffuseCol = vec3(1.0, 0.0, 1.0);
 uniform vec3 diffuseCol = vec3(1.0, 0.0, 1.0);
 uniform vec3 specularCol = vec3(1.0, 0.0, 1.0);
 uniform vec3 specularCol = vec3(1.0, 0.0, 1.0);
 #if defined(ALPHA_TESTING)
 #if defined(ALPHA_TESTING)
-	/// Below this value the pixels are getting discarded 
-	uniform float alphaTestingTolerance = 0.5; 
+/// Below this value the pixels are getting discarded 
+uniform float alphaTestingTolerance = 0.5; 
 #endif
 #endif
 uniform float blurring = 0.0;
 uniform float blurring = 0.0;
 
 
@@ -229,41 +225,41 @@ void main()
 	// The code below reads the height map, makes some calculations and returns 
 	// The code below reads the height map, makes some calculations and returns 
 	// a new texCoords
 	// a new texCoords
 	//
 	//
-	#if defined(PARALLAX_MAPPING)
-		/*const float _scale = 0.04;
-		const float _bias = scale * 0.4;
+#if defined(PARALLAX_MAPPING)
+	/*const float _scale = 0.04;
+	const float _bias = scale * 0.4;
 
 
-		vec3 _norm_eye = normalize(eye);
+	vec3 _norm_eye = normalize(eye);
 
 
-		float _h = texture2D(heightMap, vTexCoords).r;
-		float _height = _scale * _h - _bias;
+	float _h = texture2D(heightMap, vTexCoords).r;
+	float _height = _scale * _h - _bias;
 
 
-		vec2 _superTexCoords__v2f = _height * _norm_eye.xy + vTexCoords;*/
+	vec2 _superTexCoords__v2f = _height * _norm_eye.xy + vTexCoords;*/
 
 
-		vec2 _superTexCoords_ = vTexCoords;
-		const float maxStepCount = 100.0;
-		float nSteps = maxStepCount * length(_superTexCoords_);
+	vec2 _superTexCoords_ = vTexCoords;
+	const float maxStepCount = 100.0;
+	float nSteps = maxStepCount * length(_superTexCoords_);
 
 
-		vec3 dir = vVertPosViewSpace;
-		dir.xy /= 8.0;
-		dir /= -nSteps * dir.z;
+	vec3 dir = vVertPosViewSpace;
+	dir.xy /= 8.0;
+	dir /= -nSteps * dir.z;
 
 
-		float diff0, diff1 = 1.0 - texture2D(heightMap, _superTexCoords_).a;
-		if(diff1 > 0.0)
+	float diff0, diff1 = 1.0 - texture2D(heightMap, _superTexCoords_).a;
+	if(diff1 > 0.0)
+	{
+		do 
 		{
 		{
-			do 
-			{
-				_superTexCoords_ += dir.xy;
+			_superTexCoords_ += dir.xy;
 
 
-				diff0 = diff1;
-				diff1 = texture2D(heightMap, _superTexCoords_).w;
-			} while(diff1 > 0.0);
+			diff0 = diff1;
+			diff1 = texture2D(heightMap, _superTexCoords_).w;
+		} while(diff1 > 0.0);
 
 
-			_superTexCoords_.xy += (diff1 / (diff0 - diff1)) * dir.xy;
-		}
-	#else
-		#define _superTexCoords_ vTexCoords
-	#endif
+		_superTexCoords_.xy += (diff1 / (diff0 - diff1)) * dir.xy;
+	}
+#else
+#	define _superTexCoords_ vTexCoords
+#endif
 
 
 
 
 	//
 	//
@@ -272,19 +268,18 @@ void main()
 	// and alpha is zero
 	// and alpha is zero
 	//
 	//
 	vec3 _diffColl_;
 	vec3 _diffColl_;
-	#if defined(DIFFUSE_MAPPING)
+#if defined(DIFFUSE_MAPPING)
 
 
-		#if defined(ALPHA_TESTING)
-			_diffColl_ = doAlpha(diffuseMap, alphaTestingTolerance, 
-				_superTexCoords_);
-		#else // no alpha
-			_diffColl_ = texture2D(diffuseMap, _superTexCoords_).rgb;
-		#endif
+#	if defined(ALPHA_TESTING)
+	_diffColl_ = doAlpha(diffuseMap, alphaTestingTolerance, _superTexCoords_);
+#	else // no alpha
+	_diffColl_ = texture2D(diffuseMap, _superTexCoords_).rgb;
+#	endif
 
 
-		_diffColl_ *= diffuseCol.rgb;
-	#else // no diff mapping
-		_diffColl_ = diffuseCol.rgb;
-	#endif
+	_diffColl_ *= diffuseCol.rgb;
+#else // no diff mapping
+	_diffColl_ = diffuseCol.rgb;
+#endif
 
 
 
 
 	//
 	//
@@ -292,12 +287,12 @@ void main()
 	// Either use a normap map and make some calculations or use the vertex 
 	// Either use a normap map and make some calculations or use the vertex 
 	// normal
 	// normal
 	//
 	//
-	#if defined(NORMAL_MAPPING)
-		vec3 _normal_ = getNormalUsingMap(vNormal, vTangent, vTangentW, 
-			normalMap, _superTexCoords_);
-	#else
-		vec3 _normal_ = getNormalSimple(vNormal);
-	#endif
+#if defined(NORMAL_MAPPING)
+	vec3 _normal_ = getNormalUsingMap(vNormal, vTangent, vTangentW, 
+		normalMap, _superTexCoords_);
+#else
+	vec3 _normal_ = getNormalSimple(vNormal);
+#endif
 
 
 
 
 	//
 	//
@@ -306,22 +301,22 @@ void main()
 	// environmentMap and the _normal_) and
 	// environmentMap and the _normal_) and
 	// combine colors of SEM and the _diffColl_
 	// combine colors of SEM and the _diffColl_
 	//
 	//
-	#if defined(ENVIRONMENT_MAPPING)
-		// blend existing color with the SEM texture map
-		_diffColl_ += doEnvMapping(vVertPosViewSpace, _normal_, environmentMap); 
-	#endif
+#if defined(ENVIRONMENT_MAPPING)
+	// blend existing color with the SEM texture map
+	_diffColl_ += doEnvMapping(vVertPosViewSpace, _normal_, environmentMap); 
+#endif
 
 
 
 
 	//
 	//
 	// Specular Calculations
 	// Specular Calculations
 	//
 	//
-	#if defined(SPECULAR_MAPPING)
-		vec4 _specularCol_ = vec4(
-			texture2D(specularMap, _superTexCoords_).rgb * specularCol,
-			shininess / MAX_SHININESS);
-	#else // no specular map
-		vec4 _specularCol_ = vec4(specularCol, shininess / MAX_SHININESS);
-	#endif
+#if defined(SPECULAR_MAPPING)
+	vec4 _specularCol_ = vec4(
+		texture2D(specularMap, _superTexCoords_).rgb * specularCol,
+		shininess / MAX_SHININESS);
+#else // no specular map
+	vec4 _specularCol_ = vec4(specularCol, shininess / MAX_SHININESS);
+#endif
 
 
 
 
 	//
 	//

+ 6 - 4
src/Main.cpp

@@ -43,7 +43,8 @@
 #include "Events/Manager.h"
 #include "Events/Manager.h"
 #include "Events/SceneColor.h"
 #include "Events/SceneColor.h"
 #include "Events/MainRendererPpsHdr.h"
 #include "Events/MainRendererPpsHdr.h"
-#include "Resources/SProgLoader.h"
+#include "Resources/ShaderProgramPrePreprocessor.h"
+#include "Resources/Material2.h"
 
 
 
 
 // map (hard coded)
 // map (hard coded)
@@ -462,9 +463,10 @@ int main(int argc, char* argv[])
 {
 {
 	try
 	try
 	{
 	{
-		SProgLoader l("lala.sprog");
-		std::cout << "$$$" << l.getVertexShaderSource() << "$$$" << std::endl;
-		std::cerr << "$$$" << l.getFragmentShaderSource() << "$$$" << std::endl;
+		boost::ptr_vector<Material2::FuncDefinition> defs;
+		Material2::parseShaderFileForFunctionDefinitions(
+			"lala.glsl", defs);
+
 
 
 		return 0;
 		return 0;
 
 

+ 1 - 1
src/Misc/Parser.h

@@ -60,7 +60,7 @@ extern std::string parseIdentifier(Scanner::Scanner& scanner,
 	const char* expectedIdentifier = NULL);
 	const char* expectedIdentifier = NULL);
 
 
 /// Is identifier
 /// Is identifier
-extern bool isIdentifier(const Scanner::Token* token, const char* str);
+extern bool isIdentifier(const Scanner::Token& token, const char* str);
 
 
 /// Parse string
 /// Parse string
 extern std::string parseString(Scanner::Scanner& scanner);
 extern std::string parseString(Scanner::Scanner& scanner);

+ 3 - 3
src/Misc/Parser.inl.h

@@ -235,10 +235,10 @@ inline std::string parseIdentifier(Scanner::Scanner& scanner,
 //==============================================================================
 //==============================================================================
 // isIdentifier                                                                =
 // isIdentifier                                                                =
 //==============================================================================
 //==============================================================================
-inline bool isIdentifier(const Scanner::Token* token, const char* str)
+inline bool isIdentifier(const Scanner::Token& token, const char* str)
 {
 {
-	return token->getCode() == Scanner::TC_IDENTIFIER &&
-		!strcmp(token->getValue().getString(), str);
+	return token.getCode() == Scanner::TC_IDENTIFIER &&
+		!strcmp(token.getValue().getString(), str);
 }
 }
 
 
 
 

+ 236 - 16
src/Resources/Material2.cpp

@@ -1,6 +1,12 @@
 #include "Material2.h"
 #include "Material2.h"
+#include "MaterialInputVariable.h"
 #include "Util/Scanner/Scanner.h"
 #include "Util/Scanner/Scanner.h"
 #include "Misc/Parser.h"
 #include "Misc/Parser.h"
+#include "Misc/PropertyTree.h"
+#include <sstream>
+#include <boost/foreach.hpp>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/xml_parser.hpp>
 
 
 
 
 //==============================================================================
 //==============================================================================
@@ -40,30 +46,55 @@ boost::array<Material2::StdVarNameAndGlDataTypePair, Material2::SUV_NUM>
 }};
 }};
 
 
 
 
+Material2::BlendParam Material2::blendingParams[] =
+{
+	{GL_ZERO, "GL_ZERO"},
+	{GL_ONE, "GL_ONE"},
+	{GL_DST_COLOR, "GL_DST_COLOR"},
+	{GL_ONE_MINUS_DST_COLOR, "GL_ONE_MINUS_DST_COLOR"},
+	{GL_SRC_ALPHA, "GL_SRC_ALPHA"},
+	{GL_ONE_MINUS_SRC_ALPHA, "GL_ONE_MINUS_SRC_ALPHA"},
+	{GL_DST_ALPHA, "GL_DST_ALPHA"},
+	{GL_ONE_MINUS_DST_ALPHA, "GL_ONE_MINUS_DST_ALPHA"},
+	{GL_SRC_ALPHA_SATURATE, "GL_SRC_ALPHA_SATURATE"},
+	{GL_SRC_COLOR, "GL_SRC_COLOR"},
+	{GL_ONE_MINUS_SRC_COLOR, "GL_ONE_MINUS_SRC_COLOR"},
+	{0, NULL}
+};
+
+
 //==============================================================================
 //==============================================================================
 // parseShaderFileForFunctionDefinitions                                       =
 // parseShaderFileForFunctionDefinitions                                       =
 //==============================================================================
 //==============================================================================
 void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
 void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
 	boost::ptr_vector<FuncDefinition>& out)
 	boost::ptr_vector<FuncDefinition>& out)
 {
 {
-	Scanner::Scanner scanner(filename);
-	const Scanner::Token* token;
+	Scanner::Scanner scanner(filename, false);
+	const Scanner::Token* token = &scanner.getCrntToken();
 
 
+	// Forever
 	while(true)
 	while(true)
 	{
 	{
+		getNextTokenAndSkipNewline(scanner);
+		FuncDefinition* funcDef = NULL;
+
 		// EOF
 		// EOF
 		if(token->getCode() == Scanner::TC_EOF)
 		if(token->getCode() == Scanner::TC_EOF)
 		{
 		{
 			break;
 			break;
 		}
 		}
-
-		FuncDefinition* funcDef = new FuncDefinition;
-		out.push_back(funcDef);
-
+		// #
+		else if(token->getCode() == Scanner::TC_SHARP)
+		{
+			parseUntilNewline(scanner);
+			continue;
+		}
 		// Type
 		// Type
-		token = &scanner.getNextToken();
-		if(token->getCode() == Scanner::TC_IDENTIFIER)
+		else if(token->getCode() == Scanner::TC_IDENTIFIER)
 		{
 		{
+			funcDef = new FuncDefinition;
+			out.push_back(funcDef);
+
 			if(!strcmp(token->getValue().getString(), "float"))
 			if(!strcmp(token->getValue().getString(), "float"))
 			{
 			{
 				funcDef->returnArg = AT_FLOAT;
 				funcDef->returnArg = AT_FLOAT;
@@ -96,7 +127,7 @@ void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
 		}
 		}
 
 
 		// Function name
 		// Function name
-		scanner.getNextToken();
+		getNextTokenAndSkipNewline(scanner);
 		if(token->getCode() != Scanner::TC_IDENTIFIER)
 		if(token->getCode() != Scanner::TC_IDENTIFIER)
 		{
 		{
 			throw PARSER_EXCEPTION_EXPECTED("identifier");
 			throw PARSER_EXCEPTION_EXPECTED("identifier");
@@ -105,7 +136,7 @@ void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
 		funcDef->name = token->getValue().getString();
 		funcDef->name = token->getValue().getString();
 
 
 		// (
 		// (
-		scanner.getNextToken();
+		getNextTokenAndSkipNewline(scanner);
 		if(token->getCode() != Scanner::TC_LPAREN)
 		if(token->getCode() != Scanner::TC_LPAREN)
 		{
 		{
 			throw PARSER_EXCEPTION_EXPECTED("(");
 			throw PARSER_EXCEPTION_EXPECTED("(");
@@ -118,7 +149,7 @@ void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
 			funcDef->argDefinitions.push_back(argDef);
 			funcDef->argDefinitions.push_back(argDef);
 
 
 			// Call type
 			// Call type
-			scanner.getNextToken();
+			getNextTokenAndSkipNewline(scanner);
 			if(token->getCode() != Scanner::TC_IDENTIFIER)
 			if(token->getCode() != Scanner::TC_IDENTIFIER)
 			{
 			{
 				throw PARSER_EXCEPTION_EXPECTED("identifier");
 				throw PARSER_EXCEPTION_EXPECTED("identifier");
@@ -142,7 +173,7 @@ void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
 			}
 			}
 
 
 			// Type
 			// Type
-			scanner.getNextToken();
+			getNextTokenAndSkipNewline(scanner);
 			if(token->getCode() != Scanner::TC_IDENTIFIER)
 			if(token->getCode() != Scanner::TC_IDENTIFIER)
 			{
 			{
 				throw PARSER_EXCEPTION_EXPECTED("identifier");
 				throw PARSER_EXCEPTION_EXPECTED("identifier");
@@ -175,7 +206,7 @@ void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
 			}
 			}
 
 
 			// Name
 			// Name
-			scanner.getNextToken();
+			getNextTokenAndSkipNewline(scanner);
 			if(token->getCode() != Scanner::TC_IDENTIFIER)
 			if(token->getCode() != Scanner::TC_IDENTIFIER)
 			{
 			{
 				throw PARSER_EXCEPTION_EXPECTED("identifier");
 				throw PARSER_EXCEPTION_EXPECTED("identifier");
@@ -184,7 +215,7 @@ void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
 			argDef->name = token->getValue().getString();
 			argDef->name = token->getValue().getString();
 
 
 			// ,
 			// ,
-			scanner.getNextToken();
+			getNextTokenAndSkipNewline(scanner);
 			if(token->getCode() == Scanner::TC_COMMA)
 			if(token->getCode() == Scanner::TC_COMMA)
 			{
 			{
 				continue;
 				continue;
@@ -202,7 +233,7 @@ void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
 
 
 
 
 		// {
 		// {
-		scanner.getNextToken();
+		getNextTokenAndSkipNewline(scanner);
 		if(token->getCode() != Scanner::TC_LBRACKET)
 		if(token->getCode() != Scanner::TC_LBRACKET)
 		{
 		{
 			throw PARSER_EXCEPTION_EXPECTED("{");
 			throw PARSER_EXCEPTION_EXPECTED("{");
@@ -212,7 +243,7 @@ void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
 		int bracketsNum = 0;
 		int bracketsNum = 0;
 		while(true)
 		while(true)
 		{
 		{
-			scanner.getNextToken();
+			getNextTokenAndSkipNewline(scanner);
 
 
 			if(token->getCode() == Scanner::TC_RBRACKET)
 			if(token->getCode() == Scanner::TC_RBRACKET)
 			{
 			{
@@ -226,10 +257,199 @@ void Material2::parseShaderFileForFunctionDefinitions(const char* filename,
 			{
 			{
 				++bracketsNum;
 				++bracketsNum;
 			}
 			}
+			else if(token->getCode() == Scanner::TC_EOF)
+			{
+				throw PARSER_EXCEPTION_UNEXPECTED();
+			}
 			else
 			else
 			{
 			{
 				continue;
 				continue;
 			}
 			}
 		} // End until closing bracket
 		} // End until closing bracket
+
+		/*std::stringstream ss;
+		ss << "Func def: " << funcDef->returnArg << " " << funcDef->name << " ";
+		BOOST_FOREACH(const ArgDefinition& adef, funcDef->argDefinitions)
+		{
+			ss << adef.callType << " " << adef.dataType << " " <<
+				adef.name << ", ";
+		}
+		std::cout << ss.str() << std::endl;*/
 	} // End for all functions
 	} // End for all functions
 }
 }
+
+
+//==============================================================================
+// parseUntilNewline                                                           =
+//==============================================================================
+void Material2::parseUntilNewline(Scanner::Scanner& scanner)
+{
+	const Scanner::Token* token = &scanner.getCrntToken();
+	Scanner::TokenCode prevTc;
+
+	while(true)
+	{
+		prevTc = token->getCode();
+		scanner.getNextToken();
+
+		if(token->getCode() == Scanner::TC_EOF)
+		{
+			break;
+		}
+		else if(token->getCode() == Scanner::TC_NEWLINE &&
+			prevTc != Scanner::TC_BACK_SLASH)
+		{
+			break;
+		}
+	}
+}
+
+
+//==============================================================================
+// getNextTokenAndSkipNewline                                                  =
+//==============================================================================
+void Material2::getNextTokenAndSkipNewline(Scanner::Scanner& scanner)
+{
+	const Scanner::Token* token;
+
+	while(true)
+	{
+		token = &scanner.getNextToken();
+		if(token->getCode() != Scanner::TC_NEWLINE)
+		{
+			break;
+		}
+	}
+}
+
+
+//==============================================================================
+// getGlBlendEnumFromText                                                      =
+//==============================================================================
+int Material2::getGlBlendEnumFromText(const char* str)
+{
+	BlendParam* ptr = &blendingParams[0];
+	while(true)
+	{
+		if(ptr->str == NULL)
+		{
+			throw EXCEPTION("Incorrect blending factor: " + str);
+		}
+
+		if(!strcmp(ptr->str, str))
+		{
+			return ptr->glEnum;
+		}
+
+		++ptr;
+	}
+}
+
+
+//==============================================================================
+// parseMaterialTag                                                            =
+//==============================================================================
+void Material2::parseMaterialTag(const boost::property_tree::ptree& pt)
+{
+	using namespace boost::property_tree;
+
+	//
+	// castsShadow
+	//
+	boost::optional<bool> shadow =
+		PropertyTree::getBoolOptional(pt, "castsShadow");
+	if(shadow)
+	{
+		castsShadowFlag = shadow.get();
+	}
+
+	//
+	// renderInBlendingStage
+	//
+	boost::optional<bool> bs =
+		PropertyTree::getBoolOptional(pt, "renderInBlendingStage");
+	if(bs)
+	{
+		renderInBlendingStageFlag = bs.get();
+	}
+
+	//
+	// blendFunctions
+	//
+	boost::optional<const ptree&> blendFuncsTree =
+		pt.get_child_optional("blendFunctions");
+	if(blendFuncsTree)
+	{
+		// sFactor
+		blendingSfactor = getGlBlendEnumFromText(
+			blendFuncsTree.get().get<std::string>("sFactor").c_str());
+
+		// dFactor
+		blendingDfactor = getGlBlendEnumFromText(
+			blendFuncsTree.get().get<std::string>("dFactor").c_str());
+	}
+
+	//
+	// depthTesting
+	//
+	boost::optional<bool> dp =
+		PropertyTree::getBoolOptional(pt, "depthTesting");
+	if(dp)
+	{
+		depthTesting = dp.get();
+	}
+
+	//
+	// wireframe
+	//
+	boost::optional<bool> wf =
+		PropertyTree::getBoolOptional(pt, "wireframe");
+	if(wf)
+	{
+		wireframe = wf.get();
+	}
+
+	//
+	// shaderProgram
+	//
+	parseShaderProgramTag(pt.get_child("shaderProgram"));
+}
+
+
+//==============================================================================
+// parseShaderProgramTag                                                       =
+//==============================================================================
+void Material2::parseShaderProgramTag(const boost::property_tree::ptree& pt)
+{
+	using namespace boost::property_tree;
+
+	std::stringstream sprogSrc;
+
+	//
+	// inputs
+	//
+	boost::ptr_vector<FuncDefinition> funcDefs;
+
+	const ptree& includesPt = pt.get_child("includes");
+	BOOST_FOREACH(const ptree::value_type& v, includesPt)
+	{
+		if(v.first != "include")
+		{
+			throw EXCEPTION("Expected include and not: " + v.first);
+		}
+
+		const std::string& fname = v.second.data();
+		parseShaderFileForFunctionDefinitions(fname.c_str(), funcDefs);
+
+		sprogSrc << "#pragma anki include " << fname << std::endl;
+	}
+
+	//
+	// ins
+	//
+	boost::optional<const ptree&> insPt = pt.get_optional("ins");
+	if(ins)
+	{
+
+	}
+}

+ 65 - 27
src/Resources/Material2.h

@@ -14,12 +14,15 @@ class SProgAttribVar;
 class SProgUniVar;
 class SProgUniVar;
 class ShaderProg;
 class ShaderProg;
 class MaterialUserInputVariable;
 class MaterialUserInputVariable;
+namespace Scanner {
+class Scanner;
+}
 
 
 
 
 /// Contains a few properties that other classes may use
 /// Contains a few properties that other classes may use
 struct MaterialProperties
 struct MaterialProperties
 {
 {
-	///< Used in depth passes of shadowmapping and not in other depth passes
+	/// Used in depth passes of shadowmapping and not in other depth passes
 	/// like EarlyZ
 	/// like EarlyZ
 	bool castsShadowFlag;
 	bool castsShadowFlag;
 	/// The entities with blending are being rendered in blending stage and
 	/// The entities with blending are being rendered in blending stage and
@@ -34,42 +37,49 @@ struct MaterialProperties
 
 
 /// @code
 /// @code
 /// <material>
 /// <material>
+/// 	<castsShadow>true | false</castsShadow>
+///
 /// 	<renderInBlendingStage>true | false</renderInBlendingStage>
 /// 	<renderInBlendingStage>true | false</renderInBlendingStage>
 ///
 ///
-/// 	<blendFuncs>
+/// 	<blendFunctions>
 /// 		<sFactor>GL_SOMETHING</sFactor>
 /// 		<sFactor>GL_SOMETHING</sFactor>
 /// 		<dFactor>GL_SOMETHING</dFactor>
 /// 		<dFactor>GL_SOMETHING</dFactor>
-/// 	</blendFuncs>
+/// 	</blendFunctions>
 ///
 ///
 /// 	<depthTesting>true | false</depthTesting>
 /// 	<depthTesting>true | false</depthTesting>
 ///
 ///
 /// 	<wireframe>true | false</wireframe>
 /// 	<wireframe>true | false</wireframe>
 ///
 ///
-/// 	<castsShadow>true | false</castsShadow>
-///
 /// 	<shaderProgram>
 /// 	<shaderProgram>
-/// 		<include>file.glsl</include>
+/// 		<includes>
+/// 			<include>file.glsl</include>
+/// 			<include>file2.glsl</include>
+/// 		</includes>
 ///
 ///
-/// 		<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>
+/// 		<ins>
+/// 			<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>
+/// 		</ins>
 ///
 ///
-/// 		<operation>
-/// 			<id>x</id>
-/// 			<function>functionName</function>
-/// 			<parameters>
-/// 				<parameter>xx</parameter>
-/// 				<parameter>yy</parameter>
-/// 			</parameters>
-/// 		</operation>
+/// 		<operations>
+/// 			<operation>
+/// 				<id>x</id>
+/// 				<function>functionName</function>
+/// 				<parameters>
+/// 					<parameter>xx</parameter>
+/// 					<parameter>yy</parameter>
+/// 				</parameters>
+/// 			</operation>
+/// 		</operations>
 ///
 ///
 /// 	</shaderProgram>
 /// 	</shaderProgram>
 /// </material>
 /// </material>
@@ -156,7 +166,7 @@ class Material2: private MaterialProperties
 		/// Load a material file
 		/// Load a material file
 		void load(const char* filename);
 		void load(const char* filename);
 
 
-	private:
+	public: /// XXX
 		//======================================================================
 		//======================================================================
 		// Nested                                                              =
 		// Nested                                                              =
 		//======================================================================
 		//======================================================================
@@ -204,6 +214,13 @@ class Material2: private MaterialProperties
 			GLenum dataType; ///< aka GL data type
 			GLenum dataType; ///< aka GL data type
 		};
 		};
 
 
+		/// Simple pair structure
+		struct BlendParam
+		{
+			int glEnum;
+			const char* str;
+		};
+
 		//======================================================================
 		//======================================================================
 		// Members                                                             =
 		// Members                                                             =
 		//======================================================================
 		//======================================================================
@@ -224,16 +241,37 @@ class Material2: private MaterialProperties
 		/// The most important aspect of materials
 		/// The most important aspect of materials
 		RsrcPtr<ShaderProg> shaderProg;
 		RsrcPtr<ShaderProg> shaderProg;
 
 
+		/// Used to go from text to actual GL enum
+		static BlendParam blendingParams[];
+
 		//======================================================================
 		//======================================================================
 		// Methods                                                             =
 		// Methods                                                             =
 		//======================================================================
 		//======================================================================
 
 
-		/// XXX
+		/// XXX Appends
 		static void parseShaderFileForFunctionDefinitions(const char* filename,
 		static void parseShaderFileForFunctionDefinitions(const char* filename,
 			boost::ptr_vector<FuncDefinition>& out);
 			boost::ptr_vector<FuncDefinition>& out);
 
 
+		/// XXX
+		/// Used by parseShaderFileForFunctionDefinitions. Takes into account
+		/// the backslashes
+		static void parseUntilNewline(Scanner::Scanner& scanner);
+
+		/// It being used by parseShaderFileForFunctionDefinitions and it
+		/// skips until newline after a '#' found. It takes into account the
+		/// back slashes that the preprocessos may have
+		static void getNextTokenAndSkipNewline(Scanner::Scanner& scanner);
+
+		/// Searches the blendingParams array for text. It throw exception if
+		/// not found
+		static int getGlBlendEnumFromText(const char* str);
+
 		/// Parse what is within the @code <material></material> @endcode
 		/// Parse what is within the @code <material></material> @endcode
 		void parseMaterialTag(const boost::property_tree::ptree& pt);
 		void parseMaterialTag(const boost::property_tree::ptree& pt);
+
+		/// Parse what is within the
+		/// @code <shaderProgram></shaderProgram> @endcode
+		void parseShaderProgramTag(const boost::property_tree::ptree& pt);
 };
 };
 
 
 
 

+ 6 - 0
src/Resources/MaterialInputVariable.cpp

@@ -13,6 +13,7 @@ MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar, float val)
 {
 {
 	ASSERT(svar.getGlDataType() == GL_FLOAT);
 	ASSERT(svar.getGlDataType() == GL_FLOAT);
 	scalar = val;
 	scalar = val;
+	type = T_FLOAT;
 }
 }
 
 
 
 
@@ -22,6 +23,7 @@ MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
 {
 {
 	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC2);
 	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC2);
 	vec2 = val;
 	vec2 = val;
+	type = T_VEC2;
 }
 }
 
 
 
 
@@ -31,6 +33,7 @@ MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
 {
 {
 	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC3);
 	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC3);
 	vec3 = val;
 	vec3 = val;
+	type = T_VEC3;
 }
 }
 
 
 
 
@@ -40,6 +43,7 @@ MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
 {
 {
 	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC4);
 	ASSERT(svar.getGlDataType() == GL_FLOAT_VEC4);
 	vec4 = val;
 	vec4 = val;
+	type = T_VEC4;
 }
 }
 
 
 
 
@@ -48,6 +52,7 @@ MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar, Fai val)
 {
 {
 	ASSERT(svar.getGlDataType() == GL_SAMPLER_2D);
 	ASSERT(svar.getGlDataType() == GL_SAMPLER_2D);
 	fai = val;
 	fai = val;
+	type = T_FAI;
 }
 }
 
 
 
 
@@ -57,6 +62,7 @@ MaterialInputVariable::MaterialInputVariable(const SProgUniVar& svar,
 {
 {
 	ASSERT(svar.getGlDataType() == GL_SAMPLER_2D);
 	ASSERT(svar.getGlDataType() == GL_SAMPLER_2D);
 	texture.loadRsrc(texFilename);
 	texture.loadRsrc(texFilename);
+	type = T_TEXTURE;
 }
 }
 
 
 
 

+ 14 - 0
src/Resources/MaterialInputVariable.h

@@ -14,6 +14,18 @@ class SProgUniVar;
 class MaterialInputVariable
 class MaterialInputVariable
 {
 {
 	public:
 	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
 		/// The renderer's FAIs
 		enum Fai
 		enum Fai
 		{
 		{
@@ -46,10 +58,12 @@ class MaterialInputVariable
 		const Texture& getTexture() const;
 		const Texture& getTexture() const;
 
 
 		GETTER_R(SProgUniVar, sProgVar, getShaderProgramUniformVariable)
 		GETTER_R(SProgUniVar, sProgVar, getShaderProgramUniformVariable)
+		GETTER_R_BY_VAL(Type, type, getType)
 		/// @}
 		/// @}
 
 
 	private:
 	private:
 		const SProgUniVar& sProgVar; ///< The shader program's uniform
 		const SProgUniVar& sProgVar; ///< The shader program's uniform
+		Type type;
 
 
 		/// @name Data
 		/// @name Data
 		/// @{
 		/// @{

+ 0 - 546
src/Resources/ShaderPrePreprocessor.cpp

@@ -1,546 +0,0 @@
-#include <iomanip>
-#include <cstring>
-#include <iostream>
-#include <boost/lexical_cast.hpp>
-#include <boost/foreach.hpp>
-#include "ShaderPrePreprocessor.h"
-#include "Misc/Parser.h"
-#include "Util/Util.h"
-#include "Util/Exception.h"
-
-
-static const char* MULTIPLE_DEF_MSG = " already defined in the same place. "
-	"Check for circular or multiple includance";
-
-
-//==============================================================================
-// printSourceLines                                                            =
-//==============================================================================
-void ShaderPrePreprocessor::printSourceLines() const
-{
-	for(uint i = 0; i < sourceLines.size(); ++i)
-	{
-		std::cout << std::setw(3) << (i + 1) << ": " <<
-			sourceLines[i] << std::endl;
-	}
-}
-
-
-//==============================================================================
-// printShaderVars                                                             =
-//==============================================================================
-void ShaderPrePreprocessor::printShaderVars() const
-{
-	std::cout << "TYPE" << std::setw(20) << "NAME" << std::setw(4) <<
-		"LOC" << std::endl;
-	for(uint i = 0; i < output.attributes.size(); ++i)
-	{
-		std::cout << std::setw(4) << "A" << std::setw(20) <<
-			output.attributes[i].name << std::setw(4) <<
-			output.attributes[i].customLoc << std::endl;
-	}
-}
-
-
-//==============================================================================
-// findShaderVar                                                               =
-//==============================================================================
-Vec<ShaderPrePreprocessor::ShaderVarPragma>::iterator
-	ShaderPrePreprocessor::findShaderVar(Vec<ShaderVarPragma>& vec,
-	const std::string& name) const
-{
-	Vec<ShaderVarPragma>::iterator it = vec.begin();
-	while(it != vec.end() && it->name != name)
-	{
-		++it;
-	}
-	return it;
-}
-
-
-//==============================================================================
-// parseFileForPragmas                                                         =
-//==============================================================================
-void ShaderPrePreprocessor::parseFileForPragmas(const std::string& filename,
-	int depth)
-{
-	// first check the depth
-	if(depth > 99)
-	{
-		throw EXCEPTION("File \"" + filename +
-			"\": The include depth is too high. Probably circular includance");
-	}
-
-	// load file in lines
-	Vec<std::string> lines = Util::getFileLines(filename.c_str());
-	if(lines.size() < 1)
-	{
-		throw EXCEPTION("File \"" + filename + "\": Cannot open or empty");
-	}
-
-	Scanner::Scanner scanner(filename.c_str(), false);
-	const Scanner::Token* token;
-
-	while(true)
-	{
-		token = &scanner.getNextToken();
-
-		if(token->getCode() == Scanner::TC_SHARP)
-		{
-			token = &scanner.getNextToken();
-			if(token->getCode() == Scanner::TC_IDENTIFIER &&
-				strcmp(token->getValue().getString(), "pragma") == 0)
-			{
-				token = &scanner.getNextToken();
-				if(token->getCode() == Scanner::TC_IDENTIFIER &&
-					strcmp(token->getValue().getString(), "anki") == 0)
-				{
-					token = &scanner.getNextToken();
-					//
-					// vertShaderBegins
-					//
-					if(token->getCode() == Scanner::TC_IDENTIFIER &&
-						strcmp(token->getValue().getString(),
-						"vertShaderBegins") == 0)
-					{
-						// play
-
-						// its defined in same place so there is probable
-						// circular includance
-						if(vertShaderBegins.definedInLine ==
-							scanner.getLineNumber() &&
-							vertShaderBegins.definedInFile == filename)
-						{
-							throw PARSER_EXCEPTION("vertShaderBegins" +
-								MULTIPLE_DEF_MSG);
-						}
-
-						// already defined elsewhere => error
-						if(vertShaderBegins.definedInLine != -1)
-						{
-							throw PARSER_EXCEPTION(
-								"vertShaderBegins already defined at " +
-								vertShaderBegins.definedInFile + ":" +
-								boost::lexical_cast<std::string>(
-								vertShaderBegins.definedInLine));
-						}
-
-						// vert shader should be before frag
-						if(fragShaderBegins.definedInLine != -1)
-						{
-							throw PARSER_EXCEPTION(
-								"vertShaderBegins must precede "
-								"fragShaderBegins defined at " +
-								fragShaderBegins.definedInFile + ":" +
-								boost::lexical_cast<std::string>(
-								fragShaderBegins.definedInLine));
-						}
-
-						// vert shader should be before geom
-						if(geomShaderBegins.definedInLine != -1)
-						{
-							throw PARSER_EXCEPTION(
-								"vertShaderBegins must precede "
-								"geomShaderBegins defined at " +
-								geomShaderBegins.definedInFile + ":" +
-								boost::lexical_cast<std::string>(
-								geomShaderBegins.definedInLine));
-						}
-
-						vertShaderBegins.definedInFile = filename;
-						vertShaderBegins.definedInLine =
-							scanner.getLineNumber();
-						vertShaderBegins.globalLine = sourceLines.size() + 1;
-						sourceLines.push_back("#line " +
-							boost::lexical_cast<std::string>(
-							scanner.getLineNumber()) +
-							' ' + boost::lexical_cast<std::string>(depth) +
-							" // " + lines[scanner.getLineNumber()-1]);
-						// stop play
-					}
-					//
-					// geomShaderBegins
-					//
-					else if(token->getCode() == Scanner::TC_IDENTIFIER &&
-						strcmp(token->getValue().getString(),
-						"geomShaderBegins") == 0)
-					{
-						// play
-
-						// its defined in same place so there is probable
-						// circular includance
-						if(geomShaderBegins.definedInLine ==
-							scanner.getLineNumber() &&
-							geomShaderBegins.definedInFile == filename)
-						{
-							throw PARSER_EXCEPTION("geomShaderBegins" +
-								MULTIPLE_DEF_MSG);
-						}
-
-						// already defined elsewhere => error
-						if(geomShaderBegins.definedInLine != -1)
-						{
-							throw PARSER_EXCEPTION(
-								"geomShaderBegins already defined at " +
-								geomShaderBegins.definedInFile + ":" +
-								boost::lexical_cast<std::string>(
-								geomShaderBegins.definedInLine));
-						}
-
-						// vert shader entry point not defined => error
-						if(vertShaderBegins.definedInLine == -1)
-						{
-							throw PARSER_EXCEPTION(
-								"geomShaderBegins must follow "
-								"vertShaderBegins");
-						}
-
-						// frag shader entry point defined => error
-						if(fragShaderBegins.definedInLine != -1)
-						{
-							throw PARSER_EXCEPTION(
-								"geomShaderBegins must precede"
-								" fragShaderBegins defined at " +
-								fragShaderBegins.definedInFile + ":" +
-								boost::lexical_cast<std::string>(
-								fragShaderBegins.definedInLine));
-						}
-
-						geomShaderBegins.definedInFile = filename;
-						geomShaderBegins.definedInLine =
-							scanner.getLineNumber();
-						geomShaderBegins.globalLine = sourceLines.size() + 1;
-						sourceLines.push_back("#line " +
-							boost::lexical_cast<std::string>(
-							scanner.getLineNumber()) + ' ' +
-							boost::lexical_cast<std::string>(depth) + " // " +
-							lines[scanner.getLineNumber()-1]);
-						// stop play
-					}
-					//
-					// fragShaderBegins
-					//
-					else if(token->getCode() == Scanner::TC_IDENTIFIER &&
-						strcmp(token->getValue().getString(),
-						"fragShaderBegins") == 0)
-					{
-						// play
-
-						// its defined in same place so there is probable
-						// circular includance
-						if(fragShaderBegins.definedInLine ==
-							scanner.getLineNumber() &&
-							fragShaderBegins.definedInFile == filename)
-						{
-							throw PARSER_EXCEPTION("fragShaderBegins" +
-								MULTIPLE_DEF_MSG);
-						}
-
-						// if already defined elsewhere throw error
-						if(fragShaderBegins.definedInLine != -1)
-						{
-							throw PARSER_EXCEPTION(
-								"fragShaderBegins already defined at " +
-								fragShaderBegins.definedInFile + ":" +
-								boost::lexical_cast<std::string>(
-								fragShaderBegins.definedInLine));
-						}
-
-						// vert shader entry point not defined
-						if(vertShaderBegins.definedInLine == -1)
-						{
-							throw PARSER_EXCEPTION(
-							"fragShaderBegins must follow vertShaderBegins");
-						}
-
-						fragShaderBegins.definedInFile = filename;
-						fragShaderBegins.definedInLine =
-							scanner.getLineNumber();
-						fragShaderBegins.globalLine = sourceLines.size() + 1;
-						sourceLines.push_back("#line " +
-							boost::lexical_cast<std::string>(
-							scanner.getLineNumber()) + ' ' +
-							boost::lexical_cast<std::string>(depth) + " // " +
-							lines[scanner.getLineNumber()-1]);
-						// stop play
-					}
-					//
-					// include
-					//
-					else if(token->getCode() == Scanner::TC_IDENTIFIER &&
-						strcmp(token->getValue().getString(), "include") == 0)
-					{
-						token = &scanner.getNextToken();
-						if(token->getCode() == Scanner::TC_STRING)
-						{
-							// play
-							//int line = sourceLines.size();
-							sourceLines.push_back("#line 0 " +
-								boost::lexical_cast<std::string>(depth + 1) +
-								" // " + lines[scanner.getLineNumber() - 1]);
-							parseFileForPragmas(token->getValue().getString(),
-								depth + 1);
-							sourceLines.push_back("#line " +
-								boost::lexical_cast<std::string>(
-								scanner.getLineNumber()) + ' ' +
-								boost::lexical_cast<std::string>(depth) +
-								" // end of " +
-								lines[scanner.getLineNumber() - 1]);
-							// stop play
-						}
-						else
-						{
-							throw PARSER_EXCEPTION_EXPECTED("string");
-						}
-					}
-					//
-					// transformFeedbackVarying
-					//
-					else if(token->getCode() == Scanner::TC_IDENTIFIER &&
-						strcmp(token->getValue().getString(),
-						"transformFeedbackVarying") == 0)
-					{
-						token = &scanner.getNextToken();
-						if(token->getCode() == Scanner::TC_IDENTIFIER)
-						{
-							std::string varName = token->getValue().getString();
-							// check if already defined and for circular
-							// includance
-							Vec<TrffbVaryingPragma>::const_iterator var =
-								findNamed(output.trffbVaryings, varName);
-							if(var != output.trffbVaryings.end())
-							{
-								if(var->definedInLine ==
-									scanner.getLineNumber() &&
-									var->definedInFile==filename)
-								{
-									throw PARSER_EXCEPTION("\"" + varName +
-										"\"" + MULTIPLE_DEF_MSG);
-								}
-								else
-								{
-									throw PARSER_EXCEPTION("Varying \"" +
-										varName + "\" already defined at " +
-										var->definedInFile + ":" +
-										boost::lexical_cast<std::string>(
-										var->definedInLine));
-								}
-							}
-
-							// all ok, push it back
-							output.trffbVaryings.push_back(
-								TrffbVaryingPragma(filename,
-								scanner.getLineNumber(), varName));
-							sourceLines.push_back(
-								lines[scanner.getLineNumber() - 1]);
-						}
-						else
-						{
-							throw PARSER_EXCEPTION_EXPECTED("identifier");
-						}
-					}
-					//
-					// attribute
-					//
-					else if(token->getCode() == Scanner::TC_IDENTIFIER &&
-						strcmp(token->getValue().getString(), "attribute") == 0)
-					{
-						throw EXCEPTION("Deprecated feature");
-
-						token = &scanner.getNextToken();
-						if(token->getCode() == Scanner::TC_IDENTIFIER)
-						{
-							std::string varName = token->getValue().getString();
-							token = &scanner.getNextToken();
-							if(token->getCode() == Scanner::TC_NUMBER &&
-								token->getDataType() == Scanner::DT_INT)
-							{
-								uint loc = token->getValue().getInt();
-
-								// check if already defined and for circular
-								// includance
-								Vec<ShaderVarPragma>::const_iterator attrib =
-									findNamed(output.attributes, varName);
-								if(attrib != output.attributes.end())
-								{
-									if(attrib->definedInLine ==
-										scanner.getLineNumber() &&
-										attrib->definedInFile == filename)
-									{
-										throw PARSER_EXCEPTION("\"" + varName +
-											"\"" + MULTIPLE_DEF_MSG);
-									}
-									else
-									{
-										throw PARSER_EXCEPTION(
-											"Attribute \"" + varName +
-											"\" already defined at " +
-											attrib->definedInFile + ":" +
-											boost::lexical_cast<std::string>(
-											attrib->definedInLine));
-									}
-								}
-								// search if another var has the same loc
-								for(attrib = output.attributes.begin();
-									attrib != output.attributes.end(); ++attrib)
-								{
-									if(attrib->customLoc == loc)
-									{
-										throw PARSER_EXCEPTION(
-											"The attributes \"" +
-											attrib->name + "\" (" +
-											attrib->definedInFile + ":" +
-											boost::lexical_cast<std::string>(
-											attrib->definedInLine) +
-											") and \"" + varName +
-											"\" share the same location");
-									}
-								}
-
-								// all ok, push it back
-								output.attributes.push_back(ShaderVarPragma(
-									filename, scanner.getLineNumber(), varName,
-									loc));
-								sourceLines.push_back(
-									lines[scanner.getLineNumber() - 1]);
-							}
-							else
-							{
-								throw PARSER_EXCEPTION_EXPECTED("integer");
-							}
-						}
-						else
-						{
-							throw PARSER_EXCEPTION_EXPECTED("identifier");
-						}
-					}
-					else
-					{
-						throw PARSER_EXCEPTION(
-							"#pragma anki followed by incorrect " +
-							token->getInfoStr());
-					}
-				} // end if anki
-
-				token = &scanner.getNextToken();
-				if(token->getCode()!=Scanner::TC_NEWLINE &&
-					token->getCode()!=Scanner::TC_EOF)
-				{
-					throw PARSER_EXCEPTION_EXPECTED("newline or end of file");
-				}
-
-				if(token->getCode() == Scanner::TC_EOF)
-				{
-					break;
-				}
-
-			} // end if pragma
-		} // end if #
-		//
-		// newline
-		//
-		else if(token->getCode() == Scanner::TC_NEWLINE)
-		{
-			sourceLines.push_back(lines[scanner.getLineNumber() - 2]);
-			//PRINT(lines[scanner.getLineNmbr() - 2])
-		}
-		//
-		// EOF
-		//
-		else if(token->getCode() == Scanner::TC_EOF)
-		{
-			sourceLines.push_back(lines[scanner.getLineNumber() - 1]);
-			//PRINT(lines[scanner.getLineNmbr() - 1])
-			break;
-		}
-		//
-		// error
-		//
-		else if(token->getCode() == Scanner::TC_ERROR)
-		{
-			// It will never get here
-		}
-	} // end while
-}
-
-
-//==============================================================================
-// parseFile                                                                   =
-//==============================================================================
-void ShaderPrePreprocessor::parseFile(const char* filename)
-{
-	try
-	{
-		// parse master file
-		parseFileForPragmas(filename);
-
-
-		// rearrange the trffbVaryings
-	
-		// sanity checks
-		if(vertShaderBegins.globalLine == -1)
-		{
-			throw EXCEPTION("Entry point \"vertShaderBegins\" is not defined");
-		}
-		if(fragShaderBegins.globalLine == -1)
-		{
-			throw EXCEPTION("Entry point \"fragShaderBegins\" is not defined");
-		}
-
-		// construct shader's source code
-		{
-			// init
-			output.vertShaderSource = "";
-			output.geomShaderSource = "";
-			output.fragShaderSource = "";
-
-			// put global source code
-			for(int i=0; i<vertShaderBegins.globalLine-1; ++i)
-			{
-				output.vertShaderSource += sourceLines[i] + "\n";
-
-				if(geomShaderBegins.definedInLine != -1)
-				{
-					output.geomShaderSource += sourceLines[i] + "\n";
-				}
-
-				output.fragShaderSource += sourceLines[i] + "\n";
-			}
-
-			// vert shader code
-			int limit = (geomShaderBegins.definedInLine != -1) ?
-				geomShaderBegins.globalLine-1 : fragShaderBegins.globalLine-1;
-			for(int i = vertShaderBegins.globalLine - 1; i < limit; ++i)
-			{
-				output.vertShaderSource += sourceLines[i] + "\n";
-			}
-
-			// geom shader code
-			if(geomShaderBegins.definedInLine != -1)
-			{
-				for(int i = geomShaderBegins.globalLine - 1;
-					i < fragShaderBegins.globalLine - 1; ++i)
-				{
-					output.geomShaderSource += sourceLines[i] + "\n";
-				}
-			}
-
-			// frag shader code
-			for(int i = fragShaderBegins.globalLine - 1;
-				i < int(sourceLines.size()); ++i)
-			{
-				output.fragShaderSource += sourceLines[i] + "\n";
-			}
-		} // end construct shader's source code
-
-		//PRINT("vertShaderBegins.globalLine: " << vertShaderBegins.globalLine)
-		//PRINT("fragShaderBegins.globalLine: " << fragShaderBegins.globalLine)
-		//printSourceLines();
-		//printShaderVars();
-	}
-	catch(Exception& e)
-	{
-		throw EXCEPTION("Started from \"" + filename + "\": " + e.what());
-	}
-}
-

+ 10 - 39
src/Resources/ShaderProg.cpp

@@ -5,7 +5,7 @@
 #include <fstream>
 #include <fstream>
 #include <sstream>
 #include <sstream>
 #include "Resources/ShaderProg.h"
 #include "Resources/ShaderProg.h"
-#include "ShaderPrePreprocessor.h"
+#include "ShaderProgramPrePreprocessor.h"
 #include "Core/App.h" // To get cache dir
 #include "Core/App.h" // To get cache dir
 #include "GfxApi/GlException.h"
 #include "GfxApi/GlException.h"
 #include "Core/Logger.h"
 #include "Core/Logger.h"
@@ -180,32 +180,6 @@ void ShaderProg::getUniAndAttribVars()
 }
 }
 
 
 
 
-//==============================================================================
-// bindCustomAttribLocs                                                        =
-//==============================================================================
-void ShaderProg::bindCustomAttribLocs(const ShaderPrePreprocessor& pars) const
-{
-	for(uint i=0; i<pars.getOutput().getAttribLocs().size(); ++i)
-	{
-		const std::string& name = pars.getOutput().getAttribLocs()[i].name;
-		int loc = pars.getOutput().getAttribLocs()[i].customLoc;
-		glBindAttribLocation(glId, loc, name.c_str());
-
-		// check for error
-		try
-		{
-			ON_GL_FAIL_THROW_EXCEPTION();
-		}
-		catch(std::exception& e)
-		{
-			throw SPROG_EXCEPTION("Something went wrong for attrib \"" +
-				name + "\" and location " +
-				boost::lexical_cast<std::string>(loc) + ": " + e.what());
-		}
-	}
-}
-
-
 //==============================================================================
 //==============================================================================
 // load                                                                        =
 // load                                                                        =
 //==============================================================================
 //==============================================================================
@@ -214,17 +188,17 @@ void ShaderProg::load(const char* filename)
 	rsrcFilename = filename;
 	rsrcFilename = filename;
 	ASSERT(glId == std::numeric_limits<uint>::max());
 	ASSERT(glId == std::numeric_limits<uint>::max());
 
 
-	ShaderPrePreprocessor pars(filename);
+	ShaderProgramPrePreprocessor pars(filename);
 
 
 	// 1) create and compile the shaders
 	// 1) create and compile the shaders
 	std::string preprocSource = stdSourceCode;
 	std::string preprocSource = stdSourceCode;
 	vertShaderGlId = createAndCompileShader(
 	vertShaderGlId = createAndCompileShader(
-		pars.getOutput().getVertShaderSource().c_str(),
+		pars.getVertexShaderSource().c_str(),
 		preprocSource.c_str(),
 		preprocSource.c_str(),
 		GL_VERTEX_SHADER);
 		GL_VERTEX_SHADER);
 
 
 	fragShaderGlId = createAndCompileShader(
 	fragShaderGlId = createAndCompileShader(
-		pars.getOutput().getFragShaderSource().c_str(),
+		pars.getFragmentShaderSource().c_str(),
 		preprocSource.c_str(),
 		preprocSource.c_str(),
 		GL_FRAGMENT_SHADER);
 		GL_FRAGMENT_SHADER);
 
 
@@ -237,23 +211,20 @@ void ShaderProg::load(const char* filename)
 	glAttachShader(glId, vertShaderGlId);
 	glAttachShader(glId, vertShaderGlId);
 	glAttachShader(glId, fragShaderGlId);
 	glAttachShader(glId, fragShaderGlId);
 
 
-	// 3) bind the custom attrib locs
-	bindCustomAttribLocs(pars);
-
-	// 5) set the TRFFB varyings
-	if(pars.getOutput().getTrffbVaryings().size() > 0)
+	// 3) set the TRFFB varyings
+	if(pars.getTranformFeedbackVaryings().size() > 0)
 	{
 	{
 		boost::array<const char*, 128> varsArr;
 		boost::array<const char*, 128> varsArr;
-		for(uint i=0; i<pars.getOutput().getTrffbVaryings().size(); i++)
+		for(uint i = 0; i < pars.getTranformFeedbackVaryings().size(); i++)
 		{
 		{
-			varsArr[i] = pars.getOutput().getTrffbVaryings()[i].name.c_str();
+			varsArr[i] = pars.getTranformFeedbackVaryings()[i].c_str();
 		}
 		}
 		glTransformFeedbackVaryings(glId,
 		glTransformFeedbackVaryings(glId,
-			pars.getOutput().getTrffbVaryings().size(), &varsArr[0],
+			pars.getTranformFeedbackVaryings().size(), &varsArr[0],
 			GL_SEPARATE_ATTRIBS);
 			GL_SEPARATE_ATTRIBS);
 	}
 	}
 
 
-	// 6) link
+	// 4) link
 	link();
 	link();
 
 
 	// init the rest
 	// init the rest

+ 1 - 5
src/Resources/ShaderProg.h

@@ -13,7 +13,7 @@
 #include "Core/Globals.h"
 #include "Core/Globals.h"
 
 
 
 
-class ShaderPrePreprocessor;
+class ShaderProgramPrePreprocessor;
 
 
 
 
 /// Shader program @ref Resource
 /// Shader program @ref Resource
@@ -112,10 +112,6 @@ class ShaderProg
 		/// prog is done gather all the vars in custom containers
 		/// prog is done gather all the vars in custom containers
 		void getUniAndAttribVars();
 		void getUniAndAttribVars();
 
 
-		/// Uses glBindAttribLocation for every parser attrib location
-		/// @exception Exception
-		void bindCustomAttribLocs(const class ShaderPrePreprocessor& pars) const;
-
 		/// Create and compile shader
 		/// Create and compile shader
 		/// @return The shader's OpenGL id
 		/// @return The shader's OpenGL id
 		/// @exception Exception
 		/// @exception Exception

+ 351 - 0
src/Resources/ShaderProgramPrePreprocessor.cpp

@@ -0,0 +1,351 @@
+#include <iomanip>
+#include <cstring>
+#include <iostream>
+#include <boost/lexical_cast.hpp>
+#include <boost/foreach.hpp>
+#include "ShaderProgramPrePreprocessor.h"
+#include "Misc/Parser.h"
+#include "Util/Util.h"
+#include "Util/Exception.h"
+
+
+static const char* MULTIPLE_DEF_MSG = " already defined in the same place. "
+	"Check for circular or multiple includance";
+
+
+//==============================================================================
+// printSourceLines                                                            =
+//==============================================================================
+void ShaderProgramPrePreprocessor::printSourceLines() const
+{
+	for(uint i = 0; i < sourceLines.size(); ++i)
+	{
+		std::cout << std::setw(3) << (i + 1) << ": " <<
+			sourceLines[i] << std::endl;
+	}
+}
+
+
+//==============================================================================
+// parseFileForPragmas                                                         =
+//==============================================================================
+void ShaderProgramPrePreprocessor::parseFileForPragmas(
+	const std::string& filename, int depth)
+{
+	// first check the depth
+	if(depth > 99)
+	{
+		throw EXCEPTION("File \"" + filename +
+			"\": The include depth is too high. Probably circular includance");
+	}
+
+	// load file in lines
+	Vec<std::string> lines = Util::getFileLines(filename.c_str());
+	if(lines.size() < 1)
+	{
+		throw EXCEPTION("File \"" + filename + "\": Cannot open or empty");
+	}
+
+	Scanner::Scanner scanner(filename.c_str(), false);
+	const Scanner::Token* token;
+
+	while(true)
+	{
+		token = &scanner.getNextToken();
+
+		// #
+		if(token->getCode() == Scanner::TC_SHARP)
+		{
+			token = &scanner.getNextToken();
+			// pragma
+			if(Parser::isIdentifier(*token, "pragma"))
+			{
+				token = &scanner.getNextToken();
+				// anki
+				if(Parser::isIdentifier(*token, "anki"))
+				{
+					// start
+					token = &scanner.getNextToken();
+					if(Parser::isIdentifier(*token, "start"))
+					{
+						parseStartPragma(scanner, filename, depth, lines);
+					}
+					// include
+					else if(Parser::isIdentifier(*token, "include"))
+					{
+						parseIncludePragma(scanner, filename, depth, lines);
+					}
+					// transformFeedbackVarying
+					else if(Parser::isIdentifier(*token,
+						"transformFeedbackVarying"))
+					{
+						parseTrffbVarying(scanner, filename, depth, lines);
+					}
+					// error
+					else
+					{
+						throw PARSER_EXCEPTION(
+							"#pragma anki followed by incorrect " +
+							token->getInfoStr());
+					}
+				} // end if anki
+
+				token = &scanner.getNextToken();
+				if(token->getCode()!=Scanner::TC_NEWLINE &&
+					token->getCode()!=Scanner::TC_EOF)
+				{
+					throw PARSER_EXCEPTION_EXPECTED("newline or end of file");
+				}
+
+				if(token->getCode() == Scanner::TC_EOF)
+				{
+					break;
+				}
+
+			} // end if pragma
+		} // end if #
+		//
+		// newline
+		//
+		else if(token->getCode() == Scanner::TC_NEWLINE)
+		{
+			sourceLines.push_back(lines[scanner.getLineNumber() - 2]);
+			//PRINT(lines[scanner.getLineNmbr() - 2])
+		}
+		//
+		// EOF
+		//
+		else if(token->getCode() == Scanner::TC_EOF)
+		{
+			sourceLines.push_back(lines[scanner.getLineNumber() - 1]);
+			//PRINT(lines[scanner.getLineNmbr() - 1])
+			break;
+		}
+		//
+		// error
+		//
+		else if(token->getCode() == Scanner::TC_ERROR)
+		{
+			// It will never get here
+		}
+	} // end while
+}
+
+
+//==============================================================================
+// parseFile                                                                   =
+//==============================================================================
+void ShaderProgramPrePreprocessor::parseFile(const char* filename)
+{
+	try
+	{
+		// parse master file
+		parseFileForPragmas(filename);
+	
+		// sanity checks
+		if(vertShaderBegins.globalLine == -1)
+		{
+			throw EXCEPTION("Entry point \"vertexShader\" is not defined");
+		}
+		if(fragShaderBegins.globalLine == -1)
+		{
+			throw EXCEPTION("Entry point \"fragmentShader\" is not defined");
+		}
+
+		// construct shader's source code
+		{
+			// init
+			output.vertShaderSource = "";
+			output.geomShaderSource = "";
+			output.fragShaderSource = "";
+
+			// put global source code
+			for(int i = 0; i < vertShaderBegins.globalLine - 1; ++i)
+			{
+				output.vertShaderSource += sourceLines[i] + "\n";
+
+				if(geomShaderBegins.definedInLine != -1)
+				{
+					output.geomShaderSource += sourceLines[i] + "\n";
+				}
+
+				output.fragShaderSource += sourceLines[i] + "\n";
+			}
+
+			// vert shader code
+			int limit = (geomShaderBegins.definedInLine != -1) ?
+				geomShaderBegins.globalLine-1 : fragShaderBegins.globalLine-1;
+			for(int i = vertShaderBegins.globalLine - 1; i < limit; ++i)
+			{
+				output.vertShaderSource += sourceLines[i] + "\n";
+			}
+
+			// geom shader code
+			if(geomShaderBegins.definedInLine != -1)
+			{
+				for(int i = geomShaderBegins.globalLine - 1;
+					i < fragShaderBegins.globalLine - 1; ++i)
+				{
+					output.geomShaderSource += sourceLines[i] + "\n";
+				}
+			}
+
+			// frag shader code
+			for(int i = fragShaderBegins.globalLine - 1;
+				i < int(sourceLines.size()); ++i)
+			{
+				output.fragShaderSource += sourceLines[i] + "\n";
+			}
+		} // end construct shader's source code
+
+		BOOST_FOREACH(const TrffbVaryingPragma& trffbv, output.trffbVaryings)
+		{
+			trffbVaryings.push_back(trffbv.name);
+		}
+
+		//PRINT("vertShaderBegins.globalLine: " << vertShaderBegins.globalLine)
+		//PRINT("fragShaderBegins.globalLine: " << fragShaderBegins.globalLine)
+		//printSourceLines();
+		//printShaderVars();
+	}
+	catch(Exception& e)
+	{
+		throw EXCEPTION("Started from \"" + filename + "\": " + e.what());
+	}
+}
+
+
+//==============================================================================
+// parseStartPragma                                                            =
+//==============================================================================
+void ShaderProgramPrePreprocessor::parseStartPragma(Scanner::Scanner& scanner,
+	const std::string& filename, uint depth, const Vec<std::string>& lines)
+{
+	const Scanner::Token* token = &scanner.getNextToken();
+
+	// Chose the correct pragma
+	CodeBeginningPragma* cbp;
+	std::string name;
+	if(Parser::isIdentifier(*token, "vertexShader"))
+	{
+		cbp = &vertShaderBegins;
+		name = "vertexShader";
+	}
+	else if(Parser::isIdentifier(*token, "geometryShader"))
+	{
+		cbp = &geomShaderBegins;
+		name = "geometryShader";
+	}
+	else if(Parser::isIdentifier(*token, "fragmentShader"))
+	{
+		cbp = &fragShaderBegins;
+		name = "fragmentShader";
+	}
+	else
+	{
+		throw PARSER_EXCEPTION_EXPECTED("vertexShader or geometryShader or "
+			"fragmentShader");
+	}
+
+	// its defined in same place so there is probable circular includance
+	if(cbp->definedInLine == scanner.getLineNumber() &&
+		cbp->definedInFile == filename)
+	{
+		throw PARSER_EXCEPTION(name + MULTIPLE_DEF_MSG);
+	}
+
+	// already defined elsewhere => error
+	if(cbp->definedInLine != -1)
+	{
+		throw PARSER_EXCEPTION( name +  " already defined at " +
+			cbp->definedInFile + ":" +
+			boost::lexical_cast<std::string>(cbp->definedInLine));
+	}
+
+	cbp->definedInFile = filename;
+	cbp->definedInLine = scanner.getLineNumber();
+	cbp->globalLine = sourceLines.size() + 1;
+	sourceLines.push_back("#line " +
+		boost::lexical_cast<std::string>(scanner.getLineNumber()) +
+		' ' + boost::lexical_cast<std::string>(depth) +
+		" // " + lines[scanner.getLineNumber() - 1]);
+}
+
+
+//==============================================================================
+// parseIncludePragma                                                          =
+//==============================================================================
+void ShaderProgramPrePreprocessor::parseIncludePragma(
+	Scanner::Scanner& scanner, const std::string& /*filename*/, uint depth,
+	const Vec<std::string>& lines)
+{
+	const Scanner::Token* token = &scanner.getNextToken();
+
+	if(token->getCode() == Scanner::TC_STRING)
+	{
+		std::string filename = token->getValue().getString();
+
+		//int line = sourceLines.size();
+		sourceLines.push_back("#line 0 " +
+			boost::lexical_cast<std::string>(depth + 1) +
+			" // " + lines[scanner.getLineNumber() - 1]);
+
+		parseFileForPragmas(filename.c_str(), depth + 1);
+
+		sourceLines.push_back("#line " +
+			boost::lexical_cast<std::string>(scanner.getLineNumber()) + ' ' +
+			boost::lexical_cast<std::string>(depth) + " // end of " +
+			lines[scanner.getLineNumber() - 1]);
+	}
+	else
+	{
+		throw PARSER_EXCEPTION_EXPECTED("string");
+	}
+}
+
+
+//==============================================================================
+// parseTrffbVarying                                                           =
+//==============================================================================
+void ShaderProgramPrePreprocessor::parseTrffbVarying(Scanner::Scanner& scanner,
+	const std::string& filename, uint /*depth*/, const Vec<std::string>& lines)
+{
+	const Scanner::Token* token = &scanner.getNextToken();
+
+	if(token->getCode() == Scanner::TC_IDENTIFIER)
+	{
+		std::string varName = token->getValue().getString();
+
+		// check if already defined and for circular includance
+		Vec<TrffbVaryingPragma>::const_iterator var =
+			findNamed(output.trffbVaryings, varName);
+
+		// Throw the correct exception
+		if(var != output.trffbVaryings.end())
+		{
+			if(var->definedInLine == scanner.getLineNumber() &&
+				var->definedInFile == filename)
+			{
+				throw PARSER_EXCEPTION("\"" + varName +
+					"\"" + MULTIPLE_DEF_MSG);
+			}
+			else
+			{
+				throw PARSER_EXCEPTION("Varying \"" + varName +
+					"\" already defined at " + var->definedInFile + ":" +
+					boost::lexical_cast<std::string>(var->definedInLine));
+			}
+		}
+
+		// all ok, push it back
+		output.trffbVaryings.push_back(TrffbVaryingPragma(filename,
+			scanner.getLineNumber(), varName));
+
+		sourceLines.push_back(lines[scanner.getLineNumber() - 1]);
+	}
+	else
+	{
+		throw PARSER_EXCEPTION_EXPECTED("identifier");
+	}
+}
+

+ 58 - 72
src/Resources/ShaderPrePreprocessor.h → src/Resources/ShaderProgramPrePreprocessor.h

@@ -1,5 +1,5 @@
-#ifndef SHADER_PARSER_H
-#define SHADER_PARSER_H
+#ifndef SHADER_PROGRAM_PRE_PREPROCESSOR_H
+#define SHADER_PROGRAM_PRE_PREPROCESSOR_H
 
 
 #include <limits>
 #include <limits>
 #include "Util/Vec.h"
 #include "Util/Vec.h"
@@ -7,25 +7,45 @@
 #include "Util/Accessors.h"
 #include "Util/Accessors.h"
 
 
 
 
+namespace Scanner {
+class Scanner;
+}
+
+
 /// Helper class used for shader program loading
 /// Helper class used for shader program loading
 ///
 ///
 /// The class fills some of the GLSL spec deficiencies. It adds the include
 /// The class fills some of the GLSL spec deficiencies. It adds the include
 /// preprocessor directive and the support to have all the shaders in the same
 /// preprocessor directive and the support to have all the shaders in the same
 /// file. The file that includes all the shaders is called
 /// file. The file that includes all the shaders is called
-/// ShaderPrePreprocessor-compatible.
+/// ShaderProgramPrePreprocessor-compatible.
 ///
 ///
 /// The preprocessor pragmas are:
 /// The preprocessor pragmas are:
 ///
 ///
-/// - #pragma anki vertShaderBegins
-/// - #pragma anki geomShaderBegins
-/// - #pragma anki fragShaderBegins
-/// - #pragma anki attribute <varName> <customLocation>
+/// - #pragma anki start <vertexShader | geometryShader | fragmentShader>
 /// - #pragma anki include "<filename>"
 /// - #pragma anki include "<filename>"
 /// - #pragma anki transformFeedbackVarying <varName>
 /// - #pragma anki transformFeedbackVarying <varName>
 ///
 ///
 /// @note The order of the *ShaderBegins is important
 /// @note The order of the *ShaderBegins is important
-class ShaderPrePreprocessor
+class ShaderProgramPrePreprocessor
 {
 {
+	public:
+		/// It loads a file and parses it
+		/// @param[in] filename The file to load
+		/// @exception Exception
+		ShaderProgramPrePreprocessor(const char* filename)
+			{parseFile(filename);}
+
+		/// Destructor does nothing
+		~ShaderProgramPrePreprocessor() {}
+
+		/// @name Accessors
+		/// @{
+		GETTER_R(Vec<std::string>, trffbVaryings, getTranformFeedbackVaryings)
+		GETTER_R(std::string, output.vertShaderSource, getVertexShaderSource)
+		GETTER_R(std::string, output.geomShaderSource, getGeometryShaderSource)
+		GETTER_R(std::string, output.fragShaderSource, getFragmentShaderSource)
+		/// @}
+
 	protected:
 	protected:
 		/// The pragma base class
 		/// The pragma base class
 		struct Pragma
 		struct Pragma
@@ -40,16 +60,6 @@ class ShaderPrePreprocessor
 		{
 		{
 			std::string filename;
 			std::string filename;
 		};
 		};
-		
-		struct ShaderVarPragma: Pragma
-		{
-			std::string name;
-			uint customLoc;
-
-			ShaderVarPragma(const std::string& definedInFile_,
-				int definedInLine_, const std::string& name_,
-				uint customLoc_);
-		};
 
 
 		struct TrffbVaryingPragma: Pragma
 		struct TrffbVaryingPragma: Pragma
 		{
 		{
@@ -61,7 +71,8 @@ class ShaderPrePreprocessor
 	
 	
 		struct CodeBeginningPragma: Pragma
 		struct CodeBeginningPragma: Pragma
 		{
 		{
-			/// The line number in the ShaderPrePreprocessor-compatible file
+			/// The line number in the ShaderProgramPrePreprocessor-compatible
+			/// file
 			int globalLine;
 			int globalLine;
 
 
 			CodeBeginningPragma(): globalLine(-1) {}
 			CodeBeginningPragma(): globalLine(-1) {}
@@ -70,47 +81,24 @@ class ShaderPrePreprocessor
 		/// The output of the class packed in this struct
 		/// The output of the class packed in this struct
 		struct Output
 		struct Output
 		{
 		{
-			friend class ShaderPrePreprocessor;
-
-			public:
-				GETTER_R(Vec<ShaderVarPragma>, attributes, getAttribLocs)
-				GETTER_R(Vec<TrffbVaryingPragma>, trffbVaryings,
-					getTrffbVaryings)
-				GETTER_R(std::string, vertShaderSource, getVertShaderSource)
-				GETTER_R(std::string, geomShaderSource, getGeomShaderSource)
-				GETTER_R(std::string, fragShaderSource, getFragShaderSource)
-			
-			private:
-				/// It holds the name and the custom location
-				Vec<ShaderVarPragma> attributes;
-				/// Names and and ids for transform feedback varyings
-				Vec<TrffbVaryingPragma> trffbVaryings;
-				std::string vertShaderSource; ///< The vert shader source
-				std::string geomShaderSource; ///< The geom shader source
-				std::string fragShaderSource; ///< The frag shader source
-		};
-		
+			friend class ShaderProgramPrePreprocessor;
 
 
-	public:
-		/// It loads a file and parses it
-		/// @param[in] filename The file to load
-		/// @exception Exception
-		ShaderPrePreprocessor(const char* filename) {parseFile(filename);}
-
-		/// Destructor does nothing
-		~ShaderPrePreprocessor() {}
-		
-		GETTER_R(Output, output, getOutput)
+			/// Names and and ids for transform feedback varyings
+			Vec<TrffbVaryingPragma> trffbVaryings;
+			std::string vertShaderSource; ///< The vert shader source
+			std::string geomShaderSource; ///< The geom shader source
+			std::string fragShaderSource; ///< The frag shader source
+		};
 
 
-	protected:
 		Output output; ///< The most important variable
 		Output output; ///< The most important variable
+		Vec<std::string> trffbVaryings;
 		Vec<std::string> sourceLines;  ///< The parseFileForPragmas fills this
 		Vec<std::string> sourceLines;  ///< The parseFileForPragmas fills this
 		CodeBeginningPragma vertShaderBegins;
 		CodeBeginningPragma vertShaderBegins;
 		CodeBeginningPragma geomShaderBegins;
 		CodeBeginningPragma geomShaderBegins;
 		CodeBeginningPragma fragShaderBegins;
 		CodeBeginningPragma fragShaderBegins;
 
 
-		/// Parse a ShaderPrePreprocessor formated GLSL file. Use getOutput to
-		/// get the output
+		/// Parse a ShaderProgramPrePreprocessor formated GLSL file. Use
+		/// the accessors to get the output
 		/// @param filename The file to parse
 		/// @param filename The file to parse
 		/// @exception Ecxeption
 		/// @exception Ecxeption
 		void parseFile(const char* filename);
 		void parseFile(const char* filename);
@@ -124,12 +112,20 @@ class ShaderPrePreprocessor
 		/// @exception Ecxeption
 		/// @exception Ecxeption
 		void parseFileForPragmas(const std::string& filename, int depth = 0);
 		void parseFileForPragmas(const std::string& filename, int depth = 0);
 
 
-		/// Searches inside the Output::uniforms or Output::attributes vectors
-		/// @param vec Output::uniforms or Output::attributes
-		/// @param name The name of the location
-		/// @return Iterator to the vector
-		Vec<ShaderVarPragma>::iterator findShaderVar(Vec<ShaderVarPragma>& vec,
-			const std::string& name) const;
+		/// @todo
+		void parseStartPragma(Scanner::Scanner& scanner,
+			const std::string& filename, uint depth,
+			const Vec<std::string>& lines);
+
+		/// @todo
+		void parseIncludePragma(Scanner::Scanner& scanner,
+			const std::string& filename, uint depth,
+			const Vec<std::string>& lines);
+
+		/// @todo
+		void parseTrffbVarying(Scanner::Scanner& scanner,
+			const std::string& filename, uint depth,
+			const Vec<std::string>& lines);
 
 
 		/// Searches inside the Output::attributes or Output::trffbVaryings
 		/// Searches inside the Output::attributes or Output::trffbVaryings
 		/// vectors
 		/// vectors
@@ -141,7 +137,6 @@ class ShaderPrePreprocessor
 			const std::string& what) const;
 			const std::string& what) const;
 
 
 		void printSourceLines() const;  ///< For debugging
 		void printSourceLines() const;  ///< For debugging
-		void printShaderVars() const;  ///< For debugging
 };
 };
 
 
 
 
@@ -149,23 +144,14 @@ class ShaderPrePreprocessor
 // Inlines                                                                     =
 // Inlines                                                                     =
 //==============================================================================
 //==============================================================================
 
 
-inline ShaderPrePreprocessor::Pragma::Pragma(const std::string& definedInFile_,
-	int definedInLine_)
+inline ShaderProgramPrePreprocessor::Pragma::Pragma(
+	const std::string& definedInFile_, int definedInLine_)
 :	definedInFile(definedInFile_),
 :	definedInFile(definedInFile_),
 	definedInLine(definedInLine_)
 	definedInLine(definedInLine_)
 {}
 {}
 
 
 
 
-inline ShaderPrePreprocessor::ShaderVarPragma::ShaderVarPragma(
-	const std::string& definedInFile_, int definedInLine_,
-	const std::string& name_, uint customLoc_)
-:	Pragma(definedInFile_, definedInLine_),
-	name(name_),
-	customLoc(customLoc_)
-{}
-
-
-inline ShaderPrePreprocessor::TrffbVaryingPragma::TrffbVaryingPragma(
+inline ShaderProgramPrePreprocessor::TrffbVaryingPragma::TrffbVaryingPragma(
 	const std::string& definedInFile_,
 	const std::string& definedInFile_,
 	int definedInLine_, const std::string& name_)
 	int definedInLine_, const std::string& name_)
 :	Pragma(definedInFile_, definedInLine_),
 :	Pragma(definedInFile_, definedInLine_),
@@ -174,7 +160,7 @@ inline ShaderPrePreprocessor::TrffbVaryingPragma::TrffbVaryingPragma(
 
 
 
 
 template<typename Type>
 template<typename Type>
-typename Vec<Type>::const_iterator ShaderPrePreprocessor::findNamed(
+typename Vec<Type>::const_iterator ShaderProgramPrePreprocessor::findNamed(
 	const Vec<Type>& vec, const std::string& what) const
 	const Vec<Type>& vec, const std::string& what) const
 {
 {
 	typename Vec<Type>::const_iterator it = vec.begin();
 	typename Vec<Type>::const_iterator it = vec.begin();

+ 0 - 0
src/Util/Scanner/ScannerCommon.h → src/Util/Scanner/Common.h


+ 5 - 4
src/Util/Scanner/ScannerException.cpp → src/Util/Scanner/Exception.cpp

@@ -1,4 +1,4 @@
-#include "ScannerException.h"
+#include "Exception.h"
 #include <boost/lexical_cast.hpp>
 #include <boost/lexical_cast.hpp>
 
 
 
 
@@ -33,9 +33,10 @@ Exception::Exception(const Exception& e)
 //==============================================================================
 //==============================================================================
 const char* Exception::what() const throw()
 const char* Exception::what() const throw()
 {
 {
-	errWhat = "Scanner exception #" + boost::lexical_cast<std::string>(errNo) +
-		" (" + scriptFilename + ':' +
-		boost::lexical_cast<std::string>(scriptLineNmbr) + ") " + error;
+	errWhat = "Scanner exception (#" +
+		boost::lexical_cast<std::string>(errNo) +
+		":" + scriptFilename + ':' +
+		boost::lexical_cast<std::string>(scriptLineNmbr) + "): " + error;
 	return errWhat.c_str();
 	return errWhat.c_str();
 }
 }
 
 

+ 0 - 0
src/Util/Scanner/ScannerException.h → src/Util/Scanner/Exception.h


+ 6 - 2
src/Util/Scanner/Scanner.cpp

@@ -4,7 +4,7 @@
 #include <cmath>
 #include <cmath>
 #include <cassert>
 #include <cassert>
 #include "Scanner.h"
 #include "Scanner.h"
-#include "ScannerException.h"
+#include "Exception.h"
 #include <sstream>
 #include <sstream>
 #include <iomanip>
 #include <iomanip>
 #include <boost/lexical_cast.hpp>
 #include <boost/lexical_cast.hpp>
@@ -119,7 +119,7 @@ void Scanner::initAsciiMap()
 		asciiLookupTable['|'] = asciiLookupTable['&'] = asciiLookupTable['+'] =
 		asciiLookupTable['|'] = asciiLookupTable['&'] = asciiLookupTable['+'] =
 		asciiLookupTable['-'] = asciiLookupTable['*'] = asciiLookupTable['/'] =
 		asciiLookupTable['-'] = asciiLookupTable['*'] = asciiLookupTable['/'] =
 		asciiLookupTable['~'] = asciiLookupTable['%'] = asciiLookupTable['#'] =
 		asciiLookupTable['~'] = asciiLookupTable['%'] = asciiLookupTable['#'] =
-		asciiLookupTable['^'] = AC_SPECIAL;
+		asciiLookupTable['^'] = asciiLookupTable['\\'] = AC_SPECIAL;
 
 
 	asciiLookupTable['\t'] = asciiLookupTable[' '] = asciiLookupTable['\0'] =
 	asciiLookupTable['\t'] = asciiLookupTable[' '] = asciiLookupTable['\0'] =
 		AC_WHITESPACE;
 		AC_WHITESPACE;
@@ -1256,6 +1256,10 @@ void Scanner::checkSpecial()
 					code = TC_XOR;
 					code = TC_XOR;
 			}
 			}
 			break;
 			break;
+
+		case '\\':
+			code = TC_BACK_SLASH;
+			break;
 	}
 	}
 
 
 	getNextChar();
 	getNextChar();

+ 1 - 1
src/Util/Scanner/Scanner.h

@@ -1,7 +1,7 @@
 #ifndef SCANNER_H
 #ifndef SCANNER_H
 #define SCANNER_H
 #define SCANNER_H
 
 
-#include "ScannerToken.h"
+#include "Token.h"
 #include <fstream>
 #include <fstream>
 
 
 
 

+ 1 - 1
src/Util/Scanner/ScannerToken.cpp → src/Util/Scanner/Token.cpp

@@ -1,4 +1,4 @@
-#include "ScannerToken.h"
+#include "Token.h"
 #include <cstring>
 #include <cstring>
 #include <cstdio>
 #include <cstdio>
 #include <iostream>
 #include <iostream>

+ 2 - 2
src/Util/Scanner/ScannerToken.h → src/Util/Scanner/Token.h

@@ -3,7 +3,7 @@
 
 
 #include <string>
 #include <string>
 #include <boost/array.hpp>
 #include <boost/array.hpp>
-#include "ScannerCommon.h"
+#include "Common.h"
 
 
 
 
 namespace Scanner {
 namespace Scanner {
@@ -34,7 +34,7 @@ enum TokenCode
 	TC_MOD, TC_XOR, TC_INC, TC_DEC, TC_SHL,
 	TC_MOD, TC_XOR, TC_INC, TC_DEC, TC_SHL,
 	TC_SHR, TC_ASSIGN, TC_ASSIGNADD, TC_ASSIGNSUB, TC_ASSIGNMUL,
 	TC_SHR, TC_ASSIGN, TC_ASSIGNADD, TC_ASSIGNSUB, TC_ASSIGNMUL,
 	TC_ASSIGNDIV, TC_ASSIGNMOD, TC_ASSIGNSHL, TC_ASSIGNSHR, TC_ASSIGNAND,
 	TC_ASSIGNDIV, TC_ASSIGNMOD, TC_ASSIGNSHL, TC_ASSIGNSHR, TC_ASSIGNAND,
-	TC_ASSIGNXOR, TC_ASSIGNOR
+	TC_ASSIGNXOR, TC_ASSIGNOR, TC_BACK_SLASH
 }; // end enum TokenCode
 }; // end enum TokenCode