}
}
+//=======================================================================================================================================================
+
static const char *builtinshaderstring =
"// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
"// written by Forest 'LordHavoc' Hale\n"
+"// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
+"\n"
+"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE)\n"
+"# define USEFOG\n"
+"#endif\n"
+"#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
+"#define USELIGHTMAP\n"
+"#endif\n"
+"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING)\n"
+"#define USEEYEVECTOR\n"
+"#endif\n"
+"\n"
+"#if defined(USESHADOWMAPRECT) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USEDEFERREDLIGHTMAP)\n"
+"# extension GL_ARB_texture_rectangle : enable\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAP2D\n"
+"# ifdef GL_EXT_gpu_shader4\n"
+"# extension GL_EXT_gpu_shader4 : enable\n"
+"# endif\n"
+"# ifdef GL_ARB_texture_gather\n"
+"# extension GL_ARB_texture_gather : enable\n"
+"# else\n"
+"# ifdef GL_AMD_texture_texture4\n"
+"# extension GL_AMD_texture_texture4 : enable\n"
+"# endif\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAPCUBE\n"
+"# extension GL_EXT_gpu_shader4 : enable\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWSAMPLER\n"
+"# extension GL_ARB_shadow : enable\n"
+"#endif\n"
"\n"
-"// enable various extensions depending on permutation:\n"
+"//#ifdef __GLSL_CG_DATA_TYPES\n"
+"//# define myhalf half\n"
+"//# define myhalf2 half2\n"
+"//# define myhalf3 half3\n"
+"//# define myhalf4 half4\n"
+"//#else\n"
+"# define myhalf float\n"
+"# define myhalf2 vec2\n"
+"# define myhalf3 vec3\n"
+"# define myhalf4 vec4\n"
+"//#endif\n"
"\n"
"#ifdef VERTEX_SHADER\n"
"uniform mat4 ModelViewProjectionMatrix;\n"
"}\n"
"#endif\n"
"#else // !MODE_DEPTH_ORSHADOW\n"
+"\n"
+"\n"
+"\n"
+"\n"
"#ifdef MODE_SHOWDEPTH\n"
"#ifdef VERTEX_SHADER\n"
"void main(void)\n"
"}\n"
"#endif\n"
"#else // !MODE_SHOWDEPTH\n"
+"\n"
+"\n"
+"\n"
+"\n"
"#ifdef MODE_POSTPROCESS\n"
"varying vec2 TexCoord1;\n"
"varying vec2 TexCoord2;\n"
"}\n"
"#endif\n"
"#else // !MODE_POSTPROCESS\n"
+"\n"
+"\n"
+"\n"
+"\n"
"#ifdef MODE_GENERIC\n"
"#ifdef USEDIFFUSE\n"
"varying vec2 TexCoord1;\n"
"}\n"
"#endif\n"
"#else // !MODE_GENERIC\n"
+"\n"
+"\n"
+"\n"
+"\n"
"#ifdef MODE_BLOOMBLUR\n"
"varying TexCoord;\n"
"#ifdef VERTEX_SHADER\n"
"}\n"
"#endif\n"
"#else // !MODE_REFRACTION\n"
+"\n"
+"\n"
+"\n"
+"\n"
"#ifdef MODE_WATER\n"
"varying vec2 TexCoord;\n"
"varying vec3 EyeVector;\n"
"#endif\n"
"#else // !MODE_WATER\n"
"\n"
-"#if defined(USESHADOWMAPRECT) || defined(MODE_DEFERREDLIGHTSOURCE) || defined(USEDEFERREDLIGHTMAP)\n"
-"# extension GL_ARB_texture_rectangle : enable\n"
-"#endif\n"
-"\n"
-"#ifdef USESHADOWMAP2D\n"
-"# ifdef GL_EXT_gpu_shader4\n"
-"# extension GL_EXT_gpu_shader4 : enable\n"
-"# endif\n"
-"# ifdef GL_ARB_texture_gather\n"
-"# extension GL_ARB_texture_gather : enable\n"
-"# else\n"
-"# ifdef GL_AMD_texture_texture4\n"
-"# extension GL_AMD_texture_texture4 : enable\n"
-"# endif\n"
-"# endif\n"
-"#endif\n"
"\n"
-"#ifdef USESHADOWMAPCUBE\n"
-"# extension GL_EXT_gpu_shader4 : enable\n"
-"#endif\n"
"\n"
-"#ifdef USESHADOWSAMPLER\n"
-"# extension GL_ARB_shadow : enable\n"
-"#endif\n"
"\n"
"// common definitions between vertex shader and fragment shader:\n"
"\n"
-"//#ifdef __GLSL_CG_DATA_TYPES\n"
-"//# define myhalf half\n"
-"//# define myhalf2 half2\n"
-"//# define myhalf3half3\n"
-"//# define myhalf4 half4\n"
-"//#else\n"
-"# define myhalf float\n"
-"# define myhalf2 vec2\n"
-"# define myhalf3 vec3\n"
-"# define myhalf4 vec4\n"
-"//#endif\n"
-"\n"
-"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE)\n"
-"# define USEFOG\n"
-"#endif\n"
-"\n"
"varying vec2 TexCoord;\n"
"#ifdef USEVERTEXTEXTUREBLEND\n"
"varying vec2 TexCoord2;\n"
"#endif\n"
-"#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
-"#define USELIGHTMAP\n"
+"#ifdef USELIGHTMAP\n"
"varying vec2 TexCoordLightmap;\n"
"#endif\n"
"\n"
"varying vec3 LightVector;\n"
"#endif\n"
"\n"
-"#if defined(USEOFFSETMAPPING) || defined(USESPECULAR)\n"
-"//#if defined(USEOFFSETMAPPING) || defined(USESPECULAR) || defined(MODE_LIGHTDIRECTION) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
-"#define USEEYEVECTOR\n"
+"#ifdef USEEYEVECTOR\n"
"varying vec3 EyeVector;\n"
"#endif\n"
"#ifdef USEFOG\n"
-"varying vec3 EyeVectorModelSpace;\n"
-"varying float FogPlaneVertexDist;\n"
+"varying vec4 EyeVectorModelSpaceFogPlaneVertexDist;\n"
"#endif\n"
"\n"
"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY)\n"
"\n"
"\n"
"\n"
-"// vertex shader specific:\n"
-"#ifdef VERTEX_SHADER\n"
-"\n"
"// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3), this would require sending a 4 component texcoord1 with W as 1 or -1 according to which side the texcoord2 should be on\n"
"\n"
-"#ifdef MODE_DEFERREDGEOMETRY\n"
-"uniform mat4 TexMatrix;\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"uniform mat4 BackgroundTexMatrix;\n"
-"#endif\n"
-"uniform mat4 ModelViewMatrix;\n"
-"void main(void)\n"
-"{\n"
-" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" gl_FrontColor = gl_Color;\n"
-" TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
-"#endif\n"
-"\n"
-" // transform unnormalized eye direction into tangent space\n"
-"#ifdef USEOFFSETMAPPING\n"
-" vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
-" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
-" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-" VectorS = (ModelViewMatrix * vec4(gl_MultiTexCoord1.xyz, 0)).xyz;\n"
-" VectorT = (ModelViewMatrix * vec4(gl_MultiTexCoord2.xyz, 0)).xyz;\n"
-" VectorR = (ModelViewMatrix * vec4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"}\n"
-"#else // !MODE_DEFERREDGEOMETRY\n"
-"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
-"uniform mat4 ModelViewMatrix;\n"
-"void main(void)\n"
-"{\n"
-" ModelViewPosition = ModelViewMatrix * gl_Vertex;\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"}\n"
-"#else // !MODE_DEFERREDLIGHTSOURCE\n"
-"uniform mat4 TexMatrix;\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-"uniform mat4 BackgroundTexMatrix;\n"
-"#endif\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-"uniform mat4 ModelToLight;\n"
-"#endif\n"
-"void main(void)\n"
-"{\n"
-"#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
-" gl_FrontColor = gl_Color;\n"
-"#endif\n"
-" // copy the surface texcoord\n"
-" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
-"#ifdef USEVERTEXTEXTUREBLEND\n"
-" TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
-"#endif\n"
-"#ifdef USELIGHTMAP\n"
-" TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_LIGHTSOURCE\n"
-" // transform vertex position into light attenuation/cubemap space\n"
-" // (-1 to +1 across the light box)\n"
-" CubeVector = vec3(ModelToLight * gl_Vertex);\n"
-"\n"
-"# ifdef USEDIFFUSE\n"
-" // transform unnormalized light direction into tangent space\n"
-" // (we use unnormalized to ensure that it interpolates correctly and then\n"
-" // normalize it per pixel)\n"
-" vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
-" LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
-" LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
-" LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
-"# endif\n"
-"#endif\n"
-"\n"
-"#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
-" LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
-" LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
-" LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-" // transform unnormalized eye direction into tangent space\n"
-"#ifdef USEEYEVECTOR\n"
-"#ifndef USEFOG\n"
-" vec3 EyeVectorModelSpace;\n"
-"#endif\n"
-" EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
-" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
-" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
-"#endif\n"
-"\n"
-"#ifdef USEFOG\n"
-"#ifndef USEEYEVECTOR\n"
-" EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
-"#endif\n"
-" FogPlaneVertexDist = dot(FogPlane, gl_Vertex);\n"
-"#endif\n"
-"\n"
-"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
-" VectorS = gl_MultiTexCoord1.xyz;\n"
-" VectorT = gl_MultiTexCoord2.xyz;\n"
-" VectorR = gl_MultiTexCoord3.xyz;\n"
-"#endif\n"
-"\n"
-" // transform vertex to camera space, using ftransform to match non-VS rendering\n"
-" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
-"\n"
-"#ifdef USEREFLECTION\n"
-" ModelViewProjectionPosition = gl_Position;\n"
-"#endif\n"
-"}\n"
-"#endif // !MODE_DEFERREDLIGHTSOURCE\n"
-"#endif // !MODE_DEFERREDGEOMETRY\n"
-"\n"
-"#endif // VERTEX_SHADER\n"
-"\n"
-"\n"
-"\n"
-"\n"
"// fragment shader specific:\n"
"#ifdef FRAGMENT_SHADER\n"
"\n"
"uniform float FogRangeRecip;\n"
"uniform float FogPlaneViewDist;\n"
"uniform float FogHeightFade;\n"
-"myhalf FogVertex(void)\n"
+"float FogVertex(void)\n"
"{\n"
+" vec3 EyeVectorModelSpace = EyeVectorModelSpaceFogPlaneVertexDist.xyz;\n"
+" float FogPlaneVertexDist = EyeVectorModelSpaceFogPlaneVertexDist.w;\n"
" float fogfrac;\n"
"#ifdef USEFOGOUTSIDE\n"
" fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
"#else\n"
" fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
"#endif\n"
-" return myhalf(texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)));\n"
+" return float(texture2D(Texture_FogMask, myhalf2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)));\n"
"}\n"
"#endif\n"
"\n"
"#endif\n"
"\n"
"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
+"# ifndef USESHADOWMAPVSDCT\n"
"vec3 GetShadowMapTC2D(vec3 dir)\n"
"{\n"
" vec3 adir = abs(dir);\n"
-"# ifndef USESHADOWMAPVSDCT\n"
" vec2 tc;\n"
" vec2 offset;\n"
" float ma;\n"
" stc.xy += offset * ShadowMap_Parameters.y;\n"
" stc.z += ShadowMap_Parameters.z;\n"
" return stc;\n"
+"}\n"
"# else\n"
+"vec3 GetShadowMapTC2D(vec3 dir)\n"
+"{\n"
+" vec3 adir = abs(dir);\n"
" vec4 proj = textureCube(Texture_CubeProjection, dir);\n"
" float ma = max(max(adir.x, adir.y), adir.z);\n"
" vec3 stc = vec3(mix(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
" stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
" stc.z += ShadowMap_Parameters.z;\n"
" return stc;\n"
-"# endif\n"
"}\n"
+"# endif\n"
"#endif // defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
"\n"
"#ifdef USESHADOWMAPCUBE\n"
"vec4 GetShadowMapTCCube(vec3 dir)\n"
"{\n"
-" vec3 adir = abs(dir);\n"
-" return vec4(dir, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n"
+" vec3 adir = abs(dir);\n"
+" return vec4(dir, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n"
"}\n"
"#endif\n"
"\n"
"\n"
"# ifdef USESHADOWMAPPCF\n"
"# define texval(x, y) shadow2DRect(Texture_ShadowMapRect, shadowmaptc + vec3(x, y, 0.0)).r\n"
-" f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
+" f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
"# else\n"
-" f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n"
+" f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n"
"# endif\n"
"\n"
"# else\n"
"# ifdef USESHADOWMAPPCF\n"
"# if USESHADOWMAPPCF > 1\n"
"# define texval(x, y) texture2DRect(Texture_ShadowMapRect, center + vec2(x, y)).r\n"
-" vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
-" vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
-" vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0)));\n"
-" vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0)));\n"
-" vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0)));\n"
-" vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
-" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
+" vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+" vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
+" vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0)));\n"
+" vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0)));\n"
+" vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0)));\n"
+" vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
+" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
"# else\n"
"# define texval(x, y) texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy + vec2(x, y)).r\n"
-" vec2 offset = fract(shadowmaptc.xy);\n"
-" vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
-" vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
-" vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
-" vec3 cols = row2 + mix(row1, row3, offset.y);\n"
-" f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
+" vec2 offset = fract(shadowmaptc.xy);\n"
+" vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
+" vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
+" vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
+" vec3 cols = row2 + mix(row1, row3, offset.y);\n"
+" f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
"# endif\n"
"# else\n"
-" f = step(shadowmaptc.z, texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
+" f = step(shadowmaptc.z, texture2DRect(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
"# endif\n"
"\n"
"# endif\n"
"# ifdef USESHADOWMAP2D\n"
"float ShadowMapCompare(vec3 dir)\n"
"{\n"
-" vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
-" float f;\n"
+" vec3 shadowmaptc = GetShadowMapTC2D(dir);\n"
+" float f;\n"
"\n"
"# ifdef USESHADOWSAMPLER\n"
"# ifdef USESHADOWMAPPCF\n"
"# define texval(x, y) shadow2D(Texture_ShadowMap2D, vec3(center + vec2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)).r \n"
-" vec2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
-" f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
+" vec2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
+" f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
"# else\n"
-" f = shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
+" f = shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
"# endif\n"
"# else\n"
"# ifdef USESHADOWMAPPCF\n"
"# else\n"
"# define texval(x, y) texture4(Texture_ShadowMap2D, center + vec2(x,y)*ShadowMap_TextureScale)\n"
"# endif\n"
-" vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
-" center *= ShadowMap_TextureScale;\n"
-" vec4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
-" vec4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
-" vec4 group3 = step(shadowmaptc.z, texval(-1.0, 1.0));\n"
-" vec4 group4 = step(shadowmaptc.z, texval( 1.0, 1.0));\n"
-" vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) +\n"
-" mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);\n"
-" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
+" vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+" center *= ShadowMap_TextureScale;\n"
+" vec4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
+" vec4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
+" vec4 group3 = step(shadowmaptc.z, texval(-1.0, 1.0));\n"
+" vec4 group4 = step(shadowmaptc.z, texval( 1.0, 1.0));\n"
+" vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) +\n"
+" mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);\n"
+" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
"# else\n"
"# ifdef GL_EXT_gpu_shader4\n"
"# define texval(x, y) texture2DOffset(Texture_ShadowMap2D, center, ivec2(x, y)).r\n"
"# define texval(x, y) texture2D(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale).r \n"
"# endif\n"
"# if USESHADOWMAPPCF > 1\n"
-" vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
-" center *= ShadowMap_TextureScale;\n"
-" vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
-" vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0)));\n"
-" vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0)));\n"
-" vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0)));\n"
-" vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
-" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
+" vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+" center *= ShadowMap_TextureScale;\n"
+" vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
+" vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0)));\n"
+" vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0)));\n"
+" vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0)));\n"
+" vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
+" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n"
"# else\n"
-" vec2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n"
-" vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
-" vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
-" vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
-" vec3 cols = row2 + mix(row1, row3, offset.y);\n"
-" f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
+" vec2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n"
+" vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
+" vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
+" vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
+" vec3 cols = row2 + mix(row1, row3, offset.y);\n"
+" f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n"
"# endif\n"
"# endif\n"
"# else\n"
-" f = step(shadowmaptc.z, texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
+" f = step(shadowmaptc.z, texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
"# endif\n"
"# endif\n"
-" return f;\n"
+" return f;\n"
"}\n"
"# endif\n"
"\n"
"# ifdef USESHADOWMAPCUBE\n"
"float ShadowMapCompare(vec3 dir)\n"
"{\n"
-" // apply depth texture cubemap as light filter\n"
-" vec4 shadowmaptc = GetShadowMapTCCube(dir);\n"
-" float f;\n"
+" // apply depth texture cubemap as light filter\n"
+" vec4 shadowmaptc = GetShadowMapTCCube(dir);\n"
+" float f;\n"
"# ifdef USESHADOWSAMPLER\n"
-" f = shadowCube(Texture_ShadowMapCube, shadowmaptc).r;\n"
+" f = shadowCube(Texture_ShadowMapCube, shadowmaptc).r;\n"
"# else\n"
-" f = step(shadowmaptc.w, textureCube(Texture_ShadowMapCube, shadowmaptc.xyz).r);\n"
+" f = step(shadowmaptc.w, textureCube(Texture_ShadowMapCube, shadowmaptc.xyz).r);\n"
"# endif\n"
-" return f;\n"
+" return f;\n"
"}\n"
"# endif\n"
"#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"#endif // FRAGMENT_SHADER\n"
+"\n"
+"\n"
+"\n"
"\n"
"#ifdef MODE_DEFERREDGEOMETRY\n"
+"#ifdef VERTEX_SHADER\n"
+"uniform mat4 TexMatrix;\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform mat4 BackgroundTexMatrix;\n"
+"#endif\n"
+"uniform mat4 ModelViewMatrix;\n"
"void main(void)\n"
"{\n"
-"#ifdef USEOFFSETMAPPING\n"
-" // apply offsetmapping\n"
+" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+" gl_FrontColor = gl_Color;\n"
+" TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
+"#endif\n"
+"\n"
+" // transform unnormalized eye direction into tangent space\n"
+"#ifdef USEOFFSETMAPPING\n"
+" vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
+" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
+" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
+" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+" VectorS = (ModelViewMatrix * vec4(gl_MultiTexCoord1.xyz, 0)).xyz;\n"
+" VectorT = (ModelViewMatrix * vec4(gl_MultiTexCoord2.xyz, 0)).xyz;\n"
+" VectorR = (ModelViewMatrix * vec4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
+" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main(void)\n"
+"{\n"
+"#ifdef USEOFFSETMAPPING\n"
+" // apply offsetmapping\n"
" vec2 TexCoordOffset = OffsetMapping(TexCoord);\n"
"#define TexCoord TexCoordOffset\n"
"#endif\n"
"\n"
" gl_FragColor = vec4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + vec3(0.5, 0.5, 0.5), 1);\n"
"}\n"
+"#endif // FRAGMENT_SHADER\n"
"#else // !MODE_DEFERREDGEOMETRY\n"
+"\n"
+"\n"
+"\n"
+"\n"
"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
+"#ifdef VERTEX_SHADER\n"
+"uniform mat4 ModelViewMatrix;\n"
+"void main(void)\n"
+"{\n"
+" ModelViewPosition = ModelViewMatrix * gl_Vertex;\n"
+" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
"uniform mat4 ViewToLight;\n"
"// ScreenToDepth = vec2(Far / (Far - Near), Far * Near / (Near - Far));\n"
"uniform vec2 ScreenToDepth;\n"
" gl_FragData[1] *= cubecolor;\n"
"# endif\n"
"}\n"
+"#endif // FRAGMENT_SHADER\n"
"#else // !MODE_DEFERREDLIGHTSOURCE\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef VERTEX_SHADER\n"
+"uniform mat4 TexMatrix;\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform mat4 BackgroundTexMatrix;\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"uniform mat4 ModelToLight;\n"
+"#endif\n"
+"void main(void)\n"
+"{\n"
+"#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
+" gl_FrontColor = gl_Color;\n"
+"#endif\n"
+" // copy the surface texcoord\n"
+" TexCoord = vec2(TexMatrix * gl_MultiTexCoord0);\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+" TexCoord2 = vec2(BackgroundTexMatrix * gl_MultiTexCoord0);\n"
+"#endif\n"
+"#ifdef USELIGHTMAP\n"
+" TexCoordLightmap = vec2(gl_MultiTexCoord4);\n"
+"#endif\n"
+"\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+" // transform vertex position into light attenuation/cubemap space\n"
+" // (-1 to +1 across the light box)\n"
+" CubeVector = vec3(ModelToLight * gl_Vertex);\n"
+"\n"
+"# ifdef USEDIFFUSE\n"
+" // transform unnormalized light direction into tangent space\n"
+" // (we use unnormalized to ensure that it interpolates correctly and then\n"
+" // normalize it per pixel)\n"
+" vec3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
+" LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
+" LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
+" LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
+" LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
+" LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
+" LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+" // transform unnormalized eye direction into tangent space\n"
+"#ifdef USEEYEVECTOR\n"
+" vec3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
+" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
+" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
+" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+"#ifdef USEFOG\n"
+" EyeVectorModelSpaceFogPlaneVertexDist.xyz = EyePosition - gl_Vertex.xyz;\n"
+" EyeVectorModelSpaceFogPlaneVertexDist.w = dot(FogPlane, gl_Vertex);\n"
+"#endif\n"
+"\n"
+"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
+" VectorS = gl_MultiTexCoord1.xyz;\n"
+" VectorT = gl_MultiTexCoord2.xyz;\n"
+" VectorR = gl_MultiTexCoord3.xyz;\n"
+"#endif\n"
+"\n"
+" // transform vertex to camera space, using ftransform to match non-VS rendering\n"
+" gl_Position = ModelViewProjectionMatrix * gl_Vertex;\n"
+"\n"
+"#ifdef USEREFLECTION\n"
+" ModelViewProjectionPosition = gl_Position;\n"
+"#endif\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
"#ifdef USEDEFERREDLIGHTMAP\n"
"uniform myhalf3 DeferredMod_Diffuse;\n"
"uniform myhalf3 DeferredMod_Specular;\n"
"#endif\n"
"\n"
"#ifdef USEFOG\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+" color.rgb *= myhalf(FogVertex());\n"
+"#else\n"
" color.rgb = mix(FogColor, color.rgb, FogVertex());\n"
"#endif\n"
+"#endif\n"
"\n"
" // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n"
"#ifdef USEREFLECTION\n"
"\n"
" gl_FragColor = vec4(color);\n"
"}\n"
+"#endif // FRAGMENT_SHADER\n"
+"\n"
"#endif // !MODE_DEFERREDLIGHTSOURCE\n"
"#endif // !MODE_DEFERREDGEOMETRY\n"
+"#endif // !MODE_WATER\n"
+"#endif // !MODE_REFRACTION\n"
+"#endif // !MODE_BLOOMBLUR\n"
+"#endif // !MODE_GENERIC\n"
+"#endif // !MODE_POSTPROCESS\n"
+"#endif // !MODE_SHOWDEPTH\n"
+"#endif // !MODE_DEPTH_OR_SHADOW\n"
+;
+
+/*
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+
+
+
+=========================================================================================================================================================
+*/
+
+const char *builtincgshaderstring =
+"// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
+"// written by Forest 'LordHavoc' Hale\n"
+"// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
"\n"
-"#endif // FRAGMENT_SHADER\n"
+"#if defined(USEFOGINSIDE) || defined(USEFOGOUTSIDE)\n"
+"# define USEFOG\n"
+"#endif\n"
+"#if defined(MODE_LIGHTMAP) || defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
+"#define USELIGHTMAP\n"
+"#endif\n"
+"#if defined(USESPECULAR) || defined(USEOFFSETMAPPING)\n"
+"#define USEEYEVECTOR\n"
+"#endif\n"
+"\n"
+"#ifdef MODE_DEPTH_OR_SHADOW\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"out float4 gl_Position : POSITION\n"
+")\n"
+"{\n"
+" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_DEPTH_ORSHADOW\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_SHOWDEPTH\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float4 gl_FrontColor : COLOR0\n"
+")\n"
+"{\n"
+" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+" gl_FrontColor = float4(gl_Position.z, gl_Position.z, gl_Position.z, 1.0);\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_FrontColor : COLOR0,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+" gl_FragColor = gl_FrontColor;\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_SHOWDEPTH\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_POSTPROCESS\n"
+"\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float2 TexCoord1 : TEXCOORD0,\n"
+"out float2 TexCoord2 : TEXCOORD1\n"
+")\n"
+"{\n"
+" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+" TexCoord1 = gl_MultiTexCoord0.xy;\n"
+"#ifdef USEBLOOM\n"
+" TexCoord2 = gl_MultiTexCoord1.xy;\n"
+"#endif\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float2 TexCoord1 : TEXCOORD0,\n"
+"float2 TexCoord2 : TEXCOORD1,\n"
+"uniform sampler2D Texture_First,\n"
+"#ifdef USEBLOOM\n"
+"uniform sampler2D Texture_Second,\n"
+"#endif\n"
+"#ifdef USEGAMMARAMPS\n"
+"uniform sampler2D Texture_GammaRamps,\n"
+"#endif\n"
+"#ifdef USESATURATION\n"
+"uniform float Saturation,\n"
+"#endif\n"
+"#ifdef USEVIEWTINT\n"
+"uniform float4 ViewTintColor,\n"
+"#endif\n"
+"uniform float4 UserVec1,\n"
+"uniform float4 UserVec2,\n"
+"uniform float4 UserVec3,\n"
+"uniform float4 UserVec4,\n"
+"uniform float ClientTime,\n"
+"uniform float2 PixelSize,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+" gl_FragColor = tex2D(Texture_First, TexCoord1);\n"
+"#ifdef USEBLOOM\n"
+" gl_FragColor += tex2D(Texture_Second, TexCoord2);\n"
+"#endif\n"
+"#ifdef USEVIEWTINT\n"
+" gl_FragColor = mix(gl_FragColor, ViewTintColor, ViewTintColor.a);\n"
+"#endif\n"
+"\n"
+"#ifdef USEPOSTPROCESSING\n"
+"// do r_glsl_dumpshader, edit glsl/default.glsl, and replace this by your own postprocessing if you want\n"
+"// this code does a blur with the radius specified in the first component of r_glsl_postprocess_uservec1 and blends it using the second component\n"
+" gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.987688, -0.156434)) * UserVec1.y;\n"
+" gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.156434, -0.891007)) * UserVec1.y;\n"
+" gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2( 0.891007, -0.453990)) * UserVec1.y;\n"
+" gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2( 0.707107, 0.707107)) * UserVec1.y;\n"
+" gl_FragColor += tex2D(Texture_First, TexCoord1 + PixelSize*UserVec1.x*float2(-0.453990, 0.891007)) * UserVec1.y;\n"
+" gl_FragColor /= (1 + 5 * UserVec1.y);\n"
+"#endif\n"
"\n"
+"#ifdef USESATURATION\n"
+" //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
+" float y = dot(gl_FragColor.rgb, float3(0.299, 0.587, 0.114));\n"
+" //gl_FragColor = float3(y) + (gl_FragColor.rgb - float3(y)) * Saturation;\n"
+" gl_FragColor.rgb = mix(float3(y), gl_FragColor.rgb, Saturation);\n"
+"#endif\n"
+"\n"
+"#ifdef USEGAMMARAMPS\n"
+" gl_FragColor.r = tex2D(Texture_GammaRamps, float2(gl_FragColor.r, 0)).r;\n"
+" gl_FragColor.g = tex2D(Texture_GammaRamps, float2(gl_FragColor.g, 0)).g;\n"
+" gl_FragColor.b = tex2D(Texture_GammaRamps, float2(gl_FragColor.b, 0)).b;\n"
+"#endif\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_POSTPROCESS\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_GENERIC\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"float4 gl_Color : COLOR0,\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float4 gl_FrontColor : COLOR,\n"
+"out float2 TexCoord1 : TEXCOORD0,\n"
+"out float2 TexCoord2 : TEXCOORD1\n"
+")\n"
+"{\n"
+" gl_FrontColor = gl_Color;\n"
+"#ifdef USEDIFFUSE\n"
+" TexCoord1 = gl_MultiTexCoord0.xy;\n"
+"#endif\n"
+"#ifdef USESPECULAR\n"
+" TexCoord2 = gl_MultiTexCoord1.xy;\n"
+"#endif\n"
+" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"\n"
+"void main\n"
+"(\n"
+"float4 gl_FrontColor : COLOR,\n"
+"float2 TexCoord1 : TEXCOORD0,\n"
+"float2 TexCoord2 : TEXCOORD1,\n"
+"#ifdef USEDIFFUSE\n"
+"uniform sampler2D Texture_First,\n"
+"#endif\n"
+"#ifdef USESPECULAR\n"
+"uniform sampler2D Texture_Second,\n"
+"#endif\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+" gl_FragColor = gl_FrontColor;\n"
+"#ifdef USEDIFFUSE\n"
+" gl_FragColor *= tex2D(Texture_First, TexCoord1);\n"
+"#endif\n"
+"\n"
+"#ifdef USESPECULAR\n"
+" float4 tex2 = tex2D(Texture_Second, TexCoord2);\n"
+"# ifdef USECOLORMAPPING\n"
+" gl_FragColor *= tex2;\n"
+"# endif\n"
+"# ifdef USEGLOW\n"
+" gl_FragColor += tex2;\n"
+"# endif\n"
+"# ifdef USEVERTEXTEXTUREBLEND\n"
+" gl_FragColor = mix(gl_FragColor, tex2, tex2.a);\n"
+"# endif\n"
+"#endif\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_GENERIC\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_BLOOMBLUR\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float2 TexCoord : TEXCOORD0\n"
+")\n"
+"{\n"
+" TexCoord = gl_MultiTexCoord0.xy;\n"
+" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"\n"
+"void main\n"
+"(\n"
+"float2 TexCoord : TEXCOORD0,\n"
+"uniform sampler2D Texture_First,\n"
+"uniform float4 BloomBlur_Parameters,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+" int i;\n"
+" float2 tc = TexCoord;\n"
+" float3 color = tex2D(Texture_First, tc).rgb;\n"
+" tc += BloomBlur_Parameters.xy;\n"
+" for (i = 1;i < SAMPLES;i++)\n"
+" {\n"
+" color += tex2D(Texture_First, tc).rgb;\n"
+" tc += BloomBlur_Parameters.xy;\n"
+" }\n"
+" gl_FragColor = float4(color * BloomBlur_Parameters.z + float3(BloomBlur_Parameters.w), 1);\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_BLOOMBLUR\n"
+"#ifdef MODE_REFRACTION\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"uniform mat4 TexMatrix,\n"
+"uniform float3 EyePosition,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float2 TexCoord : TEXCOORD0,\n"
+"out float3 EyeVector : TEXCOORD1,\n"
+"out float4 ModelViewProjectionPosition : TEXCOORD2\n"
+")\n"
+"{\n"
+" TexCoord = float2(mul(TexMatrix, gl_MultiTexCoord0));\n"
+" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+" ModelViewProjectionPosition = gl_Position;\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float2 TexCoord : TEXCOORD0,\n"
+"float3 EyeVector : TEXCOORD1,\n"
+"float4 ModelViewProjectionPosition : TEXCOORD2,\n"
+"uniform sampler2D Texture_Normal,\n"
+"uniform sampler2D Texture_Refraction,\n"
+"uniform sampler2D Texture_Reflection,\n"
+"uniform float4 DistortScaleRefractReflect,\n"
+"uniform float4 ScreenScaleRefractReflect,\n"
+"uniform float4 ScreenCenterRefractReflect,\n"
+"uniform float4 RefractColor,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+" float2 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect.xy * (1.0 / ModelViewProjectionPosition.w);\n"
+" //float2 ScreenTexCoord = (ModelViewProjectionPosition.xy + normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5)).xy * DistortScaleRefractReflect.xy * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
+" float2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect.xy;\n"
+" float2 ScreenTexCoord = SafeScreenTexCoord + float2(normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5))).xy * DistortScaleRefractReflect.xy;\n"
+" // FIXME temporary hack to detect the case that the reflection\n"
+" // gets blackened at edges due to leaving the area that contains actual\n"
+" // content.\n"
+" // Remove this 'ack once we have a better way to stop this thing from\n"
+" // 'appening.\n"
+" float f = min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(0.01, 0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(0.01, -0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(-0.01, 0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord + float2(-0.01, -0.01)).rgb) / 0.05);\n"
+" ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
+" gl_FragColor = tex2D(Texture_Refraction, ScreenTexCoord) * RefractColor;\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_REFRACTION\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_WATER\n"
+"#ifdef VERTEX_SHADER\n"
+"\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"uniform mat4 TexMatrix,\n"
+"uniform float3 EyePosition,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float2 TexCoord : TEXCOORD0,\n"
+"out float3 EyeVector : TEXCOORD1,\n"
+"out float4 ModelViewProjectionPosition : TEXCOORD2\n"
+")\n"
+"{\n"
+" TexCoord = float2(mul(TexMatrix, gl_MultiTexCoord0));\n"
+" float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
+" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
+" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
+" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
+" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+" ModelViewProjectionPosition = gl_Position;\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float2 TexCoord : TEXCOORD0,\n"
+"float3 EyeVector : TEXCOORD1,\n"
+"float4 ModelViewProjectionPosition : TEXCOORD2,\n"
+"uniform sampler2D Texture_Normal,\n"
+"uniform sampler2D Texture_Refraction,\n"
+"uniform sampler2D Texture_Reflection,\n"
+"uniform float4 DistortScaleRefractReflect,\n"
+"uniform float4 ScreenScaleRefractReflect,\n"
+"uniform float4 ScreenCenterRefractReflect,\n"
+"uniform float4 RefractColor,\n"
+"uniform float4 ReflectColor,\n"
+"uniform float ReflectFactor,\n"
+"uniform float ReflectOffset,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+" float4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
+" //float4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
+" float4 SafeScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
+" float4 ScreenTexCoord = SafeScreenTexCoord + float2(normalize(float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5))).xyxy * DistortScaleRefractReflect;\n"
+" // FIXME temporary hack to detect the case that the reflection\n"
+" // gets blackened at edges due to leaving the area that contains actual\n"
+" // content.\n"
+" // Remove this 'ack once we have a better way to stop this thing from\n"
+" // 'appening.\n"
+" float f = min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(0.01, 0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(0.01, -0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(-0.01, 0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Refraction, ScreenTexCoord.xy + float2(-0.01, -0.01)).rgb) / 0.05);\n"
+" ScreenTexCoord.xy = mix(SafeScreenTexCoord.xy, ScreenTexCoord.xy, f);\n"
+" f = min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(0.01, 0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(0.01, -0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(-0.01, 0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord.zw + float2(-0.01, -0.01)).rgb) / 0.05);\n"
+" ScreenTexCoord.zw = mix(SafeScreenTexCoord.zw, ScreenTexCoord.zw, f);\n"
+" float Fresnel = pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0) * ReflectFactor + ReflectOffset;\n"
+" gl_FragColor = mix(tex2D(Texture_Refraction, ScreenTexCoord.xy) * RefractColor, tex2D(Texture_Reflection, ScreenTexCoord.zw) * ReflectColor, Fresnel);\n"
+"}\n"
+"#endif\n"
+"#else // !MODE_WATER\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"// TODO: get rid of tangentt (texcoord2) and use a crossproduct to regenerate it from tangents (texcoord1) and normal (texcoord3), this would require sending a 4 component texcoord1 with W as 1 or -1 according to which side the texcoord2 should be on\n"
+"\n"
+"// fragment shader specific:\n"
+"#ifdef FRAGMENT_SHADER\n"
+"\n"
+"#ifdef USEFOG\n"
+"float FogVertex(float3 EyeVectorModelSpace, float FogPlaneVertexDist, float FogRangeRecip, float FogPlaneViewDist, float FogHeightFade, sampler2D Texture_FogMask)\n"
+"{\n"
+" float fogfrac;\n"
+"#ifdef USEFOGOUTSIDE\n"
+" fogfrac = min(0.0, FogPlaneVertexDist) / (FogPlaneVertexDist - FogPlaneViewDist) * min(1.0, min(0.0, FogPlaneVertexDist) * FogHeightFade);\n"
+"#else\n"
+" fogfrac = FogPlaneViewDist / (FogPlaneViewDist - max(0.0, FogPlaneVertexDist)) * min(1.0, (min(0.0, FogPlaneVertexDist) + FogPlaneViewDist) * FogHeightFade);\n"
+"#endif\n"
+" return float(tex2D(Texture_FogMask, half2(length(EyeVectorModelSpace)*fogfrac*FogRangeRecip, 0.0)));\n"
+"}\n"
+"#endif\n"
+"\n"
+"#ifdef USEOFFSETMAPPING\n"
+"float2 OffsetMapping(float2 TexCoord, float OffsetMapping_Scale, float3 EyeVector, sampler2D Texture_Normal)\n"
+"{\n"
+"#ifdef USEOFFSETMAPPING_RELIEFMAPPING\n"
+" // 14 sample relief mapping: linear search and then binary search\n"
+" // this basically steps forward a small amount repeatedly until it finds\n"
+" // itself inside solid, then jitters forward and back using decreasing\n"
+" // amounts to find the impact\n"
+" //float3 OffsetVector = float3(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * float2(-1, 1), -1);\n"
+" //float3 OffsetVector = float3(normalize(EyeVector.xy) * OffsetMapping_Scale * float2(-1, 1), -1);\n"
+" float3 OffsetVector = float3(normalize(EyeVector).xy * OffsetMapping_Scale * float2(-1, 1), -1);\n"
+" float3 RT = float3(TexCoord, 1);\n"
+" OffsetVector *= 0.1;\n"
+" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+" RT += OffsetVector * step(tex2D(Texture_Normal, RT.xy).a, RT.z);\n"
+" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) - 0.5);\n"
+" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.5 - 0.25);\n"
+" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.25 - 0.125);\n"
+" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.125 - 0.0625);\n"
+" RT += OffsetVector * (step(tex2D(Texture_Normal, RT.xy).a, RT.z) * 0.0625 - 0.03125);\n"
+" return RT.xy;\n"
+"#else\n"
+" // 3 sample offset mapping (only 3 samples because of ATI Radeon 9500-9800/X300 limits)\n"
+" // this basically moves forward the full distance, and then backs up based\n"
+" // on height of samples\n"
+" //float2 OffsetVector = float2(EyeVector.xy * ((1.0 / EyeVector.z) * OffsetMapping_Scale) * float2(-1, 1));\n"
+" //float2 OffsetVector = float2(normalize(EyeVector.xy) * OffsetMapping_Scale * float2(-1, 1));\n"
+" float2 OffsetVector = float2(normalize(EyeVector).xy * OffsetMapping_Scale * float2(-1, 1));\n"
+" TexCoord += OffsetVector;\n"
+" OffsetVector *= 0.333;\n"
+" TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
+" TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
+" TexCoord -= OffsetVector * tex2D(Texture_Normal, TexCoord).a;\n"
+" return TexCoord;\n"
+"#endif\n"
+"}\n"
+"#endif // USEOFFSETMAPPING\n"
+"\n"
+"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
+"# ifndef USESHADOWMAPVSDCT\n"
+"float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters)\n"
+"{\n"
+" float3 adir = abs(dir);\n"
+" float2 tc;\n"
+" float2 offset;\n"
+" float ma;\n"
+" if (adir.x > adir.y)\n"
+" {\n"
+" if (adir.x > adir.z) // X\n"
+" {\n"
+" ma = adir.x;\n"
+" tc = dir.zy;\n"
+" offset = float2(mix(0.5, 1.5, dir.x < 0.0), 0.5);\n"
+" }\n"
+" else // Z\n"
+" {\n"
+" ma = adir.z;\n"
+" tc = dir.xy;\n"
+" offset = float2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
+" }\n"
+" }\n"
+" else\n"
+" {\n"
+" if (adir.y > adir.z) // Y\n"
+" {\n"
+" ma = adir.y;\n"
+" tc = dir.xz;\n"
+" offset = float2(mix(0.5, 1.5, dir.y < 0.0), 1.5);\n"
+" }\n"
+" else // Z\n"
+" {\n"
+" ma = adir.z;\n"
+" tc = dir.xy;\n"
+" offset = float2(mix(0.5, 1.5, dir.z < 0.0), 2.5);\n"
+" }\n"
+" }\n"
+"\n"
+" float3 stc = float3(tc * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
+" stc.xy += offset * ShadowMap_Parameters.y;\n"
+" stc.z += ShadowMap_Parameters.z;\n"
+" return stc;\n"
+"}\n"
+"# else\n"
+"float3 GetShadowMapTC2D(float3 dir, float4 ShadowMap_Parameters, samplerCUBE Texture_CubeProjection)\n"
+"{\n"
+" float3 adir = abs(dir);\n"
+" float4 proj = texCUBE(Texture_CubeProjection, dir);\n"
+" float ma = max(max(adir.x, adir.y), adir.z);\n"
+" float3 stc = float3(mix(dir.xy, dir.zz, proj.xy) * ShadowMap_Parameters.x, ShadowMap_Parameters.w) / ma;\n"
+" stc.xy += proj.zw * ShadowMap_Parameters.y;\n"
+" stc.z += ShadowMap_Parameters.z;\n"
+" return stc;\n"
+"}\n"
+"# endif\n"
+"#endif // defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D)\n"
+"\n"
+"#ifdef USESHADOWMAPCUBE\n"
+"float4 GetShadowMapTCCube(float3 dir, float4 ShadowMap_Parameters)\n"
+"{\n"
+" float3 adir = abs(dir);\n"
+" return float4(dir, ShadowMap_Parameters.z + ShadowMap_Parameters.w / max(max(adir.x, adir.y), adir.z));\n"
+"}\n"
+"#endif\n"
+"\n"
+"# ifdef USESHADOWMAPRECT\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+"float ShadowMapCompare(float3 dir, samplerRECT Texture_ShadowMapRect, float4 ShadowMap_Parameters, samplerCUBE Texture_CubeProjection)\n"
+"#else\n"
+"float ShadowMapCompare(float3 dir, samplerRECT Texture_ShadowMapRect, float4 ShadowMap_Parameters)\n"
+"#endif\n"
+"{\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+" float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters, Texture_CubeProjection);\n"
+"#else\n"
+" float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters);\n"
+"#endif\n"
+" float f;\n"
+"# ifdef USESHADOWSAMPLER\n"
+"\n"
+"# ifdef USESHADOWMAPPCF\n"
+"# define texval(x, y) shadow2DRect(Texture_ShadowMapRect, shadowmaptc + float3(x, y, 0.0)).r\n"
+" f = dot(float4(0.25), float4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
+"# else\n"
+" f = shadow2DRect(Texture_ShadowMapRect, shadowmaptc).r;\n"
+"# endif\n"
+"\n"
+"# else\n"
+"\n"
+"# ifdef USESHADOWMAPPCF\n"
+"# if USESHADOWMAPPCF > 1\n"
+"# define texval(x, y) texRECT(Texture_ShadowMapRect, center + float2(x, y)).r\n"
+" float2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+" float4 row1 = step(shadowmaptc.z, float4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
+" float4 row2 = step(shadowmaptc.z, float4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0)));\n"
+" float4 row3 = step(shadowmaptc.z, float4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0)));\n"
+" float4 row4 = step(shadowmaptc.z, float4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0)));\n"
+" float4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
+" f = dot(mix(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n"
+"# else\n"
+"# define texval(x, y) texRECT(Texture_ShadowMapRect, shadowmaptc.xy + float2(x, y)).r\n"
+" float2 offset = fract(shadowmaptc.xy);\n"
+" float3 row1 = step(shadowmaptc.z, float3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
+" float3 row2 = step(shadowmaptc.z, float3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
+" float3 row3 = step(shadowmaptc.z, float3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
+" float3 cols = row2 + mix(row1, row3, offset.y);\n"
+" f = dot(mix(cols.xy, cols.yz, offset.x), float2(0.25));\n"
+"# endif\n"
+"# else\n"
+" f = step(shadowmaptc.z, texRECT(Texture_ShadowMapRect, shadowmaptc.xy).r);\n"
+"# endif\n"
+"\n"
+"# endif\n"
+" return f;\n"
+"}\n"
+"# endif\n"
+"\n"
+"# ifdef USESHADOWMAP2D\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+"float ShadowMapCompare(float3 dir, sampler2D Texture_ShadowMap2D, float4 ShadowMap_Parameters, float2 ShadowMap_TextureScale, samplerCUBE Texture_CubeProjection)\n"
+"#else\n"
+"float ShadowMapCompare(float3 dir, sampler2D Texture_ShadowMap2D, float4 ShadowMap_Parameters, float2 ShadowMap_TextureScale)\n"
+"#endif\n"
+"{\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+" float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters, Texture_CubeProjection);\n"
+"#else\n"
+" float3 shadowmaptc = GetShadowMapTC2D(dir, ShadowMap_Parameters);\n"
+"#endif\n"
+" float f;\n"
+"\n"
+"# ifdef USESHADOWSAMPLER\n"
+"# ifdef USESHADOWMAPPCF\n"
+"# define texval(x, y) shadow2D(Texture_ShadowMap2D, float3(center + float2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)).r \n"
+" float2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n"
+" f = dot(float4(0.25), float4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n"
+"# else\n"
+" f = shadow2D(Texture_ShadowMap2D, float3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z)).r;\n"
+"# endif\n"
+"# else\n"
+"# ifdef USESHADOWMAPPCF\n"
+"# if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n"
+"# ifdef GL_ARB_texture_gather\n"
+"# define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec(x, y))\n"
+"# else\n"
+"# define texval(x, y) texture4(Texture_ShadowMap2D, center + float2(x,y)*ShadowMap_TextureScale)\n"
+"# endif\n"
+" float2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+" center *= ShadowMap_TextureScale;\n"
+" float4 group1 = step(shadowmaptc.z, texval(-1.0, -1.0));\n"
+" float4 group2 = step(shadowmaptc.z, texval( 1.0, -1.0));\n"
+" float4 group3 = step(shadowmaptc.z, texval(-1.0, 1.0));\n"
+" float4 group4 = step(shadowmaptc.z, texval( 1.0, 1.0));\n"
+" float4 cols = float4(group1.rg, group2.rg) + float4(group3.ab, group4.ab) +\n"
+" mix(float4(group1.ab, group2.ab), float4(group3.rg, group4.rg), offset.y);\n"
+" f = dot(mix(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n"
+"# else\n"
+"# ifdef GL_EXT_gpu_shader4\n"
+"# define texval(x, y) tex2DOffset(Texture_ShadowMap2D, center, ifloat2(x, y)).r\n"
+"# else\n"
+"# define texval(x, y) tex2D(Texture_ShadowMap2D, center + float2(x, y)*ShadowMap_TextureScale).r \n"
+"# endif\n"
+"# if USESHADOWMAPPCF > 1\n"
+" float2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n"
+" center *= ShadowMap_TextureScale;\n"
+" float4 row1 = step(shadowmaptc.z, float4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n"
+" float4 row2 = step(shadowmaptc.z, float4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0)));\n"
+" float4 row3 = step(shadowmaptc.z, float4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0)));\n"
+" float4 row4 = step(shadowmaptc.z, float4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0)));\n"
+" float4 cols = row2 + row3 + mix(row1, row4, offset.y);\n"
+" f = dot(mix(cols.xyz, cols.yzw, offset.x), float3(1.0/9.0));\n"
+"# else\n"
+" float2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n"
+" float3 row1 = step(shadowmaptc.z, float3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n"
+" float3 row2 = step(shadowmaptc.z, float3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n"
+" float3 row3 = step(shadowmaptc.z, float3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n"
+" float3 cols = row2 + mix(row1, row3, offset.y);\n"
+" f = dot(mix(cols.xy, cols.yz, offset.x), float2(0.25));\n"
+"# endif\n"
+"# endif\n"
+"# else\n"
+" f = step(shadowmaptc.z, tex2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n"
+"# endif\n"
+"# endif\n"
+" return f;\n"
+"}\n"
+"# endif\n"
+"\n"
+"# ifdef USESHADOWMAPCUBE\n"
+"float ShadowMapCompare(float3 dir, samplerCUBE Texture_ShadowMapCube, float4 ShadowMap_Parameters)\n"
+"{\n"
+" // apply depth texture cubemap as light filter\n"
+" float4 shadowmaptc = GetShadowMapTCCube(dir, ShadowMap_Parameters);\n"
+" float f;\n"
+"# ifdef USESHADOWSAMPLER\n"
+" f = shadowCube(Texture_ShadowMapCube, shadowmaptc).r;\n"
+"# else\n"
+" f = step(shadowmaptc.w, texCUBE(Texture_ShadowMapCube, shadowmaptc.xyz).r);\n"
+"# endif\n"
+" return f;\n"
+"}\n"
+"# endif\n"
+"#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"#endif // FRAGMENT_SHADER\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_DEFERREDGEOMETRY\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"float4 gl_Color : COLOR0,\n"
+"#endif\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
+"float4 gl_MultiTexCoord2 : TEXCOORD2,\n"
+"float4 gl_MultiTexCoord3 : TEXCOORD3,\n"
+"uniform mat4 TexMatrix,\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform mat4 BackgroundTexMatrix,\n"
+"#endif\n"
+"uniform mat4 ModelViewMatrix,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float4 gl_FrontColor : COLOR,\n"
+"out float4 TexCoordBoth : TEXCOORD0,\n"
+"out float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
+"out float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
+"out float3 VectorR : TEXCOORD7 // direction of R texcoord (surface normal)\n"
+")\n"
+"{\n"
+" TexCoordBoth = mul(TexMatrix, gl_MultiTexCoord0);\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+" gl_FrontColor = gl_Color;\n"
+" TexCoordBoth.zw = float2(Backgroundmul(TexMatrix, gl_MultiTexCoord0));\n"
+"#endif\n"
+"\n"
+" // transform unnormalized eye direction into tangent space\n"
+"#ifdef USEOFFSETMAPPING\n"
+" float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
+" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
+" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
+" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+" VectorS = mul(ModelViewMatrix, float4(gl_MultiTexCoord1.xyz, 0)).xyz;\n"
+" VectorT = mul(ModelViewMatrix, float4(gl_MultiTexCoord2.xyz, 0)).xyz;\n"
+" VectorR = mul(ModelViewMatrix, float4(gl_MultiTexCoord3.xyz, 0)).xyz;\n"
+" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float4 TexCoordBoth : TEXCOORD0,\n"
+"float3 EyeVector : TEXCOORD2,\n"
+"float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
+"float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
+"float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n"
+"uniform sampler2D Texture_Normal,\n"
+"#ifdef USEALPHAKILL\n"
+"uniform sampler2D Texture_Color,\n"
+"#endif\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform sampler2D Texture_SecondaryNormal,\n"
+"#endif\n"
+"#ifdef USEOFFSETMAPPING\n"
+"uniform float OffsetMapping_Scale,\n"
+"#endif\n"
+"uniform half SpecularPower,\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+" float2 TexCoord = TexCoordBoth.xy;\n"
+"#ifdef USEOFFSETMAPPING\n"
+" // apply offsetmapping\n"
+" float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal);\n"
+"#define TexCoord TexCoordOffset\n"
+"#endif\n"
+"\n"
+"#ifdef USEALPHAKILL\n"
+" if (tex2D(Texture_Color, TexCoord).a < 0.5)\n"
+" discard;\n"
+"#endif\n"
+"\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+" float alpha = tex2D(Texture_Color, TexCoord).a;\n"
+" float terrainblend = clamp(float(gl_FrontColor.a) * alpha * 2.0 - 0.5, float(0.0), float(1.0));\n"
+" //float terrainblend = min(float(gl_FrontColor.a) * alpha * 2.0, float(1.0));\n"
+" //float terrainblend = float(gl_FrontColor.a) * alpha > 0.5;\n"
+"#endif\n"
+"\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+" float3 surfacenormal = mix(float3(tex2D(Texture_SecondaryNormal, TexCoord2)), float3(tex2D(Texture_Normal, TexCoord)), terrainblend) - float3(0.5, 0.5, 0.5);\n"
+"#else\n"
+" float3 surfacenormal = float3(tex2D(Texture_Normal, TexCoord)) - float3(0.5, 0.5, 0.5);\n"
+"#endif\n"
+"\n"
+" gl_FragColor = float4(normalize(surfacenormal.x * VectorS + surfacenormal.y * VectorT + surfacenormal.z * VectorR) * 0.5 + float3(0.5, 0.5, 0.5), 1);\n"
+"}\n"
+"#endif // FRAGMENT_SHADER\n"
+"#else // !MODE_DEFERREDGEOMETRY\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"uniform mat4 ModelViewMatrix,\n"
+"out float4 gl_Position : POSITION,\n"
+"out float4 ModelViewPosition : TEXCOORD0\n"
+")\n"
+"{\n"
+" ModelViewPosition = mul(ModelViewMatrix, gl_Vertex);\n"
+" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"float2 Pixel : WPOS,\n"
+"float4 ModelViewPosition : TEXCOORD0,\n"
+"uniform mat4 ViewToLight,\n"
+"uniform float2 ScreenToDepth, // ScreenToDepth = float2(Far / (Far - Near), Far * Near / (Near - Far));\n"
+"uniform float3 LightPosition,\n"
+"uniform half3 DeferredColor_Ambient,\n"
+"uniform half3 DeferredColor_Diffuse,\n"
+"#ifdef USESPECULAR\n"
+"uniform half3 DeferredColor_Specular,\n"
+"uniform half SpecularPower,\n"
+"#endif\n"
+"uniform sampler2D Texture_Attenuation,\n"
+"uniform samplerRECT Texture_ScreenDepth,\n"
+"uniform samplerRECT Texture_ScreenNormalMap,\n"
+"\n"
+"#ifdef USESHADOWMAPRECT\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform samplerRECTShadow Texture_ShadowMapRect,\n"
+"# else\n"
+"uniform samplerRECT Texture_ShadowMapRect,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAP2D\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform sampler2DShadow Texture_ShadowMap2D,\n"
+"# else\n"
+"uniform sampler2D Texture_ShadowMap2D,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+"uniform samplerCUBE Texture_CubeProjection,\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAPCUBE\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform samplerCUBEShadow Texture_ShadowMapCube,\n"
+"# else\n"
+"uniform samplerCUBE Texture_ShadowMapCube,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D) || defined(USESHADOWMAPCUBE)\n"
+"uniform float2 ShadowMap_TextureScale,\n"
+"uniform float4 ShadowMap_Parameters,\n"
+"#endif\n"
+"\n"
+"out float4 gl_FragData0 : COLOR0,\n"
+"out float4 gl_FragData1 : COLOR1\n"
+")\n"
+"{\n"
+" // calculate viewspace pixel position\n"
+" float3 position;\n"
+" position.z = ScreenToDepth.y / (texRECT(Texture_ScreenDepth, Pixel).r + ScreenToDepth.x);\n"
+" position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n"
+" // decode viewspace pixel normal\n"
+" half4 normalmap = texRECT(Texture_ScreenNormalMap, Pixel);\n"
+" half3 surfacenormal = normalize(normalmap.rgb - half3(0.5,0.5,0.5));\n"
+" // surfacenormal = pixel normal in viewspace\n"
+" // LightVector = pixel to light in viewspace\n"
+" // CubeVector = position in lightspace\n"
+" // eyevector = pixel to view in viewspace\n"
+" float3 CubeVector = float3(mul(ViewToLight, float4(position,1)));\n"
+" half fade = half(tex2D(Texture_Attenuation, float2(length(CubeVector), 0.0)));\n"
+"#ifdef USEDIFFUSE\n"
+" // calculate diffuse shading\n"
+" half3 lightnormal = half3(normalize(LightPosition - position));\n"
+" half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
+"#endif\n"
+"#ifdef USESPECULAR\n"
+" // calculate directional shading\n"
+" float3 eyevector = position * -1.0;\n"
+"# ifdef USEEXACTSPECULARMATH\n"
+" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(eyevector)))*-1.0, 0.0)), SpecularPower);\n"
+"# else\n"
+" half3 specularnormal = normalize(lightnormal + half3(normalize(eyevector)));\n"
+" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#if defined(USESHADOWMAP2D) || defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE)\n"
+" fade *= ShadowMapCompare(CubeVector,\n"
+"# if defined(USESHADOWMAP2D)\n"
+"Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n"
+"# endif\n"
+"# if defined(USESHADOWMAPRECT)\n"
+"Texture_ShadowMapRect, ShadowMap_Parameters\n"
+"# endif\n"
+"# if defined(USESHADOWMAPCUBE)\n"
+"Texture_ShadowMapCube, ShadowMap_Parameters\n"
+"# endif\n"
+"\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+", Texture_CubeProjection\n"
+"#endif\n"
+" );\n"
+"#endif\n"
+"\n"
+"#ifdef USEDIFFUSE\n"
+" gl_FragData0 = float4((DeferredColor_Ambient + DeferredColor_Diffuse * diffuse) * fade, 1.0);\n"
+"#else\n"
+" gl_FragData0 = float4(DeferredColor_Ambient * fade, 1.0);\n"
+"#endif\n"
+"#ifdef USESPECULAR\n"
+" gl_FragData1 = float4(DeferredColor_Specular * (specular * fade), 1.0);\n"
+"#else\n"
+" gl_FragData1 = float4(0.0, 0.0, 0.0, 1.0);\n"
+"#endif\n"
+"\n"
+"# ifdef USECUBEFILTER\n"
+" float3 cubecolor = texCUBE(Texture_Cube, CubeVector).rgb;\n"
+" gl_FragData0 *= cubecolor;\n"
+" gl_FragData1 *= cubecolor;\n"
+"# endif\n"
+"}\n"
+"#endif // FRAGMENT_SHADER\n"
+"#else // !MODE_DEFERREDLIGHTSOURCE\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef VERTEX_SHADER\n"
+"void main\n"
+"(\n"
+"float4 gl_Vertex : POSITION,\n"
+"uniform float4x4 ModelViewProjectionMatrix,\n"
+"#if defined(USEVERTEXTEXTUREBLEND) || defined(MODE_VERTEXCOLOR)\n"
+"float4 gl_Color : COLOR0,\n"
+"#endif\n"
+"float4 gl_MultiTexCoord0 : TEXCOORD0,\n"
+"float4 gl_MultiTexCoord1 : TEXCOORD1,\n"
+"float4 gl_MultiTexCoord2 : TEXCOORD2,\n"
+"float4 gl_MultiTexCoord3 : TEXCOORD3,\n"
+"float4 gl_MultiTexCoord4 : TEXCOORD4,\n"
+"\n"
+"uniform float3 EyePosition,\n"
+"uniform mat4 TexMatrix,\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform mat4 BackgroundTexMatrix,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"uniform mat4 ModelToLight,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"uniform float3 LightPosition,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTDIRECTION\n"
+"uniform float3 LightDir,\n"
+"#endif\n"
+"uniform float4 FogPlane,\n"
+"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
+"uniform float3 LightPosition,\n"
+"#endif\n"
+"\n"
+"out float4 gl_FrontColor : COLOR,\n"
+"out float4 TexCoordBoth : TEXCOORD0,\n"
+"#ifdef USELIGHTMAP\n"
+"out float2 TexCoordLightmap : TEXCOORD1,\n"
+"#endif\n"
+"#ifdef USEEYEVECTOR\n"
+"out float3 EyeVector : TEXCOORD2,\n"
+"#endif\n"
+"#ifdef USEREFLECTION\n"
+"out float4 ModelViewProjectionPosition : TEXCOORD3,\n"
+"#endif\n"
+"#ifdef USEFOG\n"
+"out float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n"
+"#endif\n"
+"#if defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)\n"
+"out float3 LightVector : TEXCOORD5,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"out float3 CubeVector : TEXCOORD3,\n"
+"#endif\n"
+"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY)\n"
+"out float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
+"out float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
+"out float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n"
+"#endif\n"
+"out float4 gl_Position : POSITION\n"
+")\n"
+"{\n"
+"#if defined(MODE_VERTEXCOLOR) || defined(USEVERTEXTEXTUREBLEND)\n"
+" gl_FrontColor = gl_Color;\n"
+"#endif\n"
+" // copy the surface texcoord\n"
+" TexCoordBoth = mul(TexMatrix, gl_MultiTexCoord0);\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+" TexCoordBoth.zw = mul(BackgroundTexMatrix, gl_MultiTexCoord0).xy;\n"
+"#endif\n"
+"#ifdef USELIGHTMAP\n"
+" TexCoordLightmap = float2(gl_MultiTexCoord4);\n"
+"#endif\n"
+"\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+" // transform vertex position into light attenuation/cubemap space\n"
+" // (-1 to +1 across the light box)\n"
+" CubeVector = float3(mul(ModelToLight, gl_Vertex));\n"
+"\n"
+"# ifdef USEDIFFUSE\n"
+" // transform unnormalized light direction into tangent space\n"
+" // (we use unnormalized to ensure that it interpolates correctly and then\n"
+" // normalize it per pixel)\n"
+" float3 lightminusvertex = LightPosition - gl_Vertex.xyz;\n"
+" LightVector.x = dot(lightminusvertex, gl_MultiTexCoord1.xyz);\n"
+" LightVector.y = dot(lightminusvertex, gl_MultiTexCoord2.xyz);\n"
+" LightVector.z = dot(lightminusvertex, gl_MultiTexCoord3.xyz);\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#if defined(MODE_LIGHTDIRECTION) && defined(USEDIFFUSE)\n"
+" LightVector.x = dot(LightDir, gl_MultiTexCoord1.xyz);\n"
+" LightVector.y = dot(LightDir, gl_MultiTexCoord2.xyz);\n"
+" LightVector.z = dot(LightDir, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+" // transform unnormalized eye direction into tangent space\n"
+"#ifdef USEEYEVECTOR\n"
+" float3 EyeVectorModelSpace = EyePosition - gl_Vertex.xyz;\n"
+" EyeVector.x = dot(EyeVectorModelSpace, gl_MultiTexCoord1.xyz);\n"
+" EyeVector.y = dot(EyeVectorModelSpace, gl_MultiTexCoord2.xyz);\n"
+" EyeVector.z = dot(EyeVectorModelSpace, gl_MultiTexCoord3.xyz);\n"
+"#endif\n"
+"\n"
+"#ifdef USEFOG\n"
+" EyeVectorModelSpaceFogPlaneVertexDist.xyz = EyePosition - gl_Vertex.xyz;\n"
+" EyeVectorModelSpaceFogPlaneVertexDist.w = dot(FogPlane, gl_Vertex);\n"
+"#endif\n"
+"\n"
+"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
+" VectorS = gl_MultiTexCoord1.xyz;\n"
+" VectorT = gl_MultiTexCoord2.xyz;\n"
+" VectorR = gl_MultiTexCoord3.xyz;\n"
+"#endif\n"
+"\n"
+" // transform vertex to camera space, using ftransform to match non-VS rendering\n"
+" gl_Position = mul(ModelViewProjectionMatrix, gl_Vertex);\n"
+"\n"
+"#ifdef USEREFLECTION\n"
+" ModelViewProjectionPosition = gl_Position;\n"
+"#endif\n"
+"}\n"
+"#endif // VERTEX_SHADER\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef FRAGMENT_SHADER\n"
+"void main\n"
+"(\n"
+"#ifdef USEDEFERREDLIGHTMAP\n"
+"float2 Pixel : WPOS,\n"
+"#endif\n"
+"float4 gl_FrontColor : COLOR,\n"
+"float4 TexCoordBoth : TEXCOORD0,\n"
+"#ifdef USELIGHTMAP\n"
+"float2 TexCoordLightmap : TEXCOORD1,\n"
+"#endif\n"
+"#ifdef USEEYEVECTOR\n"
+"float3 EyeVector : TEXCOORD2,\n"
+"#endif\n"
+"#ifdef USEREFLECTION\n"
+"float4 ModelViewProjectionPosition : TEXCOORD3,\n"
+"#endif\n"
+"#ifdef USEFOG\n"
+"float4 EyeVectorModelSpaceFogPlaneVertexDist : TEXCOORD4,\n"
+"#endif\n"
+"#if defined(MODE_LIGHTSOURCE) || defined(MODE_LIGHTDIRECTION)\n"
+"float3 LightVector : TEXCOORD5,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"float3 CubeVector : TEXCOORD3,\n"
+"#endif\n"
+"#ifdef MODE_DEFERREDLIGHTSOURCE\n"
+"float4 ModelViewPosition : TEXCOORD0,\n"
+"#endif\n"
+"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_DEFERREDGEOMETRY)\n"
+"float3 VectorS : TEXCOORD5, // direction of S texcoord (sometimes crudely called tangent)\n"
+"float3 VectorT : TEXCOORD6, // direction of T texcoord (sometimes crudely called binormal)\n"
+"float3 VectorR : TEXCOORD7, // direction of R texcoord (surface normal)\n"
+"#endif\n"
+"\n"
+"uniform sampler2D Texture_Normal,\n"
+"uniform sampler2D Texture_Color,\n"
+"#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
+"uniform sampler2D Texture_Gloss,\n"
+"#endif\n"
+"#ifdef USEGLOW\n"
+"uniform sampler2D Texture_Glow,\n"
+"#endif\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+"uniform sampler2D Texture_SecondaryNormal,\n"
+"uniform sampler2D Texture_SecondaryColor,\n"
+"#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
+"uniform sampler2D Texture_SecondaryGloss,\n"
+"#endif\n"
+"#ifdef USEGLOW\n"
+"uniform sampler2D Texture_SecondaryGlow,\n"
+"#endif\n"
+"#endif\n"
+"#ifdef USECOLORMAPPING\n"
+"uniform sampler2D Texture_Pants,\n"
+"uniform sampler2D Texture_Shirt,\n"
+"#endif\n"
+"#ifdef USEFOG\n"
+"uniform sampler2D Texture_FogMask,\n"
+"#endif\n"
+"#ifdef USELIGHTMAP\n"
+"uniform sampler2D Texture_Lightmap,\n"
+"#endif\n"
+"#if defined(MODE_LIGHTDIRECTIONMAP_MODELSPACE) || defined(MODE_LIGHTDIRECTIONMAP_TANGENTSPACE)\n"
+"uniform sampler2D Texture_Deluxemap,\n"
+"#endif\n"
+"#ifdef USEREFLECTION\n"
+"uniform sampler2D Texture_Reflection,\n"
+"#endif\n"
+"\n"
+"//#ifdef MODE_DEFERREDLIGHTSOURCE\n"
+"uniform samplerRECT Texture_ScreenDepth,\n"
+"uniform samplerRECT Texture_ScreenNormalMap,\n"
+"//#endif\n"
+"#ifdef USEDEFERREDLIGHTMAP\n"
+"uniform samplerRECT Texture_ScreenDiffuse,\n"
+"uniform samplerRECT Texture_ScreenSpecular,\n"
+"#endif\n"
+"\n"
+"#ifdef USECOLORMAPPING\n"
+"uniform half3 Color_Pants,\n"
+"uniform half3 Color_Shirt,\n"
+"#endif\n"
+"#ifdef USEFOG\n"
+"uniform float3 FogColor,\n"
+"uniform float FogRangeRecip,\n"
+"uniform float FogPlaneViewDist,\n"
+"uniform float FogHeightFade,\n"
+"#endif\n"
+"\n"
+"#ifdef USEOFFSETMAPPING\n"
+"uniform float OffsetMapping_Scale,\n"
+"#endif\n"
+"\n"
+"#ifdef USEDEFERREDLIGHTMAP\n"
+"uniform half3 DeferredMod_Diffuse,\n"
+"uniform half3 DeferredMod_Specular,\n"
+"#endif\n"
+"uniform half3 Color_Ambient,\n"
+"uniform half3 Color_Diffuse,\n"
+"uniform half3 Color_Specular,\n"
+"uniform half SpecularPower,\n"
+"#ifdef USEGLOW\n"
+"uniform half3 Color_Glow,\n"
+"#endif\n"
+"uniform half Alpha,\n"
+"#ifdef USEREFLECTION\n"
+"uniform float4 DistortScaleRefractReflect,\n"
+"uniform float4 ScreenScaleRefractReflect,\n"
+"uniform float4 ScreenCenterRefractReflect,\n"
+"uniform half4 ReflectColor,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTDIRECTION\n"
+"uniform half3 LightColor,\n"
+"#endif\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+"uniform half3 LightColor,\n"
+"#endif\n"
+"\n"
+"#if defined(MODE_LIGHTSOURCE) || defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"uniform sampler2D Texture_Attenuation,\n"
+"uniform samplerCUBE Texture_Cube,\n"
+"\n"
+"#ifdef USESHADOWMAPRECT\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform samplerRECTShadow Texture_ShadowMapRect,\n"
+"# else\n"
+"uniform samplerRECT Texture_ShadowMapRect,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAP2D\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform sampler2DShadow Texture_ShadowMap2D,\n"
+"# else\n"
+"uniform sampler2D Texture_ShadowMap2D,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+"uniform samplerCUBE Texture_CubeProjection,\n"
+"#endif\n"
+"\n"
+"#ifdef USESHADOWMAPCUBE\n"
+"# ifdef USESHADOWSAMPLER\n"
+"uniform samplerCUBEShadow Texture_ShadowMapCube,\n"
+"# else\n"
+"uniform samplerCUBE Texture_ShadowMapCube,\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAP2D) || defined(USESHADOWMAPCUBE)\n"
+"uniform float2 ShadowMap_TextureScale,\n"
+"uniform float4 ShadowMap_Parameters,\n"
+"#endif\n"
+"#endif // !defined(MODE_LIGHTSOURCE) && !defined(MODE_DEFERREDLIGHTSOURCE)\n"
+"\n"
+"out float4 gl_FragColor : COLOR\n"
+")\n"
+"{\n"
+" float2 TexCoord = TexCoordBoth.xy;\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+" float2 TexCoord2 = TexCoordBoth.zw;\n"
+"#endif\n"
+"#ifdef USEOFFSETMAPPING\n"
+" // apply offsetmapping\n"
+" float2 TexCoordOffset = OffsetMapping(TexCoord, OffsetMapping_Scale, EyeVector, Texture_Normal);\n"
+"#define TexCoord TexCoordOffset\n"
+"#endif\n"
+"\n"
+" // combine the diffuse textures (base, pants, shirt)\n"
+" half4 color = half4(tex2D(Texture_Color, TexCoord));\n"
+"#ifdef USEALPHAKILL\n"
+" if (color.a < 0.5)\n"
+" discard;\n"
+"#endif\n"
+" color.a *= Alpha;\n"
+"#ifdef USECOLORMAPPING\n"
+" color.rgb += half3(tex2D(Texture_Pants, TexCoord)) * Color_Pants + half3(tex2D(Texture_Shirt, TexCoord)) * Color_Shirt;\n"
+"#endif\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+" float terrainblend = clamp(half(gl_FrontColor.a) * color.a * 2.0 - 0.5, half(0.0), half(1.0));\n"
+" //half terrainblend = min(half(gl_FrontColor.a) * color.a * 2.0, half(1.0));\n"
+" //half terrainblend = half(gl_FrontColor.a) * color.a > 0.5;\n"
+" color.rgb = half3(mix(float3(tex2D(Texture_SecondaryColor, TexCoord2)), float3(color.rgb), terrainblend));\n"
+" color.a = 1.0;\n"
+" //color = mix(half4(1, 0, 0, 1), color, terrainblend);\n"
+"#endif\n"
+"\n"
+" // get the surface normal\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+" half3 surfacenormal = normalize(half3(mix(float3(tex2D(Texture_SecondaryNormal, TexCoord2)), float3(tex2D(Texture_Normal, TexCoord)), terrainblend)) - half3(0.5, 0.5, 0.5));\n"
+"#else\n"
+" half3 surfacenormal = normalize(half3(tex2D(Texture_Normal, TexCoord)) - half3(0.5, 0.5, 0.5));\n"
+"#endif\n"
+"\n"
+" // get the material colors\n"
+" half3 diffusetex = color.rgb;\n"
+"#if defined(USESPECULAR) || defined(USEDEFERREDLIGHTMAP)\n"
+"# ifdef USEVERTEXTEXTUREBLEND\n"
+" half3 glosstex = half3(mix(float3(tex2D(Texture_SecondaryGloss, TexCoord2)), float3(tex2D(Texture_Gloss, TexCoord)), terrainblend));\n"
+"# else\n"
+" half3 glosstex = half3(tex2D(Texture_Gloss, TexCoord));\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+" // light source\n"
+" half3 lightnormal = half3(normalize(LightVector));\n"
+" half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
+" color.rgb = diffusetex * (Color_Ambient + diffuse * Color_Diffuse);\n"
+"#ifdef USESPECULAR\n"
+"#ifdef USEEXACTSPECULARMATH\n"
+" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
+"#else\n"
+" half3 specularnormal = normalize(lightnormal + half3(normalize(EyeVector)));\n"
+" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
+"#endif\n"
+" color.rgb += glosstex * (specular * Color_Specular);\n"
+"#endif\n"
+" color.rgb *= LightColor;\n"
+" color.rgb *= half(tex2D(Texture_Attenuation, float2(length(CubeVector), 0.0)));\n"
+"#if defined(USESHADOWMAPRECT) || defined(USESHADOWMAPCUBE) || defined(USESHADOWMAP2D)\n"
+" color.rgb *= ShadowMapCompare(CubeVector,\n"
+"# if defined(USESHADOWMAP2D)\n"
+"Texture_ShadowMap2D, ShadowMap_Parameters, ShadowMap_TextureScale\n"
+"# endif\n"
+"# if defined(USESHADOWMAPRECT)\n"
+"Texture_ShadowMapRect, ShadowMap_Parameters\n"
+"# endif\n"
+"# if defined(USESHADOWMAPCUBE)\n"
+"Texture_ShadowMapCube, ShadowMap_Parameters\n"
+"# endif\n"
+"\n"
+"#ifdef USESHADOWMAPVSDCT\n"
+", Texture_CubeProjection\n"
+"#endif\n"
+" );\n"
+"\n"
+"#endif\n"
+"# ifdef USECUBEFILTER\n"
+" color.rgb *= half3(texCUBE(Texture_Cube, CubeVector));\n"
+"# endif\n"
+"#endif // MODE_LIGHTSOURCE\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_LIGHTDIRECTION\n"
+"#define SHADING\n"
+" half3 lightnormal = half3(normalize(LightVector));\n"
+"#define lightcolor LightColor\n"
+"#endif // MODE_LIGHTDIRECTION\n"
+"#ifdef MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
+"#define SHADING\n"
+" // deluxemap lightmapping using light vectors in modelspace (q3map2 -light -deluxe)\n"
+" half3 lightnormal_modelspace = half3(tex2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + half3(-1.0, -1.0, -1.0);\n"
+" half3 lightcolor = half3(tex2D(Texture_Lightmap, TexCoordLightmap));\n"
+" // convert modelspace light vector to tangentspace\n"
+" half3 lightnormal;\n"
+" lightnormal.x = dot(lightnormal_modelspace, half3(VectorS));\n"
+" lightnormal.y = dot(lightnormal_modelspace, half3(VectorT));\n"
+" lightnormal.z = dot(lightnormal_modelspace, half3(VectorR));\n"
+" // calculate directional shading (and undoing the existing angle attenuation on the lightmap by the division)\n"
+" // note that q3map2 is too stupid to calculate proper surface normals when q3map_nonplanar\n"
+" // is used (the lightmap and deluxemap coords correspond to virtually random coordinates\n"
+" // on that luxel, and NOT to its center, because recursive triangle subdivision is used\n"
+" // to map the luxels to coordinates on the draw surfaces), which also causes\n"
+" // deluxemaps to be wrong because light contributions from the wrong side of the surface\n"
+" // are added up. To prevent divisions by zero or strong exaggerations, a max()\n"
+" // nudge is done here at expense of some additional fps. This is ONLY needed for\n"
+" // deluxemaps, tangentspace deluxemap avoid this problem by design.\n"
+" lightcolor *= 1.0 / max(0.25, lightnormal.z);\n"
+"#endif // MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
+"#ifdef MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
+"#define SHADING\n"
+" // deluxemap lightmapping using light vectors in tangentspace (hmap2 -light)\n"
+" half3 lightnormal = half3(tex2D(Texture_Deluxemap, TexCoordLightmap)) * 2.0 + half3(-1.0, -1.0, -1.0);\n"
+" half3 lightcolor = half3(tex2D(Texture_Lightmap, TexCoordLightmap));\n"
+"#endif\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef MODE_LIGHTMAP\n"
+" color.rgb = diffusetex * (Color_Ambient + half3(tex2D(Texture_Lightmap, TexCoordLightmap)) * Color_Diffuse);\n"
+"#endif // MODE_LIGHTMAP\n"
+"#ifdef MODE_VERTEXCOLOR\n"
+" color.rgb = diffusetex * (Color_Ambient + half3(gl_FrontColor.rgb) * Color_Diffuse);\n"
+"#endif // MODE_VERTEXCOLOR\n"
+"#ifdef MODE_FLATCOLOR\n"
+" color.rgb = diffusetex * Color_Ambient;\n"
+"#endif // MODE_FLATCOLOR\n"
+"\n"
+"\n"
+"\n"
+"\n"
+"#ifdef SHADING\n"
+"# ifdef USEDIFFUSE\n"
+" half diffuse = half(max(float(dot(surfacenormal, lightnormal)), 0.0));\n"
+"# ifdef USESPECULAR\n"
+"# ifdef USEEXACTSPECULARMATH\n"
+" half specular = pow(half(max(float(dot(reflect(lightnormal, surfacenormal), normalize(EyeVector)))*-1.0, 0.0)), SpecularPower);\n"
+"# else\n"
+" half3 specularnormal = normalize(lightnormal + half3(normalize(EyeVector)));\n"
+" half specular = pow(half(max(float(dot(surfacenormal, specularnormal)), 0.0)), SpecularPower);\n"
+"# endif\n"
+" color.rgb = diffusetex * Color_Ambient + (diffusetex * Color_Diffuse * diffuse + glosstex * Color_Specular * specular) * lightcolor;\n"
+"# else\n"
+" color.rgb = diffusetex * (Color_Ambient + Color_Diffuse * diffuse * lightcolor);\n"
+"# endif\n"
+"# else\n"
+" color.rgb = diffusetex * Color_Ambient;\n"
+"# endif\n"
+"#endif\n"
+"\n"
+"#ifdef USEDEFERREDLIGHTMAP\n"
+" color.rgb += diffusetex * half3(texRECT(Texture_ScreenDiffuse, Pixel)) * DeferredMod_Diffuse;\n"
+" color.rgb += glosstex * half3(texRECT(Texture_ScreenSpecular, Pixel)) * DeferredMod_Specular;\n"
+" color.rgb = half3(texRECT(Texture_ScreenDepth, Pixel));\n"
+"#endif\n"
+"\n"
+"#ifdef USEGLOW\n"
+"#ifdef USEVERTEXTEXTUREBLEND\n"
+" color.rgb += mix(half3(tex2D(Texture_SecondaryGlow, TexCoord2)), half3(tex2D(Texture_Glow, TexCoord)), terrainblend) * Color_Glow;\n"
+"#else\n"
+" color.rgb += half3(tex2D(Texture_Glow, TexCoord)) * Color_Glow;\n"
+"#endif\n"
+"#endif\n"
+"\n"
+"#ifdef USEFOG\n"
+"#ifdef MODE_LIGHTSOURCE\n"
+" color.rgb *= half(FogVertex());\n"
+"#else\n"
+" color.rgb = mix(FogColor, float3(color.rgb), FogVertex(EyeVectorModelSpaceFogPlaneVertexDist.xyz, EyeVectorModelSpaceFogPlaneVertexDist.w, FogRangeRecip, FogPlaneViewDist, FogHeightFade, Texture_FogMask));\n"
+"#endif\n"
+"#endif\n"
+"\n"
+" // reflection must come last because it already contains exactly the correct fog (the reflection render preserves camera distance from the plane, it only flips the side) and ContrastBoost/SceneBrightness\n"
+"#ifdef USEREFLECTION\n"
+" float4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
+" //float4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(half3(tex2D(Texture_Normal, TexCoord)) - half3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
+" float2 SafeScreenTexCoord = ModelViewProjectionPosition.xy * ScreenScaleRefractReflectIW.zw + ScreenCenterRefractReflect.zw;\n"
+" float2 ScreenTexCoord = SafeScreenTexCoord + float3(normalize(half3(tex2D(Texture_Normal, TexCoord)) - half3(0.5))).xy * DistortScaleRefractReflect.zw;\n"
+" // FIXME temporary hack to detect the case that the reflection\n"
+" // gets blackened at edges due to leaving the area that contains actual\n"
+" // content.\n"
+" // Remove this 'ack once we have a better way to stop this thing from\n"
+" // 'appening.\n"
+" float f = min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(0.01, 0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(0.01, -0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(-0.01, 0.01)).rgb) / 0.05);\n"
+" f *= min(1.0, length(tex2D(Texture_Reflection, ScreenTexCoord + float2(-0.01, -0.01)).rgb) / 0.05);\n"
+" ScreenTexCoord = mix(SafeScreenTexCoord, ScreenTexCoord, f);\n"
+" color.rgb = mix(color.rgb, half3(tex2D(Texture_Reflection, ScreenTexCoord)) * ReflectColor.rgb, ReflectColor.a);\n"
+"#endif\n"
+"\n"
+" gl_FragColor = float4(color);\n"
+"}\n"
+"#endif // FRAGMENT_SHADER\n"
+"\n"
+"#endif // !MODE_DEFERREDLIGHTSOURCE\n"
+"#endif // !MODE_DEFERREDGEOMETRY\n"
"#endif // !MODE_WATER\n"
"#endif // !MODE_REFRACTION\n"
"#endif // !MODE_BLOOMBLUR\n"
"#endif // !MODE_DEPTH_OR_SHADOW\n"
;
-const char *builtincgshaderstring = "";
+//=======================================================================================================================================================
typedef struct shaderpermutationinfo_s
{