Browse Source

Dummy tessellation is working. Need to create some real algorithms now

Panagiotis Christopoulos Charitos 12 years ago
parent
commit
6573ffbf06

+ 14 - 13
include/anki/gl/GlState.h

@@ -17,7 +17,7 @@ class ShaderProgram;
 /// @addtogroup OpenGL
 /// @addtogroup OpenGL
 /// @{
 /// @{
 
 
-/// Common stuff for all states
+/// Common stuff for all GL states
 class GlStateCommon
 class GlStateCommon
 {
 {
 public:
 public:
@@ -29,15 +29,11 @@ public:
 		GPU_NVIDIA
 		GPU_NVIDIA
 	};
 	};
 
 
-	U32 getMajorVersion() const
+	/// Return something like 430
+	U32 getVersion() const
 	{
 	{
-		ANKI_ASSERT(major != -1);
-		return (U32)major;
-	}
-	U32 getMinorVersion() const
-	{
-		ANKI_ASSERT(minor != -1);
-		return (U32)minor;
+		ANKI_ASSERT(version != -1);
+		return version;
 	}
 	}
 
 
 	Gpu getGpu() const
 	Gpu getGpu() const
@@ -45,17 +41,22 @@ public:
 		return gpu;
 		return gpu;
 	}
 	}
 
 
-	Bool isStd430Supported() const
+	Bool isTessellationSupported() const
+	{
+		return version >= 400;
+	}
+
+	Bool isComputeShaderSupported() const
 	{
 	{
-		return major >= 4 && minor >= 3;
+		return version >= 430;
 	}
 	}
 
 
-	void init(const U32 major_, const U32 minor_, 
+	void init(const U32 major, const U32 minor, 
 		Bool registerDebugMessages = false);
 		Bool registerDebugMessages = false);
 
 
 private:
 private:
 	/// Minor major GL version
 	/// Minor major GL version
-	I32 major = -1, minor = -1;
+	I32 version = -1;
 	Gpu gpu = GPU_UNKNOWN;
 	Gpu gpu = GPU_UNKNOWN;
 };
 };
 
 

+ 6 - 0
include/anki/resource/Material.h

@@ -197,6 +197,11 @@ public:
 	{
 	{
 		return wireframe;
 		return wireframe;
 	}
 	}
+
+	Bool getTessellation() const
+	{
+		return tessellation;
+	}
 	/// @}
 	/// @}
 
 
 	/// Check if blending is enabled
 	/// Check if blending is enabled
@@ -212,6 +217,7 @@ protected:
 	Bool8 depthTesting = true;
 	Bool8 depthTesting = true;
 	Bool8 wireframe = false;
 	Bool8 wireframe = false;
 	Bool8 shadow = true;
 	Bool8 shadow = true;
+	Bool8 tessellation = false;
 
 
 	U8 passesCount = 1;
 	U8 passesCount = 1;
 	U8 lodsCount = 1;
 	U8 lodsCount = 1;

+ 16 - 0
include/anki/resource/MaterialShaderProgramCreator.h

@@ -45,6 +45,18 @@ public:
 		return inputs;
 		return inputs;
 	}
 	}
 
 
+	/// At least one variable is instanced
+	Bool usesInstancing() const
+	{
+		return instanced;
+	}
+
+	/// It has tessellation shaders
+	Bool hasTessellation() const
+	{
+		return tessellation;
+	}
+
 private:
 private:
 	/// The lines of the shader program source
 	/// The lines of the shader program source
 	StringList srcLines;
 	StringList srcLines;
@@ -55,6 +67,10 @@ private:
 
 
 	Bool enableUniformBlocks;
 	Bool enableUniformBlocks;
 
 
+	Bool instanced = false;
+
+	Bool tessellation = false;
+
 	/// Parse what is within the
 	/// Parse what is within the
 	/// @code <shaderProgram></shaderProgram> @endcode
 	/// @code <shaderProgram></shaderProgram> @endcode
 	void parseShaderProgramTag(const XmlElement& el);
 	void parseShaderProgramTag(const XmlElement& el);

+ 77 - 43
shaders/MsCommonFrag.glsl

@@ -8,26 +8,32 @@
 // Variables                                                                   =
 // Variables                                                                   =
 //==============================================================================
 //==============================================================================
 
 
-/// @name Varyings
-/// @{
-#define vTexCoords_DEFINED
-in highp vec2 vTexCoords;
+/// Input
+#if TESSELLATION
+
+in highp vec2 teTexCoords;
+#if PASS_COLOR
+in mediump vec3 teNormal;
+in mediump vec4 teTangent;
+in mediump vec3 teVertPosViewSpace;
+#endif
+
+#else // no TESSELLATION
 
 
-#define vInstanceId_DEFINED
+#if INSTANCING
 flat in mediump uint vInstanceId;
 flat in mediump uint vInstanceId;
+#endif
 
 
+in highp vec2 vTexCoords;
 #if PASS_COLOR
 #if PASS_COLOR
-in vec3 vNormal;
-#	define vNormal_DEFINED
-in vec4 vTangent;
-#	define vTangent_DEFINED
-in vec3 vVertPosViewSpace;
-#	define vVertPosViewSpace_DEFINED
+in mediump vec3 vNormal;
+in mediump vec4 vTangent;
+in mediump vec3 vVertPosViewSpace;
 #endif
 #endif
-/// @}
 
 
-/// @name Fragment out
-/// @{
+#endif // TESSELLATION
+
+// Output
 #if PASS_COLOR
 #if PASS_COLOR
 #	if USE_MRT
 #	if USE_MRT
 layout(location = 0) out vec4 fMsFai0;
 layout(location = 0) out vec4 fMsFai0;
@@ -37,17 +43,62 @@ layout(location = 0) out uvec2 fMsFai0;
 #	endif
 #	endif
 #	define fMsFai0_DEFINED
 #	define fMsFai0_DEFINED
 #endif
 #endif
-/// @}
 
 
 //==============================================================================
 //==============================================================================
 // Functions                                                                   =
 // Functions                                                                   =
 //==============================================================================
 //==============================================================================
 
 
-/// @param[in] normal The fragment's normal in view space
-/// @param[in] tangent The tangent
-/// @param[in] tangent Extra stuff for the tangent
-/// @param[in] map The map
-/// @param[in] texCoords Texture coordinates
+// Getter
+#if PASS_COLOR
+#	define getNormal_DEFINED
+vec3 getNormal()
+{
+#if TESSELLATION
+	return normalize(teNormal);
+#else
+	return normalize(vNormal);
+#endif
+}
+#endif
+
+// Getter
+#if PASS_COLOR
+#	define getTangent_DEFINED
+vec4 getTangent()
+{
+#if TESSELLATION
+	return teTangent;
+#else
+	return vTangent;
+#endif
+}
+#endif
+
+// Getter
+#define getTextureCoord_DEFINED
+vec2 getTextureCoord()
+{
+#if TESSELLATION
+	return teTexCoords;
+#else
+	return vTexCoords;
+#endif
+}
+
+// Getter
+#if PASS_COLOR
+#	define getPositionViewSpace_DEFINED
+vec3 getPositionViewSpace()
+{
+#if TESSELLATION
+	return vec3(0.0);
+#else
+	return vVertPosViewSpace;
+#endif
+}
+#endif
+
+// Do normal mapping
 #if PASS_COLOR
 #if PASS_COLOR
 #	define getNormalFromTexture_DEFINED
 #	define getNormalFromTexture_DEFINED
 vec3 getNormalFromTexture(in vec3 normal, in vec4 tangent,
 vec3 getNormalFromTexture(in vec3 normal, in vec4 tangent,
@@ -59,7 +110,7 @@ vec3 getNormalFromTexture(in vec3 normal, in vec4 tangent,
 	// First read the texture
 	// First read the texture
 	vec3 nAtTangentspace = normalize((texture(map, texCoords).rgb - 0.5) * 2.0);
 	vec3 nAtTangentspace = normalize((texture(map, texCoords).rgb - 0.5) * 2.0);
 
 
-	vec3 n = normalize(normal);
+	vec3 n = normal; // Assume that getNormal() is called
 	vec3 t = normalize(tangent.xyz);
 	vec3 t = normalize(tangent.xyz);
 	vec3 b = cross(n, t) * tangent.w;
 	vec3 b = cross(n, t) * tangent.w;
 
 
@@ -70,20 +121,7 @@ vec3 getNormalFromTexture(in vec3 normal, in vec4 tangent,
 }
 }
 #endif
 #endif
 
 
-/// Just normalize
-#if PASS_COLOR
-#	define getNormalSimple_DEFINED
-vec3 getNormalSimple(in vec3 normal)
-{
-	return normalize(normal);
-}
-#endif
-
-/// Environment mapping calculations
-/// @param[in] vertPosViewSpace Fragment position in view space
-/// @param[in] normal Fragment's normal in view space as well
-/// @param[in] map The env map
-/// @return The color
+// Do environment mapping
 #if PASS_COLOR
 #if PASS_COLOR
 #	define getEnvironmentColor_DEFINED
 #	define getEnvironmentColor_DEFINED
 vec3 getEnvironmentColor(in vec3 vertPosViewSpace, in vec3 normal,
 vec3 getEnvironmentColor(in vec3 vertPosViewSpace, in vec3 normal,
@@ -103,12 +141,8 @@ vec3 getEnvironmentColor(in vec3 vertPosViewSpace, in vec3 normal,
 }
 }
 #endif
 #endif
 
 
-/// Using a 4-channel texture and a tolerance discard the fragment if the 
-/// texture's alpha is less than the tolerance
-/// @param[in] map The diffuse map
-/// @param[in] tolerance Tolerance value
-/// @param[in] texCoords Texture coordinates
-/// @return The RGB channels of the map
+// Using a 4-channel texture and a tolerance discard the fragment if the 
+// texture's alpha is less than the tolerance
 #define readTextureRgbAlphaTesting_DEFINED
 #define readTextureRgbAlphaTesting_DEFINED
 vec3 readTextureRgbAlphaTesting(
 vec3 readTextureRgbAlphaTesting(
 	in sampler2D map,
 	in sampler2D map,
@@ -136,7 +170,7 @@ vec3 readTextureRgbAlphaTesting(
 #endif
 #endif
 }
 }
 
 
-/// Just read the RGB color from texture
+// Just read the RGB color from texture
 #if PASS_COLOR
 #if PASS_COLOR
 #	define readRgbFromTexture_DEFINED
 #	define readRgbFromTexture_DEFINED
 vec3 readRgbFromTexture(in sampler2D tex, in highp vec2 texCoords)
 vec3 readRgbFromTexture(in sampler2D tex, in highp vec2 texCoords)
@@ -145,7 +179,7 @@ vec3 readRgbFromTexture(in sampler2D tex, in highp vec2 texCoords)
 }
 }
 #endif
 #endif
 
 
-/// Write the data to FAIs
+// Write the data to FAIs
 #if PASS_COLOR
 #if PASS_COLOR
 #	define writeFais_DEFINED
 #	define writeFais_DEFINED
 void writeFais(
 void writeFais(

+ 25 - 31
shaders/MsCommonTessc.glsl

@@ -1,22 +1,35 @@
+#pragma anki include "shaders/MsBsCommon.glsl"
+
 layout(vertices = 3) out;
 layout(vertices = 3) out;
 
 
 // Varyings in
 // Varyings in
-in vec3 vPosition[];
-in vec2 vTexCoords;
-in vec3 vNormal[];
-in vec3 vTangent[];
-in float vTangentW[];
+in highp vec3 vPosition[];
+in highp vec2 vTexCoords[];
+#if PASS_COLOR
+in mediump vec3 vNormal[];
+in mediump vec4 vTangent[];
+#endif
 
 
 // Varyings out
 // Varyings out
-out vec3 tcPosition[];
-out vec2 tcTexCoords;
-out vec3 tcNormal[];
-out vec3 tcTangent[];
-out float tcTangentW[];
+out highp vec3 tcPosition[];
+out highp vec2 tcTexCoords[];
+#if PASS_COLOR
+out mediump vec3 tcNormal[];
+out mediump vec4 tcTangent[];
+#endif
 
 
-#define tessellate_DEFINED
-void tessellate(in float tessLevelInner, in float tessLevelOuter)
+#define tessellatePositionNormalTangentTexCoord_DEFINED
+void tessellatePositionNormalTangentTexCoord(
+	in float tessLevelInner, 
+	in float tessLevelOuter)
 {
 {
+	tcPosition[gl_InvocationID] = vPosition[gl_InvocationID];
+	tcTexCoords[gl_InvocationID] = vTexCoords[gl_InvocationID];
+#if PASS_COLOR
+	tcNormal[gl_InvocationID] = vNormal[gl_InvocationID];
+	tcTangent[gl_InvocationID] = vTangent[gl_InvocationID];
+#endif
+
 	if(gl_InvocationID == 0) 
 	if(gl_InvocationID == 0) 
 	{
 	{
 		gl_TessLevelInner[0] = tessLevelInner;
 		gl_TessLevelInner[0] = tessLevelInner;
@@ -26,22 +39,3 @@ void tessellate(in float tessLevelInner, in float tessLevelOuter)
 	}
 	}
 }
 }
 
 
-#define tessellatePosition_DEFINED
-void tessellatePosition()
-{
-	tcPosition[gl_InvocationID] = vPosition[gl_InvocationID];
-}
-
-#define tessellateTexCoords_DEFINED
-void tessellateTexCoords()
-{
-	tcTexCoords[gl_InvocationID] = vTexCoords[gl_InvocationID];
-}
-
-#define tessellatieNormalTangent_DEFINED
-void tessellatieNormalTangent()
-{
-	tcNormal[gl_InvocationID] = vNormal[gl_InvocationID];
-	tcTangent[gl_InvocationID] = vTangent[gl_InvocationID];
-	tcTangentW[gl_InvocationID] = vTangentW[gl_InvocationID];
-}

+ 34 - 0
shaders/MsCommonTesse.glsl

@@ -0,0 +1,34 @@
+layout(triangles, equal_spacing, ccw) in;
+
+// Varyings in
+in highp vec3 tcPosition[];
+in highp vec2 tcTexCoords[];
+#if PASS_COLOR
+in mediump vec3 tcNormal[];
+in mediump vec4 tcTangent[];
+#endif
+
+// Varyings out
+out highp vec3 tePosition;
+out highp vec2 teTexCoords;
+#if PASS_COLOR
+out mediump vec3 teNormal;
+out mediump vec4 teTangent;
+#endif
+
+#define INTERPOLATE(x_) (x_[0] * gl_TessCoord.x + x_[1] * gl_TessCoord.y + x_[2] * gl_TessCoord.z)
+
+// Smooth tessellation
+#define subdivPositionNormalTangentTexCoord_DEFINED
+void subdivPositionNormalTangentTexCoord(in mat4 mvp, in mat3 normalMat)
+{
+#if PASS_COLOR
+	teNormal = normalize(normalMat * INTERPOLATE(tcNormal));
+	teTangent = INTERPOLATE(tcTangent);
+	teTangent.xyz = normalize(normalMat * teTangent.xyz);
+#endif
+
+	teTexCoords = INTERPOLATE(tcTexCoords);
+
+	gl_Position = mvp * vec4(INTERPOLATE(tcPosition), 1.0);
+}

+ 17 - 4
shaders/MsCommonVert.glsl

@@ -1,5 +1,4 @@
 #pragma anki include "shaders/MsBsCommon.glsl"
 #pragma anki include "shaders/MsBsCommon.glsl"
-#pragma anki include "shaders/Pack.glsl"
 
 
 /// @name Attributes
 /// @name Attributes
 /// @{
 /// @{
@@ -15,7 +14,7 @@ layout(location = 2) in mediump vec4 tangent;
 /// @{
 /// @{
 out highp vec2 vTexCoords;
 out highp vec2 vTexCoords;
 
 
-#ifdef INSTANCING
+#if INSTANCING
 flat out uint vInstanceId;
 flat out uint vInstanceId;
 #endif
 #endif
 
 
@@ -24,6 +23,10 @@ out mediump vec3 vNormal;
 out mediump vec4 vTangent;
 out mediump vec4 vTangent;
 out mediump vec3 vVertPosViewSpace; ///< For env mapping. AKA view vector
 out mediump vec3 vVertPosViewSpace; ///< For env mapping. AKA view vector
 #endif
 #endif
+
+#if TESSELLATION
+out highp vec3 vPosition;
+#endif
 /// @}
 /// @}
 
 
 //==============================================================================
 //==============================================================================
@@ -36,7 +39,11 @@ void writePositionTexCoord(in mat4 mvp)
 	vTexCoords = texCoord;
 	vTexCoords = texCoord;
 #endif
 #endif
 
 
+#if TESSELLATION
+	vPosition = position;
+#else
 	gl_Position = mvp * vec4(position, 1.0);
 	gl_Position = mvp * vec4(position, 1.0);
+#endif
 }
 }
 
 
 //==============================================================================
 //==============================================================================
@@ -44,9 +51,15 @@ void writePositionTexCoord(in mat4 mvp)
 void writePositionNormalTangentTexCoord(in mat4 mvp, in mat3 normalMat)
 void writePositionNormalTangentTexCoord(in mat4 mvp, in mat3 normalMat)
 {
 {
 #if PASS_COLOR
 #if PASS_COLOR
-	vNormal = vec3(normalMat * normal);
-	vTangent.xyz = vec3(normalMat * tangent.xyz);
+#	if TESSELLATION
+	// Passthrough
+	vNormal = normal;
+	vTangent = tangent;
+#	else
+	vNormal = normalMat * normal;
+	vTangent.xyz = normalMat * tangent.xyz;
 	vTangent.w = tangent.w;
 	vTangent.w = tangent.w;
+#	endif
 #endif
 #endif
 
 
 	writePositionTexCoord(mvp);
 	writePositionTexCoord(mvp);

+ 2 - 3
src/gl/GlState.cpp

@@ -74,11 +74,10 @@ static void oglMessagesCallback(GLenum source,
 #endif
 #endif
 
 
 //==============================================================================
 //==============================================================================
-void GlStateCommon::init(const U32 major_, const U32 minor_, 
+void GlStateCommon::init(const U32 major, const U32 minor, 
 	Bool registerDebugMessages)
 	Bool registerDebugMessages)
 {
 {
-	major = (I32)major_;
-	minor = (I32)minor_;
+	version = major * 100 + minor * 10;
 
 
 	std::string glstr = (const char*)glGetString(GL_VENDOR);
 	std::string glstr = (const char*)glGetString(GL_VENDOR);
 	glstr += (const char*)glGetString(GL_RENDERER);
 	glstr += (const char*)glGetString(GL_RENDERER);

+ 6 - 17
src/gl/ShaderProgram.cpp

@@ -358,8 +358,7 @@ void ShaderProgram::create(const char* vertSource, const char* tcSource,
 	const char* xfbVaryings[], const GLenum xfbBufferMode)
 	const char* xfbVaryings[], const GLenum xfbBufferMode)
 {
 {
 	ANKI_ASSERT(!isCreated());
 	ANKI_ASSERT(!isCreated());
-	U32 minor = GlStateCommonSingleton::get().getMinorVersion();
-	U32 major = GlStateCommonSingleton::get().getMajorVersion();
+	U32 version = GlStateCommonSingleton::get().getVersion();
 
 
 	// 1) create program
 	// 1) create program
 	glId = glCreateProgram();
 	glId = glCreateProgram();
@@ -372,19 +371,9 @@ void ShaderProgram::create(const char* vertSource, const char* tcSource,
 	//
 	//
 	std::string preprocSrc;
 	std::string preprocSrc;
 #if ANKI_GL == ANKI_GL_DESKTOP
 #if ANKI_GL == ANKI_GL_DESKTOP
-	preprocSrc = "#version " + std::to_string(major) 
-		+ std::to_string(minor) + "0 core\n";
-
-	if(major == 3)
-	{
-		/*preprocSrc += "#extension GL_ARB_shading_language_420pack : enable\n"
-			"#extension GL_ARB_shading_language_packing : enable\n"
-			"#extension GL_ARB_gpu_shader5 : enable\n";*/
-	}
-
+	preprocSrc = "#version " + std::to_string(version) + " core\n";
 #else
 #else
-	preprocSrc = "#version " + std::to_string(major) 
-		+ std::to_string(minor) + "0 es\n";
+	preprocSrc = "#version " + std::to_string(version) + " es\n";
 #endif
 #endif
 
 
 	// Sanity check with the combination of shaders
 	// Sanity check with the combination of shaders
@@ -427,7 +416,7 @@ void ShaderProgram::create(const char* vertSource, const char* tcSource,
 #if ANKI_GL == ANKI_GL_DESKTOP
 #if ANKI_GL == ANKI_GL_DESKTOP
 	if(tcSource != nullptr)
 	if(tcSource != nullptr)
 	{
 	{
-		ANKI_ASSERT(major > 3);
+		ANKI_ASSERT(version >= 400);
 		tcShaderGlId = createAndCompileShader(tcSource, preprocSrc.c_str(), 
 		tcShaderGlId = createAndCompileShader(tcSource, preprocSrc.c_str(), 
 			GL_TESS_CONTROL_SHADER);
 			GL_TESS_CONTROL_SHADER);
 		glAttachShader(glId, tcShaderGlId);
 		glAttachShader(glId, tcShaderGlId);
@@ -435,7 +424,7 @@ void ShaderProgram::create(const char* vertSource, const char* tcSource,
 
 
 	if(teSource != nullptr)
 	if(teSource != nullptr)
 	{
 	{
-		ANKI_ASSERT(major > 3);
+		ANKI_ASSERT(version >= 400);
 		teShaderGlId = createAndCompileShader(teSource, preprocSrc.c_str(), 
 		teShaderGlId = createAndCompileShader(teSource, preprocSrc.c_str(), 
 			GL_TESS_EVALUATION_SHADER);
 			GL_TESS_EVALUATION_SHADER);
 		glAttachShader(glId, teShaderGlId);
 		glAttachShader(glId, teShaderGlId);
@@ -450,7 +439,7 @@ void ShaderProgram::create(const char* vertSource, const char* tcSource,
 
 
 	if(compSource != nullptr)
 	if(compSource != nullptr)
 	{
 	{
-		ANKI_ASSERT(major > 3 && minor > 2);
+		ANKI_ASSERT(version >= 430);
 		compShaderGlId = createAndCompileShader(compSource, 
 		compShaderGlId = createAndCompileShader(compSource, 
 			preprocSrc.c_str(), GL_COMPUTE_SHADER);
 			preprocSrc.c_str(), GL_COMPUTE_SHADER);
 		glAttachShader(glId, compShaderGlId);
 		glAttachShader(glId, compShaderGlId);

+ 10 - 1
src/renderer/Drawer.cpp

@@ -389,7 +389,16 @@ void RenderableDrawer::render(SceneNode& frsn, RenderingStage stage,
 	// Draw call
 	// Draw call
 	Drawcall dc;
 	Drawcall dc;
 
 
-	dc.primitiveType = GL_TRIANGLES;
+	if(mtl.getTessellation())
+	{
+		glPatchParameteri(GL_PATCH_VERTICES, 3);
+		dc.primitiveType = GL_PATCHES;
+	}
+	else
+	{
+		dc.primitiveType = GL_TRIANGLES;
+	}
+
 	dc.indicesType = GL_UNSIGNED_SHORT;
 	dc.indicesType = GL_UNSIGNED_SHORT;
 	dc.instancesCount = instancesCount;
 	dc.instancesCount = instancesCount;
 	dc.indicesCountArray = (GLsizei*)indicesCountArray;
 	dc.indicesCountArray = (GLsizei*)indicesCountArray;

+ 1 - 2
src/renderer/Is.cpp

@@ -78,8 +78,7 @@ struct CommonUniforms
 // Use compute shaders on GL >= 4.3
 // Use compute shaders on GL >= 4.3
 static Bool useCompute()
 static Bool useCompute()
 {
 {
-	return GlStateCommonSingleton::get().getMajorVersion() >= 4
-		&& GlStateCommonSingleton::get().getMinorVersion() >= 3
+	return GlStateCommonSingleton::get().isComputeShaderSupported()
 		&& false;
 		&& false;
 }
 }
 
 

+ 5 - 0
src/resource/Material.cpp

@@ -272,6 +272,8 @@ void Material::parseMaterialTag(const XmlElement& materialEl)
 	MaterialShaderProgramCreator mspc(
 	MaterialShaderProgramCreator mspc(
 		shaderProgramEl, ANKI_RENDERER_USE_MATERIAL_UBOS);
 		shaderProgramEl, ANKI_RENDERER_USE_MATERIAL_UBOS);
 
 
+	tessellation = mspc.hasTessellation();
+
 	for(U level = 0; level < lodsCount; ++level)
 	for(U level = 0; level < lodsCount; ++level)
 	{
 	{
 		for(U pid = 0; pid < PASS_COUNT; ++pid)
 		for(U pid = 0; pid < PASS_COUNT; ++pid)
@@ -283,6 +285,9 @@ void Material::parseMaterialTag(const XmlElement& materialEl)
 
 
 			std::stringstream src;
 			std::stringstream src;
 
 
+			src << "#define INSTANCING " << (U)mspc.usesInstancing() << "\n";
+			src << "#define TESSELLATION " << (U)tessellation << "\n";
+
 			src << "#define LOD " << level << "\n";
 			src << "#define LOD " << level << "\n";
 
 
 			for(U i = 0; i < PASS_COUNT; i++)
 			for(U i = 0; i < PASS_COUNT; i++)

+ 30 - 11
src/resource/MaterialShaderProgramCreator.cpp

@@ -14,13 +14,14 @@ namespace anki {
 //==============================================================================
 //==============================================================================
 
 
 //==============================================================================
 //==============================================================================
+// This is a mask
 enum
 enum
 {
 {
-	VERTEX = 1,
-	TESSC,
-	TESSE,
-	GEOM,
-	FRAGMENT
+	VERTEX = 1 << 0,
+	TESSC = 1 << 1,
+	TESSE = 1 << 2,
+	GEOM = 1 << 3,
+	FRAGMENT = 1 << 4
 };
 };
 
 
 //==============================================================================
 //==============================================================================
@@ -111,6 +112,13 @@ void MaterialShaderProgramCreator::parseInputsTag(const XmlElement& programEl)
 		if(inpvar->arraySize == 0)
 		if(inpvar->arraySize == 0)
 		{
 		{
 			inpvar->instanced = (instancedEl) ? instancedEl.getInt() : 0;
 			inpvar->instanced = (instancedEl) ? instancedEl.getInt() : 0;
+
+			// If one input var is instanced notify the whole program that 
+			// it's instanced
+			if(inpvar->instanced)
+			{
+				instanced = true;
+			}
 		}
 		}
 
 
 		// <value>
 		// <value>
@@ -200,13 +208,15 @@ void MaterialShaderProgramCreator::parseShaderTag(const XmlElement& shaderEl)
 	{
 	{
 		shader = VERTEX;
 		shader = VERTEX;
 	}
 	}
-	else if(type == "tessellationControl")
+	else if(type == "tc")
 	{
 	{
 		shader = TESSC;
 		shader = TESSC;
+		tessellation = true;
 	}
 	}
-	else if(type == "tessellationEvaluation")
+	else if(type == "te")
 	{
 	{
 		shader = TESSE;
 		shader = TESSE;
+		tessellation = true;
 	}
 	}
 	else if(type == "geometry")
 	else if(type == "geometry")
 	{
 	{
@@ -302,6 +312,8 @@ void MaterialShaderProgramCreator::parseShaderTag(const XmlElement& shaderEl)
 void MaterialShaderProgramCreator::parseOperationTag(
 void MaterialShaderProgramCreator::parseOperationTag(
 	const XmlElement& operationTag, U32 shader, std::string& out)
 	const XmlElement& operationTag, U32 shader, std::string& out)
 {
 {
+	static const char OUT[] = {"out"};
+
 	// <id></id>
 	// <id></id>
 	int id = operationTag.getChildElement("id").getInt();
 	int id = operationTag.getChildElement("id").getInt();
 	
 	
@@ -311,7 +323,7 @@ void MaterialShaderProgramCreator::parseOperationTag(
 	std::string operationOut;
 	std::string operationOut;
 	if(retType != "void")
 	if(retType != "void")
 	{
 	{
-		operationOut = "out" + std::to_string(id);
+		operationOut = OUT + std::to_string(id);
 	}
 	}
 	
 	
 	// <function>functionName</function>
 	// <function>functionName</function>
@@ -337,12 +349,19 @@ void MaterialShaderProgramCreator::parseOperationTag(
 				const std::string& name = inputs[i]->name;
 				const std::string& name = inputs[i]->name;
 				if(text == name)
 				if(text == name)
 				{
 				{
-					inputs[i]->shaders |= (U32)shader;
 					input = inputs[i];
 					input = inputs[i];
+					input->shaders |= (U32)shader;
 					break;
 					break;
 				}
 				}
 			}
 			}
 
 
+			// The argument should be an input variable or an outXX
+			if(!(input != nullptr 
+				|| strncmp(argEl.getText(), OUT, sizeof(OUT) - 1) == 0))
+			{
+				throw ANKI_EXCEPTION("Incorrect argument: " + argEl.getText());
+			}
+
 			// Add to a list and do something special if instanced
 			// Add to a list and do something special if instanced
 			if(input && input->instanced)
 			if(input && input->instanced)
 			{
 			{
@@ -359,7 +378,7 @@ void MaterialShaderProgramCreator::parseOperationTag(
 				else
 				else
 				{
 				{
 					throw ANKI_EXCEPTION(
 					throw ANKI_EXCEPTION(
-						"Cannot access the instance ID all shaders");
+						"Cannot access the instance ID in all shaders");
 				}
 				}
 			}
 			}
 			else
 			else
@@ -379,7 +398,7 @@ void MaterialShaderProgramCreator::parseOperationTag(
 	// Write the defines for the operationOuts
 	// Write the defines for the operationOuts
 	for(const std::string& arg : argsList)
 	for(const std::string& arg : argsList)
 	{
 	{
-		if(arg.find("out") == 0)
+		if(arg.find(OUT) == 0)
 		{
 		{
 			lines << " && defined(" << arg << "_DEFINED)";
 			lines << " && defined(" << arg << "_DEFINED)";
 		}
 		}

+ 1 - 1
src/resource/ShaderProgramPrePreprocessor.cpp

@@ -15,8 +15,8 @@ namespace anki {
 // ShaderType enums
 // ShaderType enums
 static Array<const char*, 9> commands = {{
 static Array<const char*, 9> commands = {{
 	"#pragma anki start vertexShader",
 	"#pragma anki start vertexShader",
-	"#pragma anki start teShader",
 	"#pragma anki start tcShader",
 	"#pragma anki start tcShader",
+	"#pragma anki start teShader",
 	"#pragma anki start geometryShader",
 	"#pragma anki start geometryShader",
 	"#pragma anki start fragmentShader",
 	"#pragma anki start fragmentShader",
 	"#pragma anki start computeShader",
 	"#pragma anki start computeShader",

+ 21 - 3
src/resource/ShaderProgramResource.cpp

@@ -51,11 +51,29 @@ void ShaderProgramResource::load(const char* filename, const char* extraSrc)
 		std::string vertSrc = extraSrc + pars.getShaderSource(ST_VERTEX);
 		std::string vertSrc = extraSrc + pars.getShaderSource(ST_VERTEX);
 		std::string fragSrc = extraSrc + pars.getShaderSource(ST_FRAGMENT);
 		std::string fragSrc = extraSrc + pars.getShaderSource(ST_FRAGMENT);
 
 
+		std::string tcSrc;
+		if(pars.getShaderSource(ST_TC).size() > 0)
+		{
+			tcSrc = extraSrc + pars.getShaderSource(ST_TC);
+		}
+
+		std::string teSrc;
+		if(pars.getShaderSource(ST_TE).size() > 0)
+		{
+			teSrc = extraSrc + pars.getShaderSource(ST_TE);
+		}
+
+		std::string geomSrc;
+		if(pars.getShaderSource(ST_GEOMETRY).size() > 0)
+		{
+			geomSrc = extraSrc + pars.getShaderSource(ST_GEOMETRY);
+		}
+
 		create(
 		create(
 			vertSrc.c_str(),
 			vertSrc.c_str(),
-			nullptr,
-			nullptr,
-			nullptr,
+			tcSrc.size() ? tcSrc.c_str() : nullptr,
+			teSrc.size() ? teSrc.c_str() : nullptr,
+			geomSrc.size() ? geomSrc.c_str() : nullptr,
 			fragSrc.c_str(),
 			fragSrc.c_str(),
 			nullptr,
 			nullptr,
 			&trfVarsArr[0],
 			&trfVarsArr[0],

+ 26 - 9
tools/scene/diffNormTemplateMtl.h

@@ -7,6 +7,7 @@ R"(<?xml version="1.0" encoding="UTF-8" ?>
 			<input><type>mat3</type><name>normalMat</name><value></value><instanced>%instanced%</instanced></input>
 			<input><type>mat3</type><name>normalMat</name><value></value><instanced>%instanced%</instanced></input>
 
 
 			<input><type>vec2</type><name>specular</name><value>1.0 90.0</value></input>
 			<input><type>vec2</type><name>specular</name><value>1.0 90.0</value></input>
+			<input><type>float</type><name>blurring</name><value>0.0</value><const>1</const></input>
 			<input><type>sampler2D</type><name>diffuseMap</name><value>%diffuseMap%</value></input>
 			<input><type>sampler2D</type><name>diffuseMap</name><value>%diffuseMap%</value></input>
 			<input><type>sampler2D</type><name>normalMap</name><value>%normalMap%</value></input>
 			<input><type>sampler2D</type><name>normalMap</name><value>%normalMap%</value></input>
 		</inputs>
 		</inputs>
@@ -38,32 +39,48 @@ R"(<?xml version="1.0" encoding="UTF-8" ?>
 				<operation>
 				<operation>
 					<id>0</id>
 					<id>0</id>
 					<returnType>vec3</returnType>
 					<returnType>vec3</returnType>
+					<function>getNormal</function>
+				</operation>
+				<operation>
+					<id>1</id>
+					<returnType>vec4</returnType>
+					<function>getTangent</function>
+				</operation>
+				<operation>
+					<id>2</id>
+					<returnType>vec2</returnType>
+					<function>getTextureCoord</function>
+				</operation>
+
+				<operation>
+					<id>10</id>
+					<returnType>vec3</returnType>
 					<function>readRgbFromTexture</function>
 					<function>readRgbFromTexture</function>
 					<arguments>
 					<arguments>
 						<argument>diffuseMap</argument>
 						<argument>diffuseMap</argument>
-						<argument>vTexCoords</argument>
+						<argument>out2</argument>
 					</arguments>
 					</arguments>
 				</operation>
 				</operation>
 				<operation>
 				<operation>
-					<id>1</id>
+					<id>20</id>
 					<returnType>vec3</returnType>
 					<returnType>vec3</returnType>
 					<function>getNormalFromTexture</function>
 					<function>getNormalFromTexture</function>
 					<arguments>
 					<arguments>
-						<argument>vNormal</argument>
-						<argument>vTangent</argument>
+						<argument>out0</argument>
+						<argument>out1</argument>
 						<argument>normalMap</argument>
 						<argument>normalMap</argument>
-						<argument>vTexCoords</argument>
+						<argument>out2</argument>
 					</arguments>
 					</arguments>
 				</operation>
 				</operation>
 				<operation>
 				<operation>
-					<id>2</id>
+					<id>30</id>
 					<returnType>void</returnType>
 					<returnType>void</returnType>
 					<function>writeFais</function>
 					<function>writeFais</function>
 					<arguments>
 					<arguments>
-						<argument>out0</argument>
-						<argument>out1</argument>
+						<argument>out10</argument>
+						<argument>out20</argument>
 						<argument>specular</argument>
 						<argument>specular</argument>
-						<argument>0.0</argument>
+						<argument>blurring</argument>
 					</arguments>
 					</arguments>
 				</operation>
 				</operation>
 			</operations>
 			</operations>

+ 16 - 11
tools/scene/diffTemplateMtl.h

@@ -7,6 +7,7 @@ R"(<?xml version="1.0" encoding="UTF-8" ?>
 			<input><type>mat3</type><name>normalMat</name><value></value><instanced>%instanced%</instanced></input>
 			<input><type>mat3</type><name>normalMat</name><value></value><instanced>%instanced%</instanced></input>
 
 
 			<input><type>vec2</type><name>specular</name><value>1.0 90.0</value></input>
 			<input><type>vec2</type><name>specular</name><value>1.0 90.0</value></input>
+			<input><type>float</type><name>blurring</name><value>0.0</value><const>1</const></input>
 			<input><type>sampler2D</type><name>diffuseMap</name><value>%diffuseMap%</value></input>
 			<input><type>sampler2D</type><name>diffuseMap</name><value>%diffuseMap%</value></input>
 		</inputs>
 		</inputs>
 
 
@@ -36,30 +37,34 @@ R"(<?xml version="1.0" encoding="UTF-8" ?>
 			<operations>
 			<operations>
 				<operation>
 				<operation>
 					<id>0</id>
 					<id>0</id>
-					<returnType>vec3</returnType>
-					<function>readRgbFromTexture</function>
-					<arguments>
-						<argument>diffuseMap</argument>
-						<argument>vTexCoords</argument>
-					</arguments>
+					<returnType>vec2</returnType>
+					<function>getTextureCoord</function>
 				</operation>
 				</operation>
 				<operation>
 				<operation>
 					<id>1</id>
 					<id>1</id>
 					<returnType>vec3</returnType>
 					<returnType>vec3</returnType>
-					<function>getNormalSimple</function>
+					<function>getNormal</function>
+				</operation>
+
+				<operation>
+					<id>10</id>
+					<returnType>vec3</returnType>
+					<function>readRgbFromTexture</function>
 					<arguments>
 					<arguments>
-						<argument>vNormal</argument>
+						<argument>diffuseMap</argument>
+						<argument>out0</argument>
 					</arguments>
 					</arguments>
 				</operation>
 				</operation>
+
 				<operation>
 				<operation>
-					<id>2</id>
+					<id>20</id>
 					<returnType>void</returnType>
 					<returnType>void</returnType>
 					<function>writeFais</function>
 					<function>writeFais</function>
 					<arguments>
 					<arguments>
-						<argument>out0</argument>
+						<argument>out10</argument>
 						<argument>out1</argument>
 						<argument>out1</argument>
 						<argument>specular</argument>
 						<argument>specular</argument>
-						<argument>0.0</argument>
+						<argument>blurring</argument>
 					</arguments>
 					</arguments>
 				</operation>
 				</operation>
 			</operations>
 			</operations>