From 23fb28d4c92f3531bc63c827a6e48de8699204e0 Mon Sep 17 00:00:00 2001 From: Richard Allen Date: Thu, 31 Mar 2011 18:11:49 +0000 Subject: [PATCH] Appying the differences between v11 and v12 renderers --- reaction/code/renderer/tr_backend.c | 16 +- reaction/code/renderer/tr_bsp.c | 9 +- reaction/code/renderer/tr_cmds.c | 2 + reaction/code/renderer/tr_extramath.c | 8 +- reaction/code/renderer/tr_glsl.c | 1047 +++++++++++++++++-------- reaction/code/renderer/tr_local.h | 945 +++------------------- reaction/code/renderer/tr_shade.c | 366 +++++++-- reaction/code/renderer/tr_shader.c | 27 +- reaction/code/renderer/tr_sky.c | 18 +- reaction/code/renderer/tr_surface.c | 37 +- 10 files changed, 1198 insertions(+), 1277 deletions(-) diff --git a/reaction/code/renderer/tr_backend.c b/reaction/code/renderer/tr_backend.c index c8158565..8f640ee2 100644 --- a/reaction/code/renderer/tr_backend.c +++ b/reaction/code/renderer/tr_backend.c @@ -914,7 +914,6 @@ Used for cinematics. void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty) { int i, j; int start, end; - matrix_t matrix; if ( !tr.registered ) { return; @@ -1022,22 +1021,13 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * if (glRefConfig.glsl && r_arb_shader_objects->integer) { - shaderProgram_t *sp = &tr.genericShader[0]; + shaderProgram_t *sp = &tr.textureOnlyShader; GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD); GLSL_BindProgram(sp); - - GLSL_SetUniform_ModelViewProjectionMatrix(sp, glState.modelviewProjection); - - GLSL_SetUniform_FogAdjustColors(sp, 0); - GLSL_SetUniform_DeformGen(sp, DGEN_NONE); - GLSL_SetUniform_TCGen0(sp, TCGEN_TEXTURE); - Matrix16Identity(matrix); - GLSL_SetUniform_Texture0Matrix(sp, matrix); - GLSL_SetUniform_Texture1Env(sp, 0); - GLSL_SetUniform_ColorGen(sp, CGEN_IDENTITY); - GLSL_SetUniform_AlphaGen(sp, AGEN_IDENTITY); + + GLSL_SetUniformMatrix16(sp, TEXTUREONLY_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); } else { diff --git a/reaction/code/renderer/tr_bsp.c b/reaction/code/renderer/tr_bsp.c index 95440937..479cbabe 100644 --- a/reaction/code/renderer/tr_bsp.c +++ b/reaction/code/renderer/tr_bsp.c @@ -40,7 +40,7 @@ int c_subdivisions; int c_gridVerts; //=============================================================================== -/* +#if 0 static void HSVtoRGB( float h, float s, float v, float rgb[3] ) { int i; @@ -742,7 +742,9 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, msurface_t *surf, i cv->numTriangles -= badTriangles; } } +#endif +#if 0 /* =============== ParseFlare @@ -773,6 +775,7 @@ static void ParseFlare( dsurface_t *ds, drawVert_t *verts, msurface_t *surf, int flare->normal[i] = LittleFloat( ds->lightmapVecs[2][i] ); } } +#endif /* @@ -2795,6 +2798,10 @@ void R_MergeLeafSurfaces(void) default: break; + + // never happens, but silences a compile warning + default: + break; } } diff --git a/reaction/code/renderer/tr_cmds.c b/reaction/code/renderer/tr_cmds.c index 42e84357..b5f1acb1 100644 --- a/reaction/code/renderer/tr_cmds.c +++ b/reaction/code/renderer/tr_cmds.c @@ -73,6 +73,8 @@ void R_PerformanceCounters( void ) { { ri.Printf( PRINT_ALL, "VBO draws: static %i dynamic %i\nMultidraws: %i merged %i\n", backEnd.pc.c_staticVboDraws, backEnd.pc.c_dynamicVboDraws, backEnd.pc.c_multidraws, backEnd.pc.c_multidrawsMerged ); + ri.Printf( PRINT_ALL, "GLSL binds: %i draws: gen %i lightmap %i fog %i dlight %i\n", + backEnd.pc.c_glslShaderBinds, backEnd.pc.c_genericDraws, backEnd.pc.c_lightmappedDraws, backEnd.pc.c_fogDraws, backEnd.pc.c_dlightDraws); } Com_Memset( &tr.pc, 0, sizeof( tr.pc ) ); diff --git a/reaction/code/renderer/tr_extramath.c b/reaction/code/renderer/tr_extramath.c index 26c82032..b1a1b47a 100644 --- a/reaction/code/renderer/tr_extramath.c +++ b/reaction/code/renderer/tr_extramath.c @@ -83,10 +83,10 @@ void Matrix16Transform( const matrix_t in1, const vec4_t in2, vec4_t out ) qboolean Matrix16Compare( const matrix_t a, const matrix_t b ) { - return (a[ 0] == b[ 0] && a[ 4] == b[ 4] && a[ 8] == b[ 8] && a[12] == b[12] && - a[ 1] == b[ 1] && a[ 5] == b[ 5] && a[ 9] == b[ 9] && a[13] == b[13] && - a[ 2] == b[ 2] && a[ 6] == b[ 6] && a[10] == b[10] && a[14] == b[14] && - a[ 3] == b[ 3] && a[ 7] == b[ 7] && a[11] == b[11] && a[15] == b[15]); + return !(a[ 0] != b[ 0] || a[ 4] != b[ 4] || a[ 8] != b[ 8] || a[12] != b[12] || + a[ 1] != b[ 1] || a[ 5] != b[ 5] || a[ 9] != b[ 9] || a[13] != b[13] || + a[ 2] != b[ 2] || a[ 6] != b[ 6] || a[10] != b[10] || a[14] != b[14] || + a[ 3] != b[ 3] || a[ 7] != b[ 7] || a[11] != b[11] || a[15] != b[15]); } void Matrix16Dump( const matrix_t in ) diff --git a/reaction/code/renderer/tr_glsl.c b/reaction/code/renderer/tr_glsl.c index dc324a0d..c4a336c7 100644 --- a/reaction/code/renderer/tr_glsl.c +++ b/reaction/code/renderer/tr_glsl.c @@ -26,152 +26,293 @@ void GLSL_BindNullProgram(void); // FIXME: Do something that isn't this messy static const char *fallbackGenericShader_vp = -"attribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoord0;\r\nattrib" -"ute vec4 attr_TexCoord1;\r\nattribute vec3 attr_Normal;\r\nattribute vec4" -" attr_Color;\r\n\r\n#if defined(USE_VERTEX_ANIMATION)\r\nattribute vec4 a" -"ttr_Position2;\r\nattribute vec3 attr_Normal2;\r\n#endif\r\n\r\nuniform ma" -"t4 u_Texture0Matrix;\r\nuniform vec3 u_ViewOrigin;\r\n\r\n#if defined" -"(USE_TCGEN)\r\nuniform int u_TCGen0;\r\nuniform vec4 u_TCGen0Vector0" -";\r\nuniform vec4 u_TCGen0Vector1;\r\n#endif\r\n\r\n#if defined(USE_FOG)" -"\r\nuniform vec4 u_FogDistance;\r\nuniform vec4 u_FogDepth;\r\nunifor" -"m float u_FogEyeT;\r\nuniform int u_FogAdjustColors;\r\n#endif\r\n\r" -"\n#if defined(USE_DEFORM_VERTEXES)\r\nuniform int u_DeformGen;\r\nunifo" -"rm vec4 u_DeformWave;\r\nuniform vec3 u_DeformBulge;\r\nuniform float" -" u_DeformSpread;\r\n#endif\r\n\r\nuniform float u_Time;\r\nuniform int " -" u_ColorGen;\r\nuniform int u_AlphaGen;\r\nuniform vec4 u_Color;" -"\r\nuniform mat4 u_ModelViewProjectionMatrix;\r\nuniform vec3 u_Ambie" -"ntLight;\r\nuniform vec3 u_DirectedLight;\r\nuniform vec3 u_LightDir;" -"\r\n\r\nuniform float u_PortalRange;\r\n\r\n#if defined(USE_VERTEX_ANIMAT" -"ION)\r\nuniform float u_VertexLerp;\r\n#endif\r\n\r\nvarying vec2 var_" -"Tex1;\r\nvarying vec2 var_Tex2;\r\nvarying vec4 var_Color;\r\nvarying" -" float var_DlightMod;\r\n\r\n#if defined(USE_DEFORM_VERTEXES)\r\nfloat tr" -"iangle(float x)\r\n{\r\n\treturn max(1.0 - abs(x), 0);\r\n}\r\n\r\nfloat sa" -"wtooth(float x)\r\n{\r\n\treturn x - floor(x);\r\n}\r\n\r\nvec4 DeformPosit" -"ion(const vec4 pos, const vec3 normal, const vec2 st)\r\n{\r\n\tvec4 deform" -"ed = pos;\r\n\r\n\tif (u_DeformGen == DGEN_WAVE_SIN)\r\n\t{\r\n\t\tfloat of" -"f = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u_Deform" -"Wave.x + sin((off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * 2.0 * M_" -"PI) * u_DeformWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\tdefor" -"med.xyz += offset;\r\n\t}\r\n else if (u_DeformGen == DGEN_WAVE_SQUARE)\r" -"\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tf" -"loat scale = u_DeformWave.x + sign(sin((off + u_DeformWave.z + (u_Time * u" -"_DeformWave.w)) * 2.0 * M_PI)) * u_DeformWave.y;\r\n\t\tvec3 offset = norma" -"l * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n else if (u_Deform" -"Gen == DGEN_WAVE_TRIANGLE)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos.z" -") * u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave.x + triangle(off + u" -"_DeformWave.z + (u_Time * u_DeformWave.w)) * u_DeformWave.y;\r\n\t\tvec3 of" -"fset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n else " -"if (u_DeformGen == DGEN_WAVE_SAWTOOTH)\r\n\t{\r\n\t\tfloat off = (pos.x + p" -"os.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave.x + sawt" -"ooth(off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * u_DeformWave.y;\r" -"\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n" -"\t}\r\n else if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)\r\n\t{\r\n\t\t" -"float off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale = " -"u_DeformWave.x + (1.0 - sawtooth(off + u_DeformWave.z + (u_Time * u_DeformW" -"ave.w))) * u_DeformWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\t" -"deformed.xyz += offset;\r\n\t}\r\n else if (u_DeformGen == DGEN_BULGE)\r\n" -"\t{\r\n\t\tfloat bulgeWidth = u_DeformBulge.x;\r\n\t\tfloat bulgeHeight = u" -"_DeformBulge.y;\r\n\t\tfloat bulgeSpeed = u_DeformBulge.z;\r\n\r\n\t\tfloat" -" now = u_Time * bulgeSpeed;\r\n\r\n\t\tfloat off = (M_PI * 0.25) * st.x * b" -"ulgeWidth + now;\r\n\t\tfloat scale = sin(off) * bulgeHeight;\r\n\t\tvec3 o" -"ffset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\r\n\t" -"return deformed;\r\n}\r\n#endif\r\n\r\n#if defined(USE_TCGEN)\r\nvec2 GenTe" -"xCoords(int TCGen, vec4 position, vec3 normal, mat4 texMatrix, vec4 TCGenVe" -"ctor0, vec4 TCGenVector1)\r\n{\r\n\tvec2 tex = vec2(0.0);\r\n\r\n\tif (TCGe" -"n == TCGEN_LIGHTMAP)\r\n\t{\r\n\t\ttex = attr_TexCoord1.st;\r\n\t}\r\n\tels" -"e if (TCGen == TCGEN_TEXTURE)\r\n\t{\r\n\t\ttex = attr_TexCoord0.st;\r\n\t}" -"\r\n\telse if (TCGen == TCGEN_ENVIRONMENT_MAPPED)\r\n\t{\r\n\t\tvec3 viewer" -" = normalize(u_ViewOrigin - position.xyz);\r\n\r\n\t\tfloat d = dot(normal," -" viewer);\r\n\r\n\t\tvec3 reflected = normal * 2.0 * d - viewer;\r\n\r\n\t" -"\ttex.s = 0.5 + reflected.y * 0.5;\r\n\t\ttex.t = 0.5 - reflected.z * 0.5;" -"\r\n\t}\r\n\telse if (TCGen == TCGEN_VECTOR)\r\n\t{\r\n\t\ttex.s = dot(posi" -"tion.xyz, TCGenVector0.xyz);\r\n\t\ttex.t = dot(position.xyz, TCGenVector1." -"xyz);\r\n\t}\r\n\telse if (TCGen == TCGEN_DLIGHT)\r\n\t{\r\n\t vec3 dist =" -" TCGenVector0.xyz - position.xyz;\r\n\t \r\n\t if (dot(dist, normal) < 0)" -"\r\n\t {\r\n\t var_DlightMod = 0;\r\n\t }\r\n\t else\r\n\t {\r\n\t " -" float diffz = abs(dist.z);\r\n float radius = 1.0 / TCGenVector0.a;" -"\r\n\t \r\n\t if (diffz > radius)\r\n {\r\n var_DlightMod" -" = 0;\r\n }\r\n else\r\n {\r\n tex = vec2(0.5) + dist" -".xy * TCGenVector0.a;\r\n\r\n if (diffz < radius * 0.5)\r\n {" -"\r\n var_DlightMod = 1.0;\r\n }\r\n else\r\n " -"{\r\n var_DlightMod = 2.0 * (radius - diffz) * TCGenVector0.a;\r\n" -" }\r\n }\r\n\t }\r\n\t}\r\n\t\r\n\treturn tex;\r\n}\r\n#endif" -"\r\n\r\nvoid\tmain()\r\n{\r\n\tvec4 position;\r\n\tvec3 normal;\r\n\r\n#if " -"defined(USE_VERTEX_ANIMATION)\r\n if (u_VertexLerp > 0.0)\r\n {\r\n po" -"sition = mix(attr_Position, attr_Position2, u_VertexLerp);\r\n normal = " -"mix(attr_Normal, attr_Normal2, u_VertexLerp);\r\n normal = normalize(nor" -"mal);\r\n }\r\n else\r\n#endif\r\n {\r\n position = attr_Position;\r" -"\n normal = attr_Normal;\r\n }\r\n\r\n#if defined(USE_DEFORM_VERTEXES)" -"\r\n position = DeformPosition(position, normal, attr_TexCoord0.st);\r\n#e" -"ndif\r\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * position;\r\n\r\n" -" {\r\n vec4 tex = vec4(1.0, 1.0, 1.0, 0.0);\r\n\r\n#if defined(USE_TCGE" -"N)\r\n tex.st = GenTexCoords(u_TCGen0, position, normal, u_Texture0Matri" -"x, u_TCGen0Vector0, u_TCGen0Vector1);\r\n#else\r\n tex.st = attr_TexCoor" -"d0.st;\r\n#endif\r\n \r\n var_Tex1 = (u_Texture0Matrix * tex).st;\r\n" -"\r\n if (u_Texture0Matrix[3][0] != 0)\r\n {\r\n var_Tex1.s += si" -"n(((position.x + position.z) * 1.0 / 128.0 * 0.125 + u_Texture0Matrix[3][1]" -") * 2.0 * M_PI) * u_Texture0Matrix[3][0];\r\n var_Tex1.t += sin((posit" -"ion.y * 1.0 / 128.0 * 0.125 + u_Texture0Matrix[3][1]) * 2.0 * M_PI) * u_Tex" -"ture0Matrix[3][0];\r\n }\r\n }\r\n\r\n var_Tex2 = attr_TexCoord1.st;\r" -"\n\r\n if (u_ColorGen == CGEN_IDENTITY)\r\n {\r\n var_Color.rgb = vec3" -"(1.0);\r\n }\r\n\telse if (u_ColorGen == CGEN_LIGHTING_DIFFUSE)\r\n\t{\r\n" -"\t\tfloat incoming = dot(attr_Normal, u_LightDir);\r\n\r\n\t\tif (incoming " -"<= 0)\r\n\t\t{\r\n\t\t\tvar_Color.rgb = u_AmbientLight;\r\n\t\t}\r\n\t\tels" -"e\r\n\t\t{\r\n\t\t var_Color.rgb = min(u_AmbientLight + u_DirectedLight * " -"incoming, vec3(1));\r\n\t\t}\r\n\t}\r\n\telse if (u_ColorGen == CGEN_EXACT_" -"VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb = attr_Color.rgb;\r\n\t}\r\n\telse if (" -"u_ColorGen == CGEN_VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb = attr_Color.rgb * u" -"_Color.rgb;\r\n\t}\r\n\telse if (u_ColorGen == CGEN_ONE_MINUS_VERTEX)\r\n\t" -"{\r\n\t\tvar_Color.rgb = (vec3(1.0) - attr_Color.rgb) * u_Color.rgb;\r\n\t}" -"\r\n\telse if (u_ColorGen == CGEN_DLIGHT)\r\n\t{\r\n\t var_Color.rgb = u_C" -"olor.rgb * var_DlightMod;\r\n\t}\r\n\telse\r\n\t{\r\n\t\tvar_Color.rgb = u_" -"Color.rgb;\r\n\t}\r\n\r\n if (u_AlphaGen == AGEN_IDENTITY)\r\n {\r\n v" -"ar_Color.a = 1.0;\r\n }\r\n\telse if (u_AlphaGen == AGEN_LIGHTING_SPECULAR" -")\r\n\t{\r\n\t\tvec3 lightDir = vec3(-960.0, -1980.0, 96.0) - position.xyz;" -"\r\n\t\tlightDir = normalize(lightDir);\r\n\r\n\t\tfloat d = dot(attr_Norma" -"l, lightDir);\r\n\t\tvec3 reflected = attr_Normal * 2.0 * d - lightDir;\r\n" -"\r\n\t\tvec3 viewer = u_ViewOrigin - position.xyz;\r\n\t\tfloat ilength = 1" -".0 / length(viewer);\r\n\r\n\t\tfloat l = dot(reflected, viewer);\r\n\t\tl " -"*= ilength;\r\n\r\n\t\tif (l < 0.0)\r\n\t\t{\r\n\t\t\tvar_Color.a = 0.0;\r" -"\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tl = l*l;\r\n\t\t\tl = l*l;\r\n\t\t\tv" -"ar_Color.a = min(l, 1.0);\r\n\t\t}\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_" -"VERTEX)\r\n\t{\r\n\t\tvar_Color.a = attr_Color.a;\r\n\t}\r\n\telse if (u_Al" -"phaGen == AGEN_ONE_MINUS_VERTEX)\r\n\t{\r\n\t\tvar_Color.a = 1.0 - attr_Col" -"or.a;\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_PORTAL)\r\n\t{\r\n\t\tfloat l" -"en;\r\n\t\tvec3 v;\r\n\r\n\t\tv = position.xyz - u_ViewOrigin;\r\n\t\tlen =" -" length(v);\r\n\r\n\t\tlen /= u_PortalRange;\r\n\r\n\t\tvar_Color.a = clamp" -"(len, 0.0, 1.0);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tvar_Color.a = u_Color.a;\r" -"\n\t}\r\n\r\n#if defined (USE_FOG)\r\n if (u_FogAdjustColors != 0) \r\n\t{" -"\r\n\t\tfloat s = dot(position.xyz, u_FogDistance.xyz) + u_FogDistance.a;\r" -"\n\t\tfloat t = dot(position.xyz, u_FogDepth.xyz) + u_FogDepth.a;\r\n\t\t\r" -"\n\t\tif (s < 0.0 || t < 0.0 || (u_FogEyeT < 0.0 && t < 1.0) )\r\n\t\t{\r\n" -"\t\t s = 0.0;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t if (u_FogEyeT < 0.0)" -"\r\n\t\t {\r\n\t\t s *= t / (t - u_FogEyeT);\r\n\t\t }\r\n\r\n\t\t " -"s *= 8.0;\r\n\t\t \t\t \r\n\t\t s = clamp(s, 0.0, 1.0);\r\n\t\t \r\n\t" -"\t s = sqrt(s);\r\n\t\t}\r\n\t\t\r\n\t\tif (u_FogAdjustColors == 1)\r\n " -" {\r\n var_Color.xyz *= (1.0 - s);\r\n }\r\n else if (u_FogAdjus" -"tColors == 2)\r\n {\r\n var_Color.a *= (1.0 - s);\r\n }\r\n e" -"lse if (u_FogAdjustColors == 3)\r\n {\r\n var_Color *= (1.0 - s);\r" -"\n }\r\n else if (u_FogAdjustColors == 4)\r\n {\r\n var_Color" -".xyz = u_Color.xyz;\r\n var_Color.a = u_Color.a * s;\r\n }\r\n }\r" -"\n#endif\r\n}\r\n"; +"attribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoord0;\r\nattribut" +"e vec4 attr_TexCoord1;\r\nattribute vec3 attr_Normal;\r\nattribute vec4 att" +"r_Color;\r\n\r\n#if defined(USE_VERTEX_ANIMATION)\r\nattribute vec4 attr_Po" +"sition2;\r\nattribute vec3 attr_Normal2;\r\n#endif\r\n\r\nuniform mat4 u_" +"Texture0Matrix;\r\nuniform vec3 u_ViewOrigin;\r\n\r\n#if defined(USE_TCGE" +"N)\r\nuniform int u_TCGen0;\r\nuniform vec4 u_TCGen0Vector0;\r\nunifor" +"m vec4 u_TCGen0Vector1;\r\n#endif\r\n\r\n#if defined(USE_FOG)\r\nuniform " +"vec4 u_FogDistance;\r\nuniform vec4 u_FogDepth;\r\nuniform float u_Fog" +"EyeT;\r\nuniform int u_FogAdjustColors;\r\n#endif\r\n\r\n#if defined(USE" +"_DEFORM_VERTEXES)\r\nuniform int u_DeformGen;\r\nuniform vec4 u_Deform" +"Wave;\r\nuniform vec3 u_DeformBulge;\r\nuniform float u_DeformSpread;\r" +"\n#endif\r\n\r\nuniform float u_Time;\r\nuniform int u_ColorGen;\r\nuni" +"form int u_AlphaGen;\r\nuniform vec4 u_Color;\r\nuniform mat4 u_Mode" +"lViewProjectionMatrix;\r\nuniform vec3 u_AmbientLight;\r\nuniform vec3 " +"u_DirectedLight;\r\nuniform vec3 u_LightDir;\r\n\r\nuniform float u_Port" +"alRange;\r\n\r\n#if defined(USE_VERTEX_ANIMATION)\r\nuniform float u_Verte" +"xLerp;\r\n#endif\r\n\r\nvarying vec2 var_Tex1;\r\nvarying vec2 var_Tex2" +";\r\nvarying vec4 var_Color;\r\n\r\n#if defined(USE_DEFORM_VERTEXES)\r\nf" +"loat triangle(float x)\r\n{\r\n\treturn max(1.0 - abs(x), 0);\r\n}\r\n\r\nf" +"loat sawtooth(float x)\r\n{\r\n\treturn x - floor(x);\r\n}\r\n\r\nvec4 Defo" +"rmPosition(const vec4 pos, const vec3 normal, const vec2 st)\r\n{\r\n\tvec4" +" deformed = pos;\r\n\r\n\tif (u_DeformGen == DGEN_WAVE_SIN)\r\n\t{\r\n\t\tf" +"loat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u" +"_DeformWave.x + sin((off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * 2" +".0 * M_PI) * u_DeformWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t" +"\tdeformed.xyz += offset;\r\n\t}\r\n\telse if (u_DeformGen == DGEN_WAVE_SQU" +"ARE)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r" +"\n\t\tfloat scale = u_DeformWave.x + sign(sin((off + u_DeformWave.z + (u_T" +"ime * u_DeformWave.w)) * 2.0 * M_PI)) * u_DeformWave.y;\r\n\t\tvec3 offset " +"= normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\telse if (u" +"_DeformGen == DGEN_WAVE_TRIANGLE)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y " +"+ pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave.x + triangle(" +"off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * u_DeformWave.y;\r\n\t\t" +"vec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n" +"\telse if (u_DeformGen == DGEN_WAVE_SAWTOOTH)\r\n\t{\r\n\t\tfloat off = (po" +"s.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave.x " +" + sawtooth(off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * u_DeformWav" +"e.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset" +";\r\n\t}\r\n\telse if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)\r\n\t{\r" +"\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat sc" +"ale = u_DeformWave.x + (1.0 - sawtooth(off + u_DeformWave.z + (u_Time * u_D" +"eformWave.w))) * u_DeformWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r" +"\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\telse if (u_DeformGen == DGEN_BULG" +"E)\r\n\t{\r\n\t\tfloat bulgeWidth = u_DeformBulge.x;\r\n\t\tfloat bulgeHeig" +"ht = u_DeformBulge.y;\r\n\t\tfloat bulgeSpeed = u_DeformBulge.z;\r\n\r\n\t" +"\tfloat now = u_Time * bulgeSpeed;\r\n\r\n\t\tfloat off = (M_PI * 0.25) * s" +"t.x * bulgeWidth + now;\r\n\t\tfloat scale = sin(off) * bulgeHeight;\r\n\t" +"\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r" +"\n\r\n\treturn deformed;\r\n}\r\n#endif\r\n\r\n#if defined(USE_TCGEN)\r\nve" +"c2 GenTexCoords(int TCGen, vec4 position, vec3 normal, mat4 texMatrix, vec4" +" TCGenVector0, vec4 TCGenVector1)\r\n{\r\n\tvec2 tex = vec2(0.0);\r\n\r\n\t" +"if (TCGen == TCGEN_LIGHTMAP)\r\n\t{\r\n\t\ttex = attr_TexCoord1.st;\r\n\t}" +"\r\n\telse if (TCGen == TCGEN_TEXTURE)\r\n\t{\r\n\t\ttex = attr_TexCoord0.s" +"t;\r\n\t}\r\n\telse if (TCGen == TCGEN_ENVIRONMENT_MAPPED)\r\n\t{\r\n\t\tve" +"c3 viewer = normalize(u_ViewOrigin - position.xyz);\r\n\r\n\t\tfloat d = do" +"t(normal, viewer);\r\n\r\n\t\tvec3 reflected = normal * 2.0 * d - viewer;\r" +"\n\r\n\t\ttex.s = 0.5 + reflected.y * 0.5;\r\n\t\ttex.t = 0.5 - reflected.z" +" * 0.5;\r\n\t}\r\n\telse if (TCGen == TCGEN_VECTOR)\r\n\t{\r\n\t\ttex.s = d" +"ot(position.xyz, TCGenVector0.xyz);\r\n\t\ttex.t = dot(position.xyz, TCGenV" +"ector1.xyz);\r\n\t}\r\n\t\r\n\treturn tex;\r\n}\r\n#endif\r\n\r\nvoid main(" +")\r\n{\r\n\tvec4 position;\r\n\tvec3 normal;\r\n\tvec4 tex;\r\n\r\n#if defi" +"ned(USE_VERTEX_ANIMATION)\r\n\tif (u_VertexLerp > 0.0)\r\n\t{\r\n\t\tpositi" +"on = mix(attr_Position, attr_Position2, u_VertexLerp);\r\n\t\tnormal = mix(" +"attr_Normal, attr_Normal2, u_VertexLerp);\r\n\t\tnormal = normalize(normal)" +";\r\n\t}\r\n\telse\r\n#endif\r\n\t{\r\n\t\tposition = attr_Position;\r\n\t" +"\tnormal = attr_Normal;\r\n\t}\r\n\r\n#if defined(USE_DEFORM_VERTEXES)\r\n" +"\tposition = DeformPosition(position, normal, attr_TexCoord0.st);\r\n#endif" +"\r\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * position;\r\n\r\n\r\n" +"\ttex = vec4(1.0, 1.0, 1.0, 0.0);\r\n\r\n#if defined(USE_TCGEN)\r\n\ttex.st" +" = GenTexCoords(u_TCGen0, position, normal, u_Texture0Matrix, u_TCGen0Vecto" +"r0, u_TCGen0Vector1);\r\n#else\r\n\ttex.st = attr_TexCoord0.st;\r\n#endif\r" +"\n \r\n\tvar_Tex1 = (u_Texture0Matrix * tex).st;\r\n\r\n\tif (u_Texture0" +"Matrix[3][0] != 0)\r\n\t{\r\n\t\tvar_Tex1.s += sin(((position.x + position." +"z) * 1.0 / 128.0 * 0.125 + u_Texture0Matrix[3][1]) * 2.0 * M_PI) * u_Textur" +"e0Matrix[3][0];\r\n\t\tvar_Tex1.t += sin((position.y * 1.0 / 128.0 * 0.125 " +"+ u_Texture0Matrix[3][1]) * 2.0 * M_PI) * u_Texture0Matrix[3][0];\r\n\t}\r" +"\n\r\n\tvar_Tex2 = attr_TexCoord1.st;\r\n\r\n\tif (u_ColorGen == CGEN_IDENT" +"ITY)\r\n\t{\r\n\t\tvar_Color.rgb = vec3(1.0);\r\n\t}\r\n\telse if (u_ColorG" +"en == CGEN_LIGHTING_DIFFUSE)\r\n\t{\r\n\t\tfloat incoming = dot(attr_Normal" +", u_LightDir);\r\n\r\n\t\tif (incoming <= 0)\r\n\t\t{\r\n\t\t\tvar_Color.rg" +"b = u_AmbientLight;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tvar_Color.rgb = " +"min(u_AmbientLight + u_DirectedLight * incoming, vec3(1));\r\n\t\t}\r\n\t}" +"\r\n\telse if (u_ColorGen == CGEN_EXACT_VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb" +" = attr_Color.rgb;\r\n\t}\r\n\telse if (u_ColorGen == CGEN_VERTEX)\r\n\t{\r" +"\n\t\tvar_Color.rgb = attr_Color.rgb * u_Color.rgb;\r\n\t}\r\n\telse if (u_" +"ColorGen == CGEN_ONE_MINUS_VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb = (vec3(1.0)" +" - attr_Color.rgb) * u_Color.rgb;\r\n\t}\r\n\telse\r\n\t{\r\n\t\tvar_Color." +"rgb = u_Color.rgb;\r\n\t}\r\n\r\n\tif (u_AlphaGen == AGEN_IDENTITY)\r\n\t{" +"\r\n\t\tvar_Color.a = 1.0;\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_LIGHTING" +"_SPECULAR)\r\n\t{\r\n\t\tvec3 lightDir = vec3(-960.0, -1980.0, 96.0) - posi" +"tion.xyz;\r\n\t\tlightDir = normalize(lightDir);\r\n\r\n\t\tfloat d = dot(a" +"ttr_Normal, lightDir);\r\n\t\tvec3 reflected = attr_Normal * 2.0 * d - ligh" +"tDir;\r\n\r\n\t\tvec3 viewer = u_ViewOrigin - position.xyz;\r\n\t\tfloat il" +"ength = 1.0 / length(viewer);\r\n\r\n\t\tfloat l = dot(reflected, viewer);" +"\r\n\t\tl *= ilength;\r\n\r\n\t\tif (l < 0.0)\r\n\t\t{\r\n\t\t\tvar_Color.a" +" = 0.0;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tl = l*l;\r\n\t\t\tl = l*l;\r" +"\n\t\t\tvar_Color.a = min(l, 1.0);\r\n\t\t}\r\n\t}\r\n\telse if (u_AlphaGen" +" == AGEN_VERTEX)\r\n\t{\r\n\t\tvar_Color.a = attr_Color.a;\r\n\t}\r\n\telse" +" if (u_AlphaGen == AGEN_ONE_MINUS_VERTEX)\r\n\t{\r\n\t\tvar_Color.a = 1.0 -" +" attr_Color.a;\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_PORTAL)\r\n\t{\r\n\t" +"\tfloat len;\r\n\t\tvec3 v;\r\n\r\n\t\tv = position.xyz - u_ViewOrigin;\r\n" +"\t\tlen = length(v);\r\n\r\n\t\tlen /= u_PortalRange;\r\n\r\n\t\tvar_Color." +"a = clamp(len, 0.0, 1.0);\r\n\t}\r\n\telse\r\n\t{\r\n\t\tvar_Color.a = u_Co" +"lor.a;\r\n\t}\r\n\r\n#if defined (USE_FOG)\r\n\tif (u_FogAdjustColors != AC" +"FF_NONE) \r\n\t{\r\n\t\tfloat s = dot(position.xyz, u_FogDistance.xyz) + u_" +"FogDistance.a;\r\n\t\tfloat t = dot(position.xyz, u_FogDepth.xyz) + u_FogDe" +"pth.a;\r\n\t\t\r\n\t\tif (s < 0.0 || t < 0.0 || (u_FogEyeT < 0.0 && t < 1.0" +") )\r\n\t\t{\r\n\t\t\ts = 0.0;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tif (u" +"_FogEyeT < 0.0)\r\n\t\t\t{\r\n\t\t\t\ts *= t / (t - u_FogEyeT);\r\n\t\t\t}" +"\r\n\r\n\t\t\ts *= 8.0;\r\n\t\t\t\t \r\n\t\t\ts = clamp(s, 0.0, 1.0);\r\n" +"\r\n\t\t\ts = 1.0 - sqrt(s);\r\n\t\t}\r\n\t\t\r\n\t\tif (u_FogAdjustColors " +"== ACFF_MODULATE_RGB)\r\n\t\t{\r\n\t\t\tvar_Color.xyz *= s;\r\n\t\t}\r\n\t" +"\telse if (u_FogAdjustColors == ACFF_MODULATE_ALPHA)\r\n\t\t{\r\n\t\t\tvar_" +"Color.a *= s;\r\n\t\t}\r\n\t\telse if (u_FogAdjustColors == ACFF_MODULATE_R" +"GBA)\r\n\t\t{\r\n\t\t\tvar_Color *= s;\r\n\t\t}\r\n\t}\r\n#endif\r\n}\r\n"; static const char *fallbackGenericShader_fp = -"uniform sampler2D u_Texture0Map;\r\nuniform sampler2D u_Texture1Map;" -"\r\nuniform int u_Texture1Env;\r\n\r\n#if defined(USE_FOG)\r\nunif" -"orm int u_FogAdjustColors;\r\n#endif\r\n\r\nvarying vec2 v" -"ar_Tex1;\r\nvarying vec2 var_Tex2;\r\nvarying vec4 var_Colo" -"r;\r\n\r\n\r\nvoid\tmain()\r\n{\r\n\tvec4 color;\r\n\r\n#if defined(USE_FOG" -")\r\n if (u_FogAdjustColors == 4)\r\n {\r\n color = var_Color;\r\n }" -"\r\n else\r\n#endif\r\n {\r\n if (u_Texture1Env != 2)\r\n {\r\n " -" color = texture2D(u_Texture0Map, var_Tex1);\r\n }\r\n \r\n if (" -"u_Texture1Env != 0)\r\n {\r\n vec4 color2 = texture2D(u_Texture1Map" -", var_Tex2);\r\n\r\n if (u_Texture1Env == 1) // GL_MODULATE\r\n {" -"\r\n color *= color2;\r\n }\r\n else if (u_Texture1Env == " -"4) // GL_ADD\r\n {\r\n color += color2;\r\n }\r\n els" -"e // if (u_Texture1Env == 2) GL_REPLACE\r\n {\r\n color = color" -"2;\r\n }\r\n }\r\n\r\n color *= var_Color;\r\n }\r\n\r\n\tgl_Fr" -"agColor = color;\r\n}\r\n"; +"uniform sampler2D u_Texture0Map;\r\nuniform sampler2D u_Texture1Map;\r\nuni" +"form int u_Texture1Env;\r\n\r\nvarying vec2 var_Tex1;\r\nvarying" +" vec2 var_Tex2;\r\nvarying vec4 var_Color;\r\n\r\n\r\nvoid main()" +"\r\n{\r\n\tvec4 color;\r\n\r\n\tif (u_Texture1Env != 2)\r\n\t{\r\n\t\tcolor" +" = texture2D(u_Texture0Map, var_Tex1);\r\n\t}\r\n\r\n\tif (u_Texture1Env !=" +" 0)\r\n\t{\r\n\t\tvec4 color2 = texture2D(u_Texture1Map, var_Tex2);\r\n\r\n" +"\t\tif (u_Texture1Env == GL_MODULATE)\r\n\t\t{\r\n\t\t\tcolor *= color2;\r" +"\n\t\t}\r\n\t\t\telse if (u_Texture1Env == GL_ADD)\r\n\t\t{\r\n\t\t\tcolor " +"+= color2;\r\n\t\t}\r\n\t\t\telse // if (u_Texture1Env == GL_REPLACE)\r\n\t" +"\t{\r\n\t\t\tcolor = color2;\r\n\t\t}\r\n\t}\r\n\r\n\tcolor *= var_Color;\r" +"\n\r\n\tgl_FragColor = color;\r\n}\r\n"; + +static const char *fallbackLightmappedShader_vp = +"#version 120\r\n\r\n#ifndef M_PI\r\n#define M_PI 3.14159265358979323846f\r" +"\n#endif\r\n\r\nattribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoo" +"rd0;\r\nattribute vec4 attr_TexCoord1;\r\n\r\nuniform mat4 u_Texture0Matr" +"ix;\r\nuniform mat4 u_ModelViewProjectionMatrix;\r\n\r\nvarying vec2 va" +"r_Tex1;\r\nvarying vec2 var_Tex2;\r\n\r\nvoid main()\r\n{\r\n\tvec4 tex =" +" vec4(1, 1, 1, 0);\r\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * att" +"r_Position;\r\n\r\n\ttex.st = attr_TexCoord0.st;\r\n \r\n\tvar_Tex1 = (u" +"_Texture0Matrix * tex).st;\r\n\r\n\tif (u_Texture0Matrix[3][0] != 0)\r\n\t{" +"\r\n\t\tvar_Tex1.s += sin(((attr_Position.x + attr_Position.z) * 1.0 / 128." +"0 * 0.125 + u_Texture0Matrix[3][1]) * 2.0 * M_PI) * u_Texture0Matrix[3][0];" +"\r\n\t\tvar_Tex1.t += sin((attr_Position.y * 1.0 / 128.0 * 0.125 + u_Textur" +"e0Matrix[3][1]) * 2.0 * M_PI) * u_Texture0Matrix[3][0];\r\n\t}\r\n\r\n\tvar" +"_Tex2 = attr_TexCoord1.st;\r\n}\r\n"; + +static const char *fallbackLightmappedShader_fp = +"#version 120\r\n\r\nuniform sampler2D u_Texture0Map;\r\nuniform sampler2" +"D u_Texture1Map;\r\n\r\nvarying vec2 var_Tex1;\r\nvarying vec2 " +" var_Tex2;\r\n\r\n\r\nvoid\tmain()\r\n{\r\n\tvec4 color, light;\r\n\r" +"\n\tcolor = texture2D(u_Texture0Map, var_Tex1);\r\n\tlight = texture2D(u_Te" +"xture1Map, var_Tex2);\r\n\r\n\tgl_FragColor = color * light;\r\n}\r\n"; + +static const char *fallbackTextureOnlyShader_vp = +"#version 120\r\n\r\nattribute vec4 attr_Position;\r\nattribute vec4 attr_Te" +"xCoord0;\r\n\r\nuniform mat4 u_ModelViewProjectionMatrix;\r\n\r\nvarying " +"vec2 var_Tex1;\r\n\r\n\r\nvoid main()\r\n{\r\n\tgl_Position = u_ModelView" +"ProjectionMatrix * attr_Position;\r\n\tvar_Tex1 = attr_TexCoord0.st;\r\n}\r" +"\n"; + +static const char *fallbackTextureOnlyShader_fp = +"#version 120\r\n\r\nuniform sampler2D u_Texture0Map;\r\n\r\nvarying vec2" +" var_Tex1;\r\n\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor = texture2" +"D(u_Texture0Map, var_Tex1);\r\n}\r\n"; + +static const char *fallbackFogPassShader_vp = +"attribute vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\nattribute" +" vec4 attr_TexCoord0;\r\n\r\n//#if defined(USE_VERTEX_ANIMATION)\r\nattrib" +"ute vec4 attr_Position2;\r\nattribute vec3 attr_Normal2;\r\n//#endif\r\n" +"\r\nuniform vec4 u_FogDistance;\r\nuniform vec4 u_FogDepth;\r\nunifor" +"m float u_FogEyeT;\r\n\r\n//#if defined(USE_DEFORM_VERTEXES)\r\nuniform i" +"nt u_DeformGen;\r\nuniform vec4 u_DeformWave;\r\nuniform vec3 u_D" +"eformBulge;\r\nuniform float u_DeformSpread;\r\n//#endif\r\n\r\nuniform f" +"loat u_Time;\r\nuniform vec4 u_Color;\r\nuniform mat4 u_ModelViewPr" +"ojectionMatrix;\r\n\r\n//#if defined(USE_VERTEX_ANIMATION)\r\nuniform float" +" u_VertexLerp;\r\n//#endif\r\n\r\nvarying vec4 var_Color;\r\n\r\n//#if" +" defined(USE_DEFORM_VERTEXES)\r\nfloat triangle(float x)\r\n{\r\n\treturn m" +"ax(1.0 - abs(x), 0);\r\n}\r\n\r\nfloat sawtooth(float x)\r\n{\r\n\treturn x" +" - floor(x);\r\n}\r\n\r\nvec4 DeformPosition(const vec4 pos, const vec3 nor" +"mal, const vec2 st)\r\n{\r\n\tvec4 deformed = pos;\r\n\r\n\tif (u_DeformGen" +" == DGEN_WAVE_SIN)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_De" +"formSpread;\r\n\t\tfloat scale = u_DeformWave.x + sin((off + u_DeformWave." +"z + (u_Time * u_DeformWave.w)) * 2.0 * M_PI) * u_DeformWave.y;\r\n\t\tvec3 " +"offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\tels" +"e if (u_DeformGen == DGEN_WAVE_SQUARE)\r\n\t{\r\n\t\tfloat off = (pos.x + p" +"os.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave.x + sign" +"(sin((off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * 2.0 * M_PI)) * u_" +"DeformWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz " +"+= offset;\r\n\t}\r\n\telse if (u_DeformGen == DGEN_WAVE_TRIANGLE)\r\n\t{\r" +"\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat sc" +"ale = u_DeformWave.x + triangle(off + u_DeformWave.z + (u_Time * u_DeformW" +"ave.w)) * u_DeformWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\td" +"eformed.xyz += offset;\r\n\t}\r\n\telse if (u_DeformGen == DGEN_WAVE_SAWTOO" +"TH)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n" +"\t\tfloat scale = u_DeformWave.x + sawtooth(off + u_DeformWave.z + (u_Time" +" * u_DeformWave.w)) * u_DeformWave.y;\r\n\t\tvec3 offset = normal * scale;" +"\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\telse if (u_DeformGen == DGE" +"N_WAVE_INVERSE_SAWTOOTH)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos.z) " +"* u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave.x + (1.0 - sawtooth(off" +" + u_DeformWave.z + (u_Time * u_DeformWave.w))) * u_DeformWave.y;\r\n\t\tve" +"c3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\t" +"else if (u_DeformGen == DGEN_BULGE)\r\n\t{\r\n\t\tfloat bulgeWidth = u_Defo" +"rmBulge.x;\r\n\t\tfloat bulgeHeight = u_DeformBulge.y;\r\n\t\tfloat bulgeSp" +"eed = u_DeformBulge.z;\r\n\r\n\t\tfloat now = u_Time * bulgeSpeed;\r\n\r\n" +"\t\tfloat off = (M_PI * 0.25) * st.x * bulgeWidth + now;\r\n\t\tfloat scale" +" = sin(off) * bulgeHeight;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\t" +"deformed.xyz += offset;\r\n\t}\r\n\r\n\treturn deformed;\r\n}\r\n//#endif\r" +"\n\r\n\r\nvoid\tmain()\r\n{\r\n\tvec4 position;\r\n\tvec3 normal;\r\n\r\n//" +"#if defined(USE_VERTEX_ANIMATION)\r\n\tif (u_VertexLerp > 0.0)\r\n\t{\r\n\t" +"\tposition = mix(attr_Position, attr_Position2, u_VertexLerp);\r\n\t\tnorma" +"l = mix(attr_Normal, attr_Normal2, u_VertexLerp);\r\n\t\tnormal = normalize" +"(normal);\r\n\t}\r\n\telse\r\n//#endif\r\n\t{\r\n\t\tposition = attr_Positi" +"on;\r\n\t\tnormal = attr_Normal;\r\n\t}\r\n\r\n//#if defined(USE_DEFORM_VER" +"TEXES)\r\n\tposition = DeformPosition(position, normal, attr_TexCoord0.st);" +"\r\n//#endif\r\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * position;" +"\r\n\r\n\t{\r\n\t\tfloat s = dot(position.xyz, u_FogDistance.xyz) + u_FogDi" +"stance.a;\r\n\t\tfloat t = dot(position.xyz, u_FogDepth.xyz) + u_FogDepth.a" +";\r\n\r\n\t\tif (s < 0.0 || t < 0.0 || (u_FogEyeT < 0.0 && t < 1.0) )\r\n\t" +"\t{\r\n\t\t\ts = 0.0;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tif (u_FogEyeT " +"< 0.0)\r\n\t\t\t{\r\n\t\t\t\ts *= t / (t - u_FogEyeT);\r\n\t\t\t}\r\n\r\n\t" +"\t\ts *= 8.0;\r\n\t\t \r\n\t\t\ts = clamp(s, 0.0, 1.0);\r\n\r\n\t\t\ts = s" +"qrt(s);\r\n\t\t}\r\n\r\n\t\tvar_Color.xyz = u_Color.xyz;\r\n\t\tvar_Color.a" +" = u_Color.a * s;\r\n\t}\r\n}\r\n"; + +static const char *fallbackFogPassShader_fp = +"varying vec4 var_Color;\r\n\r\n\r\nvoid\tmain()\r\n{\r\n\tgl_FragCo" +"lor = var_Color;\r\n}\r\n"; + +static const char *fallbackDlightShader_vp = +"attribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoord0;\r\nattribut" +"e vec3 attr_Normal;\r\n\r\nattribute vec4 attr_Position2;\r\nattribute vec3" +" attr_Normal2;\r\n\r\nuniform vec4 u_DlightInfo;\r\n\r\nuniform int u_" +"DeformGen;\r\nuniform vec4 u_DeformWave;\r\nuniform vec3 u_DeformBulge;" +"\r\nuniform float u_DeformSpread;\r\n\r\nuniform float u_Time;\r\nuniform" +" vec4 u_Color;\r\nuniform mat4 u_ModelViewProjectionMatrix;\r\n\r\nunif" +"orm float u_VertexLerp;\r\n\r\nvarying vec2 var_Tex1;\r\nvarying vec4 " +"var_Color;\r\n\r\nfloat triangle(float x)\r\n{\r\n\treturn max(1.0 - abs(x)" +", 0);\r\n}\r\n\r\nfloat sawtooth(float x)\r\n{\r\n\treturn x - floor(x);\r" +"\n}\r\n\r\nvec4 DeformPosition(const vec4 pos, const vec3 normal, const vec" +"2 st)\r\n{\r\n\tvec4 deformed = pos;\r\n\r\n\tif (u_DeformGen == DGEN_WAVE_" +"SIN)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r" +"\n\t\tfloat scale = u_DeformWave.x + sin((off + u_DeformWave.z + (u_Time *" +" u_DeformWave.w)) * 2.0 * M_PI) * u_DeformWave.y;\r\n\t\tvec3 offset = norm" +"al * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\telse if (u_Defor" +"mGen == DGEN_WAVE_SQUARE)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos.z)" +" * u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave.x + sign(sin((off + u" +"_DeformWave.z + (u_Time * u_DeformWave.w)) * 2.0 * M_PI)) * u_DeformWave.y;" +"\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r" +"\n\t}\r\n\telse if (u_DeformGen == DGEN_WAVE_TRIANGLE)\r\n\t{\r\n\t\tfloat " +"off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u_Defo" +"rmWave.x + triangle(off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * u_" +"DeformWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz " +"+= offset;\r\n\t}\r\n\telse if (u_DeformGen == DGEN_WAVE_SAWTOOTH)\r\n\t{\r" +"\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat sc" +"ale = u_DeformWave.x + sawtooth(off + u_DeformWave.z + (u_Time * u_DeformW" +"ave.w)) * u_DeformWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\td" +"eformed.xyz += offset;\r\n\t}\r\n\telse if (u_DeformGen == DGEN_WAVE_INVERS" +"E_SAWTOOTH)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_DeformSpr" +"ead;\r\n\t\tfloat scale = u_DeformWave.x + (1.0 - sawtooth(off + u_DeformWa" +"ve.z + (u_Time * u_DeformWave.w))) * u_DeformWave.y;\r\n\t\tvec3 offset = n" +"ormal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\telse if (u_De" +"formGen == DGEN_BULGE)\r\n\t{\r\n\t\tfloat bulgeWidth = u_DeformBulge.x;\r" +"\n\t\tfloat bulgeHeight = u_DeformBulge.y;\r\n\t\tfloat bulgeSpeed = u_Defo" +"rmBulge.z;\r\n\r\n\t\tfloat now = u_Time * bulgeSpeed;\r\n\r\n\t\tfloat off" +" = (M_PI * 0.25) * st.x * bulgeWidth + now;\r\n\t\tfloat scale = sin(off) *" +" bulgeHeight;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz " +"+= offset;\r\n\t}\r\n\r\n\treturn deformed;\r\n}\r\n\r\n\r\nvoid main()\r\n" +"{\r\n\tvec4 position;\r\n\tvec3 normal;\r\n\tvec3 dist;\r\n\tvec2 tex;\r\n" +"\tfloat dlightmod;\r\n\r\n\tif (u_VertexLerp > 0.0)\r\n\t{\r\n\t\tposition " +"= mix(attr_Position, attr_Position2, u_VertexLerp);\r\n\t\tnormal = mix(att" +"r_Normal, attr_Normal2, u_VertexLerp);\r\n\t\tnormal = normalize(normal);\r" +"\n\t}\r\n\telse\r\n\t{\r\n\t\tposition = attr_Position;\r\n\t\tnormal = att" +"r_Normal;\r\n\t}\r\n\r\n\tposition = DeformPosition(position, normal, attr_" +"TexCoord0.st);\r\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * positio" +"n;\r\n\t\r\n\t\r\n\ttex = vec2(0);\r\n\t\r\n\tdist = u_DlightInfo.xyz - pos" +"ition.xyz;\t\r\n\tdlightmod = 0;\r\n\r\n\tif (!(dot(dist, normal) < 0))\r\n" +"\t{\r\n\t\tfloat diffz = abs(dist.z);\r\n\t\tfloat radius = 1.0 / u_DlightI" +"nfo.a;\r\n \r\n\t\tif (diffz <= radius)\r\n\t\t{\r\n\t\t\ttex = vec2(0.5" +") + dist.xy * u_DlightInfo.a;\r\n\r\n\t\t\tif (diffz < radius * 0.5)\r\n\t" +"\t\t{\r\n\t\t\t\tdlightmod = 1.0;\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t" +"\t\t\tdlightmod = 2.0 * (radius - diffz) * u_DlightInfo.a;\r\n\t\t\t}\r\n\t" +"\t}\r\n\t}\r\n\r\n\tvar_Tex1 = tex;\r\n\tvar_Color.rgb = u_Color.rgb * dlig" +"htmod;\r\n\tvar_Color.a = u_Color.a;\r\n}\r\n"; + +static const char *fallbackDlightShader_fp = +"uniform sampler2D u_Texture0Map;\r\n\r\nvarying vec2 var_Tex1;\r\nvary" +"ing vec4 var_Color;\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec4 color;\r\n\r" +"\n\tcolor = texture2D(u_Texture0Map, var_Tex1);\r\n\r\n\tcolor *= var_Color" +";\r\n\r\n\tgl_FragColor = color;\r\n}\r\n"; static void GLSL_PrintInfoLog(GLhandleARB object, qboolean developerOnly) @@ -231,13 +372,14 @@ static void GLSL_PrintShaderSource(GLhandleARB object) ri.Free(msg); } -static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, const GLcharARB *buffer, int size, GLenum shaderType, const GLcharARB *extra) +static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, const GLcharARB *buffer, int size, GLenum shaderType, const GLcharARB *extra, qboolean addHeader) { GLint compiled; GLhandleARB shader; shader = qglCreateShaderObjectARB(shaderType); + if (addHeader) { static char bufferExtra[32000]; int sizeExtra; @@ -364,6 +506,32 @@ static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, c ATEST_LT_128, ATEST_GE_128)); + Q_strcat(bufferExtra, sizeof(bufferExtra), + va("#ifndef acff_t\n" + "#define acff_t\n" + "#define ACFF_NONE %i\n" + "#define ACFF_MODULATE_RGB %i\n" + "#define ACFF_MODULATE_RGBA %i\n" + "#define ACFF_MODULATE_ALPHA %i\n" + "#endif\n", + ACFF_NONE, + ACFF_MODULATE_RGB, + ACFF_MODULATE_RGBA, + ACFF_MODULATE_ALPHA)); + + Q_strcat(bufferExtra, sizeof(bufferExtra), + va("#ifndef texenv_t\n" + "#define texenv_t\n" + "#define GL_MODULATE %i\n" + "#define GL_ADD %i\n" + "#define GL_REPLACE %i\n" + "#endif\n", + GL_MODULATE, + GL_ADD, + GL_REPLACE)); + + + fbufWidthScale = 1.0f / ((float)glConfig.vidWidth); fbufHeightScale = 1.0f / ((float)glConfig.vidHeight); Q_strcat(bufferExtra, sizeof(bufferExtra), @@ -382,8 +550,6 @@ static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, c sizeExtra = strlen(bufferExtra); sizeFinal = sizeExtra + size; - //ri.Printf(PRINT_ALL, "GLSL extra: %s\n", bufferExtra); - bufferFinal = ri.Hunk_AllocateTempMemory(size + sizeExtra); strcpy(bufferFinal, bufferExtra); @@ -393,6 +559,11 @@ static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, c ri.Hunk_FreeTempMemory(bufferFinal); } + else + { + int sizeFinal = size; + qglShaderSourceARB(shader, 1, (const GLcharARB **)&buffer, &sizeFinal); + } // compile shader qglCompileShaderARB(shader); @@ -425,7 +596,7 @@ static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, c } -static int GLSL_LoadGPUShader(GLhandleARB program, GLhandleARB *prevShader, const char *name, GLenum shaderType, const GLcharARB *extra) +static int GLSL_LoadGPUShader(GLhandleARB program, GLhandleARB *prevShader, const char *name, GLenum shaderType, const GLcharARB *extra, qboolean addHeader) { char filename[MAX_QPATH]; GLcharARB *buffer = NULL; @@ -523,7 +694,7 @@ static int GLSL_LoadGPUShader(GLhandleARB program, GLhandleARB *prevShader, cons } #endif - result = GLSL_CompileGPUShader(program, prevShader, buffer, size, shaderType, extra); + result = GLSL_CompileGPUShader(program, prevShader, buffer, size, shaderType, extra, addHeader); ri.FS_FreeFile(buffer); @@ -583,7 +754,8 @@ static void GLSL_ShowProgramUniforms(GLhandleARB program) qglUseProgramObjectARB(0); } -static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name, int attribs, qboolean fragmentShader, const GLcharARB *extra) +static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name, int attribs, qboolean fragmentShader, const GLcharARB *extra, qboolean addHeader, + const char *fallback_vp, const char *fallback_fp, int numUniforms) { ri.Printf(PRINT_DEVELOPER, "------- GPU shader -------\n"); @@ -597,15 +769,48 @@ static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name, int a program->program = qglCreateProgramObjectARB(); program->attribs = attribs; - if (!(GLSL_LoadGPUShader(program->program, &program->vertexShader, name, GL_VERTEX_SHADER_ARB, extra))) + if (!(GLSL_LoadGPUShader(program->program, &program->vertexShader, name, GL_VERTEX_SHADER_ARB, extra, addHeader))) { ri.Printf(PRINT_ALL, "GLSL_InitGPUShader: Unable to load \"%s\" as GL_VERTEX_SHADER_ARB\n", name); - qglDeleteObjectARB(program->program); - return 0; + if (fallback_vp) + { + ri.Printf(PRINT_ALL, "compiling fallback...\n"); + if (!GLSL_CompileGPUShader(program->program, &program->vertexShader, fallback_vp, strlen(fallback_vp), GL_VERTEX_SHADER_ARB, extra, addHeader)) + { + ri.Printf(PRINT_ALL, "Fallback failed!\n"); + qglDeleteObjectARB(program->program); + return 0; + } + } + else + { + qglDeleteObjectARB(program->program); + return 0; + } } if(fragmentShader) - GLSL_LoadGPUShader(program->program, &program->fragmentShader, name, GL_FRAGMENT_SHADER_ARB, extra); + { + if(!(GLSL_LoadGPUShader(program->program, &program->fragmentShader, name, GL_FRAGMENT_SHADER_ARB, extra, addHeader))) + { + ri.Printf(PRINT_ALL, "GLSL_InitGPUShader: Unable to load \"%s\" as GL_FRAGMENT_SHADER_ARB\n", name); + if (fallback_fp) + { + ri.Printf(PRINT_ALL, "compiling fallback...\n"); + if (!GLSL_CompileGPUShader(program->program, &program->fragmentShader, fallback_fp, strlen(fallback_fp), GL_FRAGMENT_SHADER_ARB, extra, addHeader)) + { + ri.Printf(PRINT_ALL, "Fallback failed!\n"); + qglDeleteObjectARB(program->program); + return 0; + } + } + else + { + qglDeleteObjectARB(program->program); + return 0; + } + } + } if(attribs & ATTR_POSITION) qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION, "attr_Position"); @@ -648,84 +853,269 @@ static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name, int a GLSL_LinkProgram(program->program); + program->numUniforms = numUniforms; + + { + int i, size; + + size = sizeof(*program->uniforms) * numUniforms; + program->uniforms = ri.Malloc(size); + for (i = 0; i < numUniforms; i++) + { + program->uniforms[i] = -1; + } + + size = sizeof(*program->uniformTypes) * numUniforms; + program->uniformTypes = ri.Malloc(size); + memset(program->uniformTypes, 0, size); + + size = sizeof(*program->uniformBufferOffsets) * numUniforms; + program->uniformBufferOffsets = ri.Malloc(size); + memset(program->uniformBufferOffsets, 0, size); + } + return 1; } - -static int GLSL_InitFallbackGenericShader(shaderProgram_t * program, const char *name, int attribs, qboolean fragmentShader, const GLcharARB *extra) +// intentionally deceiving the user here, not actually setting the names but getting their indexes. +void GLSL_AddUniform(shaderProgram_t *program, int uniformNum, const char *name, int type) { - ri.Printf(PRINT_DEVELOPER, "------- GPU shader -------\n"); + GLint *uniforms = program->uniforms; - if(strlen(name) >= MAX_QPATH) - { - ri.Error(ERR_DROP, "GLSL_InitGPUShader: \"%s\" is too long\n", name); - } - - Q_strncpyz(program->name, name, sizeof(program->name)); - - program->program = qglCreateProgramObjectARB(); - program->attribs = attribs; - - if (!(GLSL_CompileGPUShader(program->program, &program->vertexShader, fallbackGenericShader_vp, strlen(fallbackGenericShader_vp), GL_VERTEX_SHADER_ARB, extra))) - { - ri.Printf(PRINT_ALL, "GLSL_InitFallbackGenericShader: Unable to load \"%s\" as GL_VERTEX_SHADER_ARB\n", name); - qglDeleteObjectARB(program->program); - return 0; - } - - if(fragmentShader) - GLSL_CompileGPUShader(program->program, &program->fragmentShader, fallbackGenericShader_fp, strlen(fallbackGenericShader_fp), GL_FRAGMENT_SHADER_ARB, extra); - - if(attribs & ATTR_POSITION) - qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION, "attr_Position"); - - if(attribs & ATTR_TEXCOORD) - qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD0, "attr_TexCoord0"); - - if(attribs & ATTR_LIGHTCOORD) - qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD1, "attr_TexCoord1"); - -// if(attribs & ATTR_TEXCOORD2) -// qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD2, "attr_TexCoord2"); - -// if(attribs & ATTR_TEXCOORD3) -// qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD3, "attr_TexCoord3"); - - if(attribs & ATTR_TANGENT) - qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent"); - - if(attribs & ATTR_BINORMAL) - qglBindAttribLocationARB(program->program, ATTR_INDEX_BINORMAL, "attr_Binormal"); - - if(attribs & ATTR_NORMAL) - qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL, "attr_Normal"); - - if(attribs & ATTR_COLOR) - qglBindAttribLocationARB(program->program, ATTR_INDEX_COLOR, "attr_Color"); - - if(attribs & ATTR_PAINTCOLOR) - qglBindAttribLocationARB(program->program, ATTR_INDEX_PAINTCOLOR, "attr_PaintColor"); - - if(attribs & ATTR_LIGHTDIRECTION) - qglBindAttribLocationARB(program->program, ATTR_INDEX_LIGHTDIRECTION, "attr_LightDirection"); - - if(attribs & ATTR_POSITION2) - qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION2, "attr_Position2"); - - if(attribs & ATTR_NORMAL2) - qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2"); - - GLSL_LinkProgram(program->program); - - return 1; + uniforms[uniformNum] = qglGetUniformLocationARB(program->program, name); + program->uniformTypes[uniformNum] = type; } +void GLSL_FinishGPUShader(shaderProgram_t *program) +{ + if (program->numUniforms) + { + int i, size; + + size = 0; + for (i = 0; i < program->numUniforms; i++) + { + if (program->uniforms[i] != -1) + { + program->uniformBufferOffsets[i] = size; + + switch(program->uniformTypes[i]) + { + case GLSL_INT: + size += sizeof(GLint); + break; + case GLSL_FLOAT: + size += sizeof(GLfloat); + break; + case GLSL_VEC2: + size += sizeof(vec_t) * 2; + break; + case GLSL_VEC3: + size += sizeof(vec_t) * 3; + break; + case GLSL_VEC4: + size += sizeof(vec_t) * 4; + break; + case GLSL_MAT16: + size += sizeof(vec_t) * 16; + break; + default: + break; + } + } + } + + ri.Printf(PRINT_ALL, "size %d\n", size); + + program->uniformBuffer = ri.Malloc(size); + + } + + GLSL_ValidateProgram(program->program); + GLSL_ShowProgramUniforms(program->program); + GL_CheckErrors(); +} + +void GLSL_SetUniformInt(shaderProgram_t *program, int uniformNum, GLint value) +{ + GLint *uniforms = program->uniforms; + GLint *compare = (GLint *)(program->uniformBuffer + program->uniformBufferOffsets[uniformNum]); + + if (uniforms[uniformNum] == -1) + return; + + if (program->uniformTypes[uniformNum] != GLSL_INT) + { + ri.Printf( PRINT_WARNING, "GLSL_SetUniformInt: wrong type for uniform %i in program %s\n", uniformNum, program->name); + return; + } + + if (value == *compare) + { + return; + } + + qglUniform1iARB(uniforms[uniformNum], value); +} + +void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat value) +{ + GLint *uniforms = program->uniforms; + GLfloat *compare = (GLfloat *)(program->uniformBuffer + program->uniformBufferOffsets[uniformNum]); + + if (uniforms[uniformNum] == -1) + return; + + if (program->uniformTypes[uniformNum] != GLSL_FLOAT) + { + ri.Printf( PRINT_WARNING, "GLSL_SetUniformFloat: wrong type for uniform %i in program %s\n", uniformNum, program->name); + return; + } + + if (value == *compare) + { + return; + } + + qglUniform1fARB(uniforms[uniformNum], value); +} + +void GLSL_SetUniformVec2(shaderProgram_t *program, int uniformNum, const vec2_t v) +{ + GLint *uniforms = program->uniforms; + vec_t *compare = (float *)(program->uniformBuffer + program->uniformBufferOffsets[uniformNum]); + + if (uniforms[uniformNum] == -1) + return; + + if (program->uniformTypes[uniformNum] != GLSL_VEC2) + { + ri.Printf( PRINT_WARNING, "GLSL_SetUniformVec2: wrong type for uniform %i in program %s\n", uniformNum, program->name); + return; + } + + if (v[0] == compare[0] && v[1] == compare[1]) + { + return; + } + + qglUniform2fARB(uniforms[uniformNum], v[0], v[1]); +} + +void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t v) +{ + GLint *uniforms = program->uniforms; + vec_t *compare = (float *)(program->uniformBuffer + program->uniformBufferOffsets[uniformNum]); + + if (uniforms[uniformNum] == -1) + return; + + if (program->uniformTypes[uniformNum] != GLSL_VEC3) + { + ri.Printf( PRINT_WARNING, "GLSL_SetUniformVec3: wrong type for uniform %i in program %s\n", uniformNum, program->name); + return; + } + + if (VectorCompare(v, compare)) + { + return; + } + + qglUniform3fARB(uniforms[uniformNum], v[0], v[1], v[2]); +} + +void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t v) +{ + GLint *uniforms = program->uniforms; + vec_t *compare = (float *)(program->uniformBuffer + program->uniformBufferOffsets[uniformNum]); + + if (uniforms[uniformNum] == -1) + return; + + if (program->uniformTypes[uniformNum] != GLSL_VEC4) + { + ri.Printf( PRINT_WARNING, "GLSL_SetUniformVec4: wrong type for uniform %i in program %s\n", uniformNum, program->name); + return; + } + + if (VectorCompare4(v, compare)) + { + return; + } + + qglUniform4fARB(uniforms[uniformNum], v[0], v[1], v[2], v[3]); +} + +void GLSL_SetUniformMatrix16(shaderProgram_t *program, int uniformNum, const matrix_t matrix) +{ + GLint *uniforms = program->uniforms; + vec_t *compare = (float *)(program->uniformBuffer + program->uniformBufferOffsets[uniformNum]); + + if (uniforms[uniformNum] == -1) + return; + + if (program->uniformTypes[uniformNum] != GLSL_MAT16) + { + ri.Printf( PRINT_WARNING, "GLSL_SetUniformMatrix16: wrong type for uniform %i in program %s\n", uniformNum, program->name); + return; + } + + if (Matrix16Compare(matrix, compare)) + { + return; + } + + qglUniformMatrix4fvARB(uniforms[uniformNum], 1, GL_FALSE, matrix); +} + +void GLSL_DeleteGPUShader(shaderProgram_t *program) +{ + if(program->program) + { + if (program->vertexShader) + { + qglDetachObjectARB(program->program, program->vertexShader); + qglDeleteObjectARB(program->vertexShader); + } + + if (program->fragmentShader) + { + qglDetachObjectARB(program->program, program->fragmentShader); + qglDeleteObjectARB(program->fragmentShader); + } + + qglDeleteObjectARB(program->program); + + if (program->uniforms) + { + ri.Free(program->uniforms); + } + + if (program->uniformTypes) + { + ri.Free(program->uniformTypes); + } + + if (program->uniformBuffer) + { + ri.Free(program->uniformBuffer); + } + + if (program->uniformBufferOffsets) + { + ri.Free(program->uniformBufferOffsets); + } + + Com_Memset(program, 0, sizeof(*program)); + } +} void GLSL_InitGPUShaders(void) { int startTime, endTime; int i; char extradefines[1024]; + int attribs; ri.Printf(PRINT_ALL, "------- GLSL_InitGPUShaders -------\n"); @@ -735,8 +1125,8 @@ void GLSL_InitGPUShaders(void) startTime = ri.Milliseconds(); for (i = 0; i < GLSLDEF_COUNT; i++) - { - int attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_NORMAL | ATTR_COLOR; + { + attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_NORMAL | ATTR_COLOR; extradefines[0] = '\0'; if (i & GLSLDEF_USE_DEFORM_VERTEXES) @@ -756,103 +1146,150 @@ void GLSL_InitGPUShaders(void) Q_strcat(extradefines, 1024, "#define USE_FOG\n"); } - if (!GLSL_InitGPUShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines)) + if (!GLSL_InitGPUShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines, qtrue, fallbackGenericShader_vp, fallbackGenericShader_fp, GENERIC_UNIFORM_COUNT)) { - // Failed to load, init the fallback one - GLSL_InitFallbackGenericShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines); + ri.Error(ERR_FATAL, "Could not load generic shader!\n"); } - tr.genericShader[i].u_ModelViewProjectionMatrix = - qglGetUniformLocationARB(tr.genericShader[i].program, "u_ModelViewProjectionMatrix"); + // There's actually no need to filter these out, since they'll + // redirect to -1 if nonexistent, but it's more understandable this way. + + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16); - tr.genericShader[i].u_AlphaTest = -1; //qglGetUniformLocationARB(tr.genericShader[i].program, "u_AlphaTest"); - tr.genericShader[i].u_ColorGen = qglGetUniformLocationARB(tr.genericShader[i].program, "u_ColorGen"); - tr.genericShader[i].u_AlphaGen = qglGetUniformLocationARB(tr.genericShader[i].program, "u_AlphaGen"); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_COLORGEN, "u_ColorGen", GLSL_INT); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_ALPHAGEN, "u_AlphaGen", GLSL_INT); if (i & GLSLDEF_USE_TCGEN) { - tr.genericShader[i].u_TCGen0 = qglGetUniformLocationARB(tr.genericShader[i].program, "u_TCGen0"); - tr.genericShader[i].u_TCGen1 = -1; //qglGetUniformLocationARB(tr.genericShader[i].program, "u_TCGen1"); - tr.genericShader[i].u_TCGen0Vector0 = qglGetUniformLocationARB(tr.genericShader[i].program, "u_TCGen0Vector0"); - tr.genericShader[i].u_TCGen0Vector1 = qglGetUniformLocationARB(tr.genericShader[i].program, "u_TCGen0Vector1"); - tr.genericShader[i].u_TCGen1Vector0 = -1; //qglGetUniformLocationARB(tr.genericShader[i].program, "u_TCGen1Vector0"); - tr.genericShader[i].u_TCGen1Vector1 = -1; //qglGetUniformLocationARB(tr.genericShader[i].program, "u_TCGen1Vector1"); - } - else - { - tr.genericShader[i].u_TCGen0 = -1; - tr.genericShader[i].u_TCGen1 = -1; - tr.genericShader[i].u_TCGen0Vector0 = -1; - tr.genericShader[i].u_TCGen0Vector1 = -1; - tr.genericShader[i].u_TCGen1Vector0 = -1; - tr.genericShader[i].u_TCGen1Vector1 = -1; + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TCGEN0, "u_TCGen0", GLSL_INT); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TCGEN0VECTOR0, "u_TCGen0Vector0", GLSL_VEC4); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TCGEN0VECTOR1, "u_TCGen0Vector1", GLSL_VEC4); } if (i & GLSLDEF_USE_FOG) { - tr.genericShader[i].u_FogAdjustColors = qglGetUniformLocationARB(tr.genericShader[i].program, "u_FogAdjustColors"); - tr.genericShader[i].u_FogDistance = qglGetUniformLocationARB(tr.genericShader[i].program, "u_FogDistance"); - tr.genericShader[i].u_FogDepth = qglGetUniformLocationARB(tr.genericShader[i].program, "u_FogDepth"); - tr.genericShader[i].u_FogEyeT = qglGetUniformLocationARB(tr.genericShader[i].program, "u_FogEyeT"); - } - else - { - tr.genericShader[i].u_FogAdjustColors = -1; - tr.genericShader[i].u_FogDistance = -1; - tr.genericShader[i].u_FogDepth = -1; - tr.genericShader[i].u_FogEyeT = -1; + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_FOGADJUSTCOLORS, "u_FogAdjustColors", GLSL_INT); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_FOGDISTANCE, "u_FogDistance", GLSL_VEC4); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_FOGDEPTH, "u_FogDepth", GLSL_VEC4); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_FOGEYET, "u_FogEyeT", GLSL_FLOAT); } if (i & GLSLDEF_USE_DEFORM_VERTEXES) { - tr.genericShader[i].u_DeformGen = qglGetUniformLocationARB(tr.genericShader[i].program, "u_DeformGen"); - tr.genericShader[i].u_DeformWave = qglGetUniformLocationARB(tr.genericShader[i].program, "u_DeformWave"); - tr.genericShader[i].u_DeformBulge = qglGetUniformLocationARB(tr.genericShader[i].program, "u_DeformBulge"); - tr.genericShader[i].u_DeformSpread = qglGetUniformLocationARB(tr.genericShader[i].program, "u_DeformSpread"); - } - else - { - tr.genericShader[i].u_DeformGen = -1; - tr.genericShader[i].u_DeformWave = -1; - tr.genericShader[i].u_DeformBulge = -1; - tr.genericShader[i].u_DeformSpread = -1; + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_DEFORMGEN, "u_DeformGen", GLSL_INT); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_DEFORMWAVE, "u_DeformWave", GLSL_VEC4); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_DEFORMBULGE, "u_DeformBulge", GLSL_VEC3); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_DEFORMSPREAD, "u_DeformSpread", GLSL_FLOAT); } - tr.genericShader[i].u_Time = qglGetUniformLocationARB(tr.genericShader[i].program, "u_Time"); - tr.genericShader[i].u_Color = qglGetUniformLocationARB(tr.genericShader[i].program, "u_Color"); - tr.genericShader[i].u_AmbientLight = qglGetUniformLocationARB(tr.genericShader[i].program, "u_AmbientLight"); - tr.genericShader[i].u_DirectedLight = qglGetUniformLocationARB(tr.genericShader[i].program, "u_DirectedLight"); - tr.genericShader[i].u_LightDir = qglGetUniformLocationARB(tr.genericShader[i].program, "u_LightDir"); - tr.genericShader[i].u_ViewOrigin = qglGetUniformLocationARB(tr.genericShader[i].program, "u_ViewOrigin"); - tr.genericShader[i].u_Texture0Matrix = qglGetUniformLocationARB(tr.genericShader[i].program, "u_Texture0Matrix"); - tr.genericShader[i].u_Texture1Matrix = -1; //qglGetUniformLocationARB(tr.genericShader[i].program, "u_Texture1Matrix"); - tr.genericShader[i].u_Texture1Env = qglGetUniformLocationARB(tr.genericShader[i].program, "u_Texture1Env"); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TIME, "u_Time", GLSL_FLOAT); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_COLOR, "u_Color", GLSL_VEC4); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_AMBIENTLIGHT, "u_AmbientLight", GLSL_VEC3); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_DIRECTEDLIGHT, "u_DirectedLight", GLSL_VEC3); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_LIGHTDIR, "u_LightDir", GLSL_VEC3); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_VIEWORIGIN, "u_ViewOrigin", GLSL_VEC3); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE0MATRIX, "u_Texture0Matrix", GLSL_MAT16); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE1ENV, "u_Texture1Env", GLSL_INT); - tr.genericShader[i].u_Texture0Map = qglGetUniformLocationARB(tr.genericShader[i].program, "u_Texture0Map"); - tr.genericShader[i].u_Texture1Map = qglGetUniformLocationARB(tr.genericShader[i].program, "u_Texture1Map"); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE0MAP, "u_Texture0Map", GLSL_INT); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE1MAP, "u_Texture1Map", GLSL_INT); - tr.genericShader[i].u_PortalRange = qglGetUniformLocationARB(tr.genericShader[i].program, "u_PortalRange"); - tr.genericShader[i].u_ModelMatrix = -1; //qglGetUniformLocationARB(tr.genericShader[i].program, "u_ModelMatrix"); + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_PORTALRANGE, "u_PortalRange", GLSL_FLOAT); if (i & GLSLDEF_USE_VERTEX_ANIMATION) { - tr.genericShader[i].u_VertexLerp = qglGetUniformLocationARB(tr.genericShader[i].program, "u_VertexLerp"); - } - else - { - tr.genericShader[i].u_VertexLerp = -1; + GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_VERTEXLERP, "u_VertexLerp", GLSL_FLOAT); } + GLSL_FinishGPUShader(&tr.genericShader[i]); + qglUseProgramObjectARB(tr.genericShader[i].program); - qglUniform1iARB(tr.genericShader[i].u_Texture0Map, 0); - qglUniform1iARB(tr.genericShader[i].u_Texture1Map, 1); + GLSL_SetUniformInt(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE0MAP, 0); + GLSL_SetUniformInt(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE1MAP, 1); qglUseProgramObjectARB(0); - - GLSL_ValidateProgram(tr.genericShader[i].program); - GLSL_ShowProgramUniforms(tr.genericShader[i].program); - GL_CheckErrors(); } + + attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD; + + if (!GLSL_InitGPUShader(&tr.lightmappedShader, "lightmapped", attribs, qtrue, NULL, qfalse, fallbackLightmappedShader_vp, fallbackLightmappedShader_fp, LIGHTMAPPED_UNIFORM_COUNT)) + { + ri.Error(ERR_FATAL, "Could not load lightmapped shader!\n"); + } + + GLSL_AddUniform(&tr.lightmappedShader, LIGHTMAPPED_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16); + GLSL_AddUniform(&tr.lightmappedShader, LIGHTMAPPED_UNIFORM_TEXTURE0MATRIX, "u_Texture0Matrix", GLSL_MAT16); + GLSL_AddUniform(&tr.lightmappedShader, LIGHTMAPPED_UNIFORM_TEXTURE1ENV, "u_Texture1Env", GLSL_INT); + GLSL_AddUniform(&tr.lightmappedShader, LIGHTMAPPED_UNIFORM_TEXTURE0MAP, "u_Texture0Map", GLSL_INT); + GLSL_AddUniform(&tr.lightmappedShader, LIGHTMAPPED_UNIFORM_TEXTURE1MAP, "u_Texture1Map", GLSL_INT); + + GLSL_FinishGPUShader(&tr.lightmappedShader); + + qglUseProgramObjectARB(tr.lightmappedShader.program); + GLSL_SetUniformInt(&tr.lightmappedShader, LIGHTMAPPED_UNIFORM_TEXTURE0MAP, 0); + GLSL_SetUniformInt(&tr.lightmappedShader, LIGHTMAPPED_UNIFORM_TEXTURE1MAP, 1); + qglUseProgramObjectARB(0); + + + attribs = ATTR_POSITION | ATTR_TEXCOORD; + + if (!GLSL_InitGPUShader(&tr.textureOnlyShader, "textureonly", attribs, qtrue, NULL, qfalse, fallbackTextureOnlyShader_vp, fallbackTextureOnlyShader_fp, TEXTUREONLY_UNIFORM_COUNT)) + { + ri.Error(ERR_FATAL, "Could not load textureonly shader!\n"); + } + + GLSL_AddUniform(&tr.textureOnlyShader, TEXTUREONLY_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16); + GLSL_AddUniform(&tr.textureOnlyShader, TEXTUREONLY_UNIFORM_TEXTURE0MAP, "u_Texture0Map", GLSL_INT); + + GLSL_FinishGPUShader(&tr.textureOnlyShader); + + qglUseProgramObjectARB(tr.textureOnlyShader.program); + GLSL_SetUniformInt(&tr.textureOnlyShader, TEXTUREONLY_UNIFORM_TEXTURE0MAP, 0); + qglUseProgramObjectARB(0); + + + attribs = ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TEXCOORD; + + if (!GLSL_InitGPUShader(&tr.fogShader, "fogpass", attribs, qtrue, NULL, qtrue, fallbackFogPassShader_vp, fallbackFogPassShader_fp, FOGPASS_UNIFORM_COUNT)) + { + ri.Error(ERR_FATAL, "Could not load fogpass shader!\n"); + } + + GLSL_AddUniform(&tr.fogShader, FOGPASS_UNIFORM_FOGDISTANCE, "u_FogDistance", GLSL_VEC4); + GLSL_AddUniform(&tr.fogShader, FOGPASS_UNIFORM_FOGDEPTH, "u_FogDepth", GLSL_VEC4); + GLSL_AddUniform(&tr.fogShader, FOGPASS_UNIFORM_FOGEYET, "u_FogEyeT", GLSL_FLOAT); + GLSL_AddUniform(&tr.fogShader, FOGPASS_UNIFORM_DEFORMGEN, "u_DeformGen", GLSL_INT); + GLSL_AddUniform(&tr.fogShader, FOGPASS_UNIFORM_DEFORMWAVE, "u_DeformWave", GLSL_VEC4); + GLSL_AddUniform(&tr.fogShader, FOGPASS_UNIFORM_DEFORMBULGE, "u_DeformBulge", GLSL_VEC3); + GLSL_AddUniform(&tr.fogShader, FOGPASS_UNIFORM_DEFORMSPREAD, "u_DeformSpread", GLSL_FLOAT); + GLSL_AddUniform(&tr.fogShader, FOGPASS_UNIFORM_TIME, "u_Time", GLSL_FLOAT); + GLSL_AddUniform(&tr.fogShader, FOGPASS_UNIFORM_COLOR, "u_Color", GLSL_VEC4); + GLSL_AddUniform(&tr.fogShader, FOGPASS_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16); + GLSL_AddUniform(&tr.fogShader, FOGPASS_UNIFORM_VERTEXLERP, "u_VertexLerp", GLSL_FLOAT); + + GLSL_FinishGPUShader(&tr.fogShader); + + + attribs = ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TEXCOORD; + + if (!GLSL_InitGPUShader(&tr.dlightShader, "dlight", attribs, qtrue, NULL, qtrue, fallbackDlightShader_vp, fallbackDlightShader_fp, DLIGHT_UNIFORM_COUNT)) + { + ri.Error(ERR_FATAL, "Could not load dlight shader!\n"); + } + + GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_DLIGHTINFO, "u_DlightInfo", GLSL_VEC4); + GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_DEFORMGEN, "u_DeformGen", GLSL_INT); + GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_DEFORMWAVE, "u_DeformWave", GLSL_VEC4); + GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_DEFORMBULGE, "u_DeformBulge", GLSL_VEC3); + GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_DEFORMSPREAD, "u_DeformSpread", GLSL_FLOAT); + GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_TIME, "u_Time", GLSL_FLOAT); + GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_COLOR, "u_Color", GLSL_VEC4); + GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16); + GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_VERTEXLERP, "u_VertexLerp", GLSL_FLOAT); + + GLSL_FinishGPUShader(&tr.dlightShader); + + endTime = ri.Milliseconds(); ri.Printf(PRINT_ALL, "GLSL shaders load time = %5.2f seconds\n", (endTime - startTime) / 1000.0); @@ -867,31 +1304,22 @@ void GLSL_ShutdownGPUShaders(void) qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD0); qglDisableVertexAttribArrayARB(ATTR_INDEX_TEXCOORD1); qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION); + qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION2); qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL); + qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2); qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR); GLSL_BindNullProgram(); for ( i = 0; i < GLSLDEF_COUNT; i++) { - if(tr.genericShader[i].program) - { - if (tr.genericShader[i].vertexShader) - { - qglDetachObjectARB(tr.genericShader[i].program, tr.genericShader[i].vertexShader); - qglDeleteObjectARB(tr.genericShader[i].vertexShader); - } - - if (tr.genericShader[i].fragmentShader) - { - qglDetachObjectARB(tr.genericShader[i].program, tr.genericShader[i].fragmentShader); - qglDeleteObjectARB(tr.genericShader[i].fragmentShader); - } - - qglDeleteObjectARB(tr.genericShader[i].program); - Com_Memset(&tr.genericShader[i], 0, sizeof(shaderProgram_t)); - } + GLSL_DeleteGPUShader(&tr.genericShader[i]); } + GLSL_DeleteGPUShader(&tr.textureOnlyShader); + GLSL_DeleteGPUShader(&tr.lightmappedShader); + GLSL_DeleteGPUShader(&tr.fogShader); + GLSL_DeleteGPUShader(&tr.dlightShader); + glState.currentProgram = 0; qglUseProgramObjectARB(0); } @@ -915,9 +1343,11 @@ void GLSL_BindProgram(shaderProgram_t * program) { qglUseProgramObjectARB(program->program); glState.currentProgram = program; + backEnd.pc.c_glslShaderBinds++; } } + void GLSL_BindNullProgram(void) { if(r_logFile->integer) @@ -1135,4 +1565,5 @@ shaderProgram_t *GLSL_GetGenericShaderProgram() } return &tr.genericShader[shaderAttribs]; -} \ No newline at end of file +} + diff --git a/reaction/code/renderer/tr_local.h b/reaction/code/renderer/tr_local.h index 64248ea6..f66e928c 100644 --- a/reaction/code/renderer/tr_local.h +++ b/reaction/code/renderer/tr_local.h @@ -677,6 +677,15 @@ enum GLSLDEF_COUNT = 0x0010, }; +enum +{ + GLSL_INT, + GLSL_FLOAT, + GLSL_VEC2, + GLSL_VEC3, + GLSL_VEC4, + GLSL_MAT16 +}; // Tr3B - shaderProgram_t represents a pair of one // GLSL vertex and one GLSL fragment shader @@ -690,841 +699,101 @@ typedef struct shaderProgram_s uint32_t attribs; // vertex array attributes // uniform parameters - GLint u_Texture0Map; - GLint u_Texture1Map; - GLint u_Texture2Map; - GLint u_Texture3Map; - - GLint u_PortalRange; - float t_PortalRange; - - GLint u_FogAdjustColors; - int t_FogAdjustColors; - - GLint u_FogDistance; - vec4_t t_FogDistance; - - GLint u_FogDepth; - vec4_t t_FogDepth; - - GLint u_FogEyeT; - float t_FogEyeT; - - GLint u_ModelMatrix; // model -> world - matrix_t t_ModelMatrix; - - GLint u_ModelViewProjectionMatrix; - matrix_t t_ModelViewProjectionMatrix; - - GLint u_AlphaTest; - alphaTest_t t_AlphaTest; - - GLint u_ColorGen; - colorGen_t t_ColorGen; - - GLint u_AlphaGen; - alphaGen_t t_AlphaGen; - - GLint u_TCGen0; - texCoordGen_t t_TCGen0; - - GLint u_TCGen1; - texCoordGen_t t_TCGen1; - - GLint u_TCGen0Vector0; - vec4_t t_TCGen0Vector0; - - GLint u_TCGen0Vector1; - vec4_t t_TCGen0Vector1; - - GLint u_TCGen1Vector0; - vec4_t t_TCGen1Vector0; - - GLint u_TCGen1Vector1; - vec4_t t_TCGen1Vector1; - - GLint u_DeformGen; - deformGen_t t_DeformGen; - - GLint u_DeformWave; - vec4_t t_DeformWave; - - GLint u_DeformBulge; - vec3_t t_DeformBulge; - - GLint u_DeformSpread; - float t_DeformSpread; - - GLint u_Time; - float t_Time; - - GLint u_Color; - vec4_t t_Color; - - GLint u_AmbientLight; - vec3_t t_AmbientLight; - - GLint u_DirectedLight; - vec3_t t_DirectedLight; - - GLint u_LightDir; - vec3_t t_LightDir; - - GLint u_ViewOrigin; - vec4_t t_ViewOrigin; - - GLint u_Texture0Matrix; - matrix_t t_Texture0Matrix; - - GLint u_Texture1Matrix; - matrix_t t_Texture1Matrix; - - GLint u_Texture1Env; - uint32_t t_Texture1Env; - - GLint u_Texture2Matrix; - matrix_t t_Texture2Matrix; - - GLint u_Texture3Matrix; - matrix_t t_Texture3Matrix; - - GLint u_VertexLerp; - float t_VertexLerp; - + int numUniforms; + GLint *uniforms; + GLint *uniformTypes; + int *uniformBufferOffsets; + char *uniformBuffer; } shaderProgram_t; +enum +{ + LIGHTMAPPED_UNIFORM_MODELVIEWPROJECTIONMATRIX = 0, + LIGHTMAPPED_UNIFORM_TEXTURE0MATRIX, + LIGHTMAPPED_UNIFORM_TEXTURE1ENV, + LIGHTMAPPED_UNIFORM_TEXTURE0MAP, + LIGHTMAPPED_UNIFORM_TEXTURE1MAP, + LIGHTMAPPED_UNIFORM_COUNT +}; + + +enum +{ + TEXTUREONLY_UNIFORM_MODELVIEWPROJECTIONMATRIX = 0, + TEXTUREONLY_UNIFORM_TEXTURE0MAP, + TEXTUREONLY_UNIFORM_COUNT +}; + + +enum +{ + FOGPASS_UNIFORM_FOGDISTANCE = 0, + FOGPASS_UNIFORM_FOGDEPTH, + FOGPASS_UNIFORM_FOGEYET, + FOGPASS_UNIFORM_DEFORMGEN, + FOGPASS_UNIFORM_DEFORMWAVE, + FOGPASS_UNIFORM_DEFORMBULGE, + FOGPASS_UNIFORM_DEFORMSPREAD, + FOGPASS_UNIFORM_TIME, + FOGPASS_UNIFORM_COLOR, + FOGPASS_UNIFORM_MODELVIEWPROJECTIONMATRIX, + FOGPASS_UNIFORM_VERTEXLERP, + FOGPASS_UNIFORM_COUNT +}; + + +enum +{ + DLIGHT_UNIFORM_DLIGHTINFO = 0, + DLIGHT_UNIFORM_DEFORMGEN, + DLIGHT_UNIFORM_DEFORMWAVE, + DLIGHT_UNIFORM_DEFORMBULGE, + DLIGHT_UNIFORM_DEFORMSPREAD, + DLIGHT_UNIFORM_TIME, + DLIGHT_UNIFORM_COLOR, + DLIGHT_UNIFORM_MODELVIEWPROJECTIONMATRIX, + DLIGHT_UNIFORM_VERTEXLERP, + DLIGHT_UNIFORM_COUNT +}; + + +enum +{ + GENERIC_UNIFORM_TEXTURE0MAP = 0, + GENERIC_UNIFORM_TEXTURE1MAP, + GENERIC_UNIFORM_TEXTURE0MATRIX, + GENERIC_UNIFORM_TEXTURE1ENV, + GENERIC_UNIFORM_VIEWORIGIN, + GENERIC_UNIFORM_TCGEN0, + GENERIC_UNIFORM_TCGEN0VECTOR0, + GENERIC_UNIFORM_TCGEN0VECTOR1, + GENERIC_UNIFORM_DEFORMGEN, + GENERIC_UNIFORM_DEFORMWAVE, + GENERIC_UNIFORM_DEFORMBULGE, + GENERIC_UNIFORM_DEFORMSPREAD, + GENERIC_UNIFORM_COLORGEN, + GENERIC_UNIFORM_ALPHAGEN, + GENERIC_UNIFORM_COLOR, + GENERIC_UNIFORM_AMBIENTLIGHT, + GENERIC_UNIFORM_DIRECTEDLIGHT, + GENERIC_UNIFORM_LIGHTDIR, + GENERIC_UNIFORM_PORTALRANGE, + GENERIC_UNIFORM_FOGDISTANCE, + GENERIC_UNIFORM_FOGDEPTH, + GENERIC_UNIFORM_FOGEYET, + GENERIC_UNIFORM_FOGADJUSTCOLORS, + GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, + GENERIC_UNIFORM_TIME, + GENERIC_UNIFORM_VERTEXLERP, + GENERIC_UNIFORM_COUNT +}; + // // Tr3B: these are fire wall functions to avoid expensive redundant glUniform* calls #define USE_UNIFORM_FIREWALL 1 //#define LOG_GLSL_UNIFORMS 1 -#if defined(LOG_GLSL_UNIFORMS) -extern cvar_t *r_logFile; // number of frames to emit GL logs -void GLimp_LogComment(char *comment); -#define GLimp_LogUniformComment(...) GLimp_LogComment(__VA_ARGS__) -#else -#define GLimp_LogUniformComment(...) -#endif - -// *INDENT-OFF* - -static ID_INLINE void GLSL_SetUniform_Texture0Matrix(shaderProgram_t * program, const matrix_t m) -{ - if (program->u_Texture0Matrix == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(Matrix16Compare(program->t_Texture0Matrix, m)) - return; - - Matrix16Copy(m, program->t_Texture0Matrix); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_Texture0Matrix( program = %s, " - "matrix = \n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", - program->name, - m[0], m[4], m[8], m[12], - m[1], m[5], m[9], m[13], - m[2], m[6], m[10], m[14], - m[3], m[7], m[11], m[15])); - - qglUniformMatrix4fvARB(program->u_Texture0Matrix, 1, GL_FALSE, m); -} - -static ID_INLINE void GLSL_SetUniform_Texture1Matrix(shaderProgram_t * program, const matrix_t m) -{ - if (program->u_Texture1Matrix == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(Matrix16Compare(program->t_Texture1Matrix, m)) - return; - - Matrix16Copy(m, program->t_Texture1Matrix); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_Texture1Matrix( program = %s, " - "matrix = \n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", - program->name, - m[0], m[4], m[8], m[12], - m[1], m[5], m[9], m[13], - m[2], m[6], m[10], m[14], - m[3], m[7], m[11], m[15])); - - qglUniformMatrix4fvARB(program->u_Texture1Matrix, 1, GL_FALSE, m); -} - -static ID_INLINE void GLSL_SetUniform_Texture1Env(shaderProgram_t * program, uint32_t env) -{ - uint32_t value; - - if (program->u_Texture1Env == -1) - return; - - switch ( env ) - { - case GL_MODULATE: - value = 1; - break; - case GL_REPLACE: - value = 2; - break; - case GL_DECAL: - value = 3; - break; - case GL_ADD: - value = 4; - break; - default: - value = 0; - break; - } - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_Texture1Env == value) - return; - - program->t_Texture1Env = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_Texture1Env( program = %s, value = %i ) ---\n", program->name, value)); - - qglUniform1iARB(program->u_Texture1Env, value); -} - -static ID_INLINE void GLSL_SetUniform_Texture2Matrix(shaderProgram_t * program, const matrix_t m) -{ - if (program->u_Texture2Matrix == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(Matrix16Compare(program->t_Texture2Matrix, m)) - return; - - Matrix16Copy(m, program->t_Texture2Matrix); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_Texture2Matrix( program = %s, " - "matrix = \n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", - program->name, - m[0], m[4], m[8], m[12], - m[1], m[5], m[9], m[13], - m[2], m[6], m[10], m[14], - m[3], m[7], m[11], m[15])); - - qglUniformMatrix4fvARB(program->u_Texture2Matrix, 1, GL_FALSE, m); -} - -static ID_INLINE void GLSL_SetUniform_Texture3Matrix(shaderProgram_t * program, const matrix_t m) -{ - if (program->u_Texture3Matrix == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(Matrix16Compare(program->t_Texture3Matrix, m)) - return; - - Matrix16Copy(m, program->t_Texture3Matrix); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_Texture3Matrix( program = %s, " - "matrix = \n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", - program->name, - m[0], m[4], m[8], m[12], - m[1], m[5], m[9], m[13], - m[2], m[6], m[10], m[14], - m[3], m[7], m[11], m[15])); - - qglUniformMatrix4fvARB(program->u_Texture3Matrix, 1, GL_FALSE, m); -} - - -static ID_INLINE void GLSL_SetUniform_AlphaTest(shaderProgram_t * program, uint32_t stateBits) -{ - alphaTest_t value; - - if (program->u_AlphaTest == -1) - return; - - switch (stateBits & GLS_ATEST_BITS) - { - case GLS_ATEST_GT_0: - value = ATEST_GT_0; - break; - - case GLS_ATEST_LT_128: - value = ATEST_LT_128; - break; - - case GLS_ATEST_GE_128: - value = ATEST_GE_128; - break; - - default: - value = ATEST_NONE; - break; - } - - // don't just call LogComment, or we will get - // a call to va() every frame! - GLimp_LogUniformComment(va("--- GLSL_SetUniformAlphaTest( program = %s, value = %i ) ---\n", program->name, value)); - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_AlphaTest == value) - return; - - program->t_AlphaTest = value; -#endif - - qglUniform1iARB(program->u_AlphaTest, value); -} - -static ID_INLINE void GLSL_SetUniform_ViewOrigin(shaderProgram_t * program, const vec3_t v) -{ - if (program->u_ViewOrigin == -1) - return; - - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare(program->t_ViewOrigin, v)) - return; - - VectorCopy(v, program->t_ViewOrigin); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_ViewOrigin( program = %s, viewOrigin = ( %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2])); - - qglUniform3fARB(program->u_ViewOrigin, v[0], v[1], v[2]); -} - -static ID_INLINE void GLSL_SetUniform_TCGen0(shaderProgram_t * program, texCoordGen_t value) -{ - if (program->u_TCGen0 == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_TCGen0 == value) - return; - - program->t_TCGen0 = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_TCGen( program = %s, value = %i ) ---\n", program->name, value)); - - qglUniform1iARB(program->u_TCGen0, value); -} - -static ID_INLINE void GLSL_SetUniform_TCGen1(shaderProgram_t * program, texCoordGen_t value) -{ - if (program->u_TCGen1 == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_TCGen1 == value) - return; - - program->t_TCGen1 = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_TCGen( program = %s, value = %i ) ---\n", program->name, value)); - - qglUniform1iARB(program->u_TCGen1, value); -} - -static ID_INLINE void GLSL_SetUniform_TCGen0Vector0(shaderProgram_t * program, const vec4_t v) -{ - if (program->u_TCGen0Vector0 == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare(program->t_TCGen0Vector0, v)) - return; - - VectorCopy(v, program->t_TCGen0Vector0); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_TCGen0Vector0( program = %s, color = ( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2], v[3])); - - qglUniform4fARB(program->u_TCGen0Vector0, v[0], v[1], v[2], v[3]); -} - -static ID_INLINE void GLSL_SetUniform_TCGen0Vector1(shaderProgram_t * program, const vec4_t v) -{ - if (program->u_TCGen0Vector1 == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare(program->t_TCGen0Vector1, v)) - return; - - VectorCopy(v, program->t_TCGen0Vector1); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_TCGen0Vector1( program = %s, color = ( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2], v[3])); - - qglUniform4fARB(program->u_TCGen0Vector1, v[0], v[1], v[2], v[3]); -} -static ID_INLINE void GLSL_SetUniform_TCGen1Vector0(shaderProgram_t * program, const vec4_t v) -{ - if (program->u_TCGen1Vector0 == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare(program->t_TCGen1Vector0, v)) - return; - - VectorCopy(v, program->t_TCGen1Vector0); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_TCGen1Vector0( program = %s, color = ( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2], v[3])); - - qglUniform4fARB(program->u_TCGen1Vector0, v[0], v[1], v[2], v[3]); -} -static ID_INLINE void GLSL_SetUniform_TCGen1Vector1(shaderProgram_t * program, const vec4_t v) -{ - if (program->u_TCGen1Vector1 == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare(program->t_TCGen1Vector1, v)) - return; - - VectorCopy(v, program->t_TCGen1Vector1); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_TCGen1Vector1( program = %s, color = ( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2], v[3])); - - qglUniform4fARB(program->u_TCGen1Vector1, v[0], v[1], v[2], v[3]); -} - -static ID_INLINE void GLSL_SetUniform_DeformGen(shaderProgram_t * program, deformGen_t value) -{ - if (program->u_DeformGen == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_DeformGen == value) - return; - - program->t_DeformGen = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_DeformGen( program = %s, value = %i ) ---\n", program->name, value)); - - qglUniform1iARB(program->u_DeformGen, value); -} - -static ID_INLINE void GLSL_SetUniform_DeformWave(shaderProgram_t * program, const waveForm_t * wf) -{ - vec4_t v; - - if (program->u_DeformWave == -1) - return; - - VectorSet4(v, wf->base, wf->amplitude, wf->phase, wf->frequency); - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare4(program->t_DeformWave, v)) - return; - - VectorCopy4(v, program->t_DeformWave); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_DeformWave( program = %s, wave form = ( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2], v[3])); - - qglUniform4fARB(program->u_DeformWave, v[0], v[1], v[2], v[3]); -} - -static ID_INLINE void GLSL_SetUniform_DeformBulge(shaderProgram_t * program, const deformStage_t * ds) -{ - vec3_t v; - - if (program->u_DeformBulge == -1) - return; - - VectorSet(v, ds->bulgeWidth, ds->bulgeHeight, ds->bulgeSpeed); - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare(program->t_DeformBulge, v)) - return; - - VectorCopy(v, program->t_DeformBulge); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_DeformBulge( program = %s, bulge = ( %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2])); - - qglUniform3fARB(program->u_DeformBulge, v[0], v[1], v[2]); -} - -static ID_INLINE void GLSL_SetUniform_DeformSpread(shaderProgram_t * program, float value) -{ - if (program->u_DeformSpread == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_DeformSpread == value) - return; - - program->t_DeformSpread = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_DeformSpread( program = %s, value = %f ) ---\n", program->name, value)); - - qglUniform1fARB(program->u_DeformSpread, value); -} - -static ID_INLINE void GLSL_SetUniform_ColorGen(shaderProgram_t * program, colorGen_t value) -{ -#if 0 - float floatValue; - - switch (value) - { - case CGEN_VERTEX: - floatValue = 1.0f; - break; - - case CGEN_ONE_MINUS_VERTEX: - floatValue = -1.0f; - break; - - default: - floatValue = 0.0f; - break; - } - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_ColorGen == floatValue) - return; - - program->t_ColorGen = floatValue; -#endif - - qglUniform1fARB(program->u_ColorGen, floatValue); -#else - if (program->u_ColorGen == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_ColorGen == value) - return; - - program->t_ColorGen = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_ColorGen( program = %s, value = %i ) ---\n", program->name, value)); - - qglUniform1iARB(program->u_ColorGen, value); -#endif -} - -static ID_INLINE void GLSL_SetUniform_AlphaGen(shaderProgram_t * program, alphaGen_t value) -{ -#if 0 - float floatValue; - - switch (value) - { - case AGEN_VERTEX: - floatValue = 1.0f; - break; - - case AGEN_ONE_MINUS_VERTEX: - floatValue = -1.0f; - break; - - default: - floatValue = 0.0f; - break; - } - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_AlphaGen == floatValue) - return; - - program->t_AlphaGen = floatValue; -#endif - - qglUniform1fARB(program->u_AlphaGen, floatValue); - -#else -#if defined(USE_UNIFORM_FIREWALL) - if (program->u_AlphaGen == -1) - return; - - if(program->t_AlphaGen == value) - return; - - program->t_AlphaGen = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_AlphaGen( program = %s, value = %i ) ---\n", program->name, value)); - - qglUniform1iARB(program->u_AlphaGen, value); -#endif -} - -static ID_INLINE void GLSL_SetUniform_Color(shaderProgram_t * program, const vec4_t v) -{ - if (program->u_Color == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare4(program->t_Color, v)) - return; - - VectorCopy4(v, program->t_Color); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_Color( program = %s, color = ( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2], v[3])); - - qglUniform4fARB(program->u_Color, v[0], v[1], v[2], v[3]); -} - - -static ID_INLINE void GLSL_SetUniform_AmbientLight(shaderProgram_t * program, const vec3_t v) -{ - if (program->u_AmbientLight == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare(program->t_AmbientLight, v)) - return; - - VectorCopy(v, program->t_AmbientLight); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_AmbientLight( program = %s, color = ( %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2])); - - qglUniform3fARB(program->u_AmbientLight, v[0], v[1], v[2]); -} - -static ID_INLINE void GLSL_SetUniform_DirectedLight(shaderProgram_t * program, const vec3_t v) -{ - if (program->u_DirectedLight == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare(program->t_DirectedLight, v)) - return; - - VectorCopy(v, program->t_DirectedLight); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_DirectedLight( program = %s, color = ( %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2])); - - qglUniform3fARB(program->u_DirectedLight, v[0], v[1], v[2]); -} - -static ID_INLINE void GLSL_SetUniform_LightDir(shaderProgram_t * program, const vec3_t v) -{ - if (program->u_LightDir == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare(program->t_LightDir, v)) - return; - - VectorCopy(v, program->t_LightDir); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_LightDir( program = %s, color = ( %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2])); - - qglUniform3fARB(program->u_LightDir, v[0], v[1], v[2]); -} - -static ID_INLINE void GLSL_SetUniform_PortalRange(shaderProgram_t * program, float value) -{ - if (program->u_PortalRange == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_PortalRange == value) - return; - - program->t_PortalRange = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_PortalRange( program = %s, value = %f ) ---\n", program->name, value)); - - qglUniform1fARB(program->u_PortalRange, value); -} - -static ID_INLINE void GLSL_SetUniform_FogDistance(shaderProgram_t * program, const vec4_t v) -{ - if (program->u_FogDistance == -1) - return; - - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare4(program->t_FogDistance, v)) - return; - - VectorCopy(v, program->t_FogDistance); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniformFogDistance( program = %s, viewOrigin = ( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2], v[3])); - - qglUniform4fARB(program->u_FogDistance, v[0], v[1], v[2], v[3]); -} - -static ID_INLINE void GLSL_SetUniform_FogDepth(shaderProgram_t * program, const vec4_t v) -{ - if (program->u_FogDepth == -1) - return; - - -#if defined(USE_UNIFORM_FIREWALL) - if(VectorCompare4(program->t_FogDepth, v)) - return; - - VectorCopy(v, program->t_FogDepth); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniformFogDepth( program = %s, viewOrigin = ( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", program->name, v[0], v[1], v[2], v[3])); - - qglUniform4fARB(program->u_FogDepth, v[0], v[1], v[2], v[3]); -} - -static ID_INLINE void GLSL_SetUniform_FogEyeT(shaderProgram_t * program, float value) -{ - if (program->u_FogEyeT == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_FogEyeT == value) - return; - - program->t_FogEyeT = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_FogEyeT( program = %s, value = %f ) ---\n", program->name, value)); - - qglUniform1fARB(program->u_FogEyeT, value); -} - -static ID_INLINE void GLSL_SetUniform_FogAdjustColors(shaderProgram_t * program, int value) -{ - if (program->u_FogAdjustColors == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_FogAdjustColors == value) - return; - - program->t_FogAdjustColors = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_FogAdjustColors( program = %s, value = %i ) ---\n", program->name, value)); - - qglUniform1iARB(program->u_FogAdjustColors, value); -} - -static ID_INLINE void GLSL_SetUniform_ModelMatrix(shaderProgram_t * program, const matrix_t m) -{ - if (program->u_ModelMatrix == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(Matrix16Compare(program->t_ModelMatrix, m)) - return; - - Matrix16Copy(m, program->t_ModelMatrix); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_ModelMatrix( program = %s, " - "matrix = \n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", - program->name, - m[0], m[4], m[8], m[12], - m[1], m[5], m[9], m[13], - m[2], m[6], m[10], m[14], - m[3], m[7], m[11], m[15])); - - qglUniformMatrix4fvARB(program->u_ModelMatrix, 1, GL_FALSE, m); -} - -static ID_INLINE void GLSL_SetUniform_ModelViewProjectionMatrix(shaderProgram_t * program, const matrix_t m) -{ - if (program->u_ModelViewProjectionMatrix == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(Matrix16Compare(program->t_ModelViewProjectionMatrix, m)) - return; - - Matrix16Copy(m, program->t_ModelViewProjectionMatrix); -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_ModelViewProjectionMatrix( program = %s, " - "matrix = \n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f )\n" - "( %5.3f, %5.3f, %5.3f, %5.3f ) ) ---\n", - program->name, - m[0], m[4], m[8], m[12], - m[1], m[5], m[9], m[13], - m[2], m[6], m[10], m[14], - m[3], m[7], m[11], m[15])); - - qglUniformMatrix4fvARB(program->u_ModelViewProjectionMatrix, 1, GL_FALSE, m); -} - -static ID_INLINE void GLSL_SetUniform_Time(shaderProgram_t * program, float value) -{ - if (program->u_Time == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_Time == value) - return; - - program->t_Time = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_Time( program = %s, value = %f ) ---\n", program->name, value)); - - qglUniform1fARB(program->u_Time, value); -} - -static ID_INLINE void GLSL_SetUniform_VertexLerp(shaderProgram_t * program, float value) -{ - if (program->u_VertexLerp == -1) - return; - -#if defined(USE_UNIFORM_FIREWALL) - if(program->t_VertexLerp == value) - return; - - program->t_VertexLerp = value; -#endif - - GLimp_LogUniformComment(va("--- GLSL_SetUniform_VertexLerp( program = %s, value = %f ) ---\n", program->name, value)); - - qglUniform1fARB(program->u_VertexLerp, value); -} - // trRefdef_t holds everything that comes in refdef_t, // as well as the locally generated scene information @@ -2211,6 +1480,12 @@ typedef struct { int c_flareTests; int c_flareRenders; + int c_glslShaderBinds; + int c_genericDraws; + int c_lightmappedDraws; + int c_fogDraws; + int c_dlightDraws; + int msec; // total msec for backend run } backEndCounters_t; @@ -2314,6 +1589,10 @@ typedef struct { // shaderProgram_t genericShader[GLSLDEF_COUNT]; + shaderProgram_t lightmappedShader; + shaderProgram_t textureOnlyShader; + shaderProgram_t fogShader; + shaderProgram_t dlightShader; // ----------------------------------------- @@ -2769,10 +2048,12 @@ void RB_StageIteratorGeneric( void ); void RB_StageIteratorGenericVBO( void ); void RB_StageIteratorSky( void ); void RB_StageIteratorVertexLitTexture( void ); +void RB_StageIteratorLightmappedMultitextureVBOGLSL( void ); void RB_StageIteratorLightmappedMultitexture( void ); void RB_AddQuadStamp( vec3_t origin, vec3_t left, vec3_t up, byte *color ); void RB_AddQuadStampExt( vec3_t origin, vec3_t left, vec3_t up, byte *color, float s1, float t1, float s2, float t2 ); +void RB_InstantQuad( vec4_t quadVerts[4] ); void RB_ShowImages( void ); @@ -2929,6 +2210,16 @@ void GLSL_VertexAttribsState(uint32_t stateBits); void GLSL_VertexAttribPointers(uint32_t attribBits); void GLSL_BindProgram(shaderProgram_t * program); void GLSL_BindNullProgram(void); + +void GLSL_SetNumUniforms(shaderProgram_t *program, int numUniforms); +void GLSL_SetUniformName(shaderProgram_t *program, int uniformNum, const char *name); +void GLSL_SetUniformInt(shaderProgram_t *program, int uniformNum, GLint value); +void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat value); +void GLSL_SetUniformVec2(shaderProgram_t *program, int uniformNum, const vec2_t v); +void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t v); +void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t v); +void GLSL_SetUniformMatrix16(shaderProgram_t *program, int uniformNum, const matrix_t matrix); + shaderProgram_t *GLSL_GetGenericShaderProgram(void); /* diff --git a/reaction/code/renderer/tr_shade.c b/reaction/code/renderer/tr_shade.c index 8fc05002..2b0c0688 100644 --- a/reaction/code/renderer/tr_shade.c +++ b/reaction/code/renderer/tr_shade.c @@ -300,25 +300,16 @@ static void DrawTris (shaderCommands_t *input) { { if (glRefConfig.glsl && r_arb_shader_objects->integer) { - matrix_t matrix; - shaderProgram_t *sp = &tr.genericShader[0]; + shaderProgram_t *sp = &tr.textureOnlyShader; GLSL_VertexAttribsState(ATTR_POSITION); GLSL_BindProgram(sp); - GLSL_SetUniform_ModelViewProjectionMatrix(sp, glState.modelviewProjection); - - //GLSL_SetUniform_DeformGen(sp, DGEN_NONE); - GLSL_SetUniform_TCGen0(sp, TCGEN_IDENTITY); - Matrix16Identity(matrix); - GLSL_SetUniform_Texture0Matrix(sp, matrix); - GLSL_SetUniform_Texture1Env(sp, 0); - GLSL_SetUniform_ColorGen(sp, CGEN_IDENTITY); - GLSL_SetUniform_AlphaGen(sp, AGEN_IDENTITY); + GLSL_SetUniformMatrix16(sp, TEXTUREONLY_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); if (input->multiDrawPrimitives) { - R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **) input->multiDrawFirstIndex, input->multiDrawNumIndexes); + R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **)input->multiDrawFirstIndex, input->multiDrawNumIndexes); } else { @@ -732,7 +723,7 @@ static void DrawMultitexturedVBO( shaderCommands_t *input, int stage ) { if (input->multiDrawPrimitives) { - R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **) input->multiDrawFirstIndex, input->multiDrawNumIndexes); + R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **)input->multiDrawFirstIndex, input->multiDrawNumIndexes); } else { @@ -1120,7 +1111,6 @@ static void ProjectDlightTextureVBOGLSL( void ) { dlight_t *dl; shaderProgram_t *sp; vec4_t vector; - matrix_t matrix; if ( !( tess.dlightBits & ( 1 << l ) ) ) { continue; // this surface definately doesn't have any of this light @@ -1131,28 +1121,69 @@ static void ProjectDlightTextureVBOGLSL( void ) { radius = dl->radius; scale = 1.0f / radius; - sp = GLSL_GetGenericShaderProgram(); + sp = &tr.dlightShader; + + backEnd.pc.c_dlightDraws++; GLSL_BindProgram(sp); - GLSL_SetUniform_TCGen0(sp, TCGEN_DLIGHT); - Matrix16Identity(matrix); - GLSL_SetUniform_Texture0Matrix(sp, matrix); - GLSL_SetUniform_Texture1Env(sp, 0); - GLSL_SetUniform_ColorGen(sp, CGEN_DLIGHT); - GLSL_SetUniform_AlphaGen(sp, AGEN_CONST); + GLSL_SetUniformMatrix16(sp, DLIGHT_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); + + GLSL_SetUniformFloat(sp, DLIGHT_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); + + // u_DeformGen + if(!ShaderRequiresCPUDeforms(tess.shader)) + { + deformStage_t *ds; + + // only support the first one + ds = &tess.shader->deforms[0]; + + switch (ds->deformation) + { + case DEFORM_WAVE: + GLSL_SetUniformInt(sp, DLIGHT_UNIFORM_DEFORMGEN, ds->deformationWave.func); + { + vec4_t v; + waveForm_t *wf = &ds->deformationWave; + VectorSet4(v, wf->base, wf->amplitude, wf->phase, wf->frequency); + GLSL_SetUniformVec4(sp, DLIGHT_UNIFORM_DEFORMWAVE, v); + } + GLSL_SetUniformFloat(sp, DLIGHT_UNIFORM_DEFORMSPREAD, ds->deformationSpread); + GLSL_SetUniformFloat(sp, DLIGHT_UNIFORM_TIME, tess.shaderTime); + break; + + case DEFORM_BULGE: + GLSL_SetUniformInt(sp, DLIGHT_UNIFORM_DEFORMGEN, DGEN_BULGE); + { + vec3_t v; + VectorSet(v, ds->bulgeWidth, ds->bulgeHeight, ds->bulgeSpeed); + GLSL_SetUniformVec3(sp, DLIGHT_UNIFORM_DEFORMBULGE, v); + } + GLSL_SetUniformFloat(sp, DLIGHT_UNIFORM_TIME, tess.shaderTime); + break; + + default: + GLSL_SetUniformInt(sp, DLIGHT_UNIFORM_DEFORMGEN, DGEN_NONE); + break; + } + } + else + { + GLSL_SetUniformInt(sp, DLIGHT_UNIFORM_DEFORMGEN, DGEN_NONE); + } vector[0] = dl->color[0]; vector[1] = dl->color[1]; vector[2] = dl->color[2]; vector[3] = 1.0f; - GLSL_SetUniform_Color(sp, vector); + GLSL_SetUniformVec4(sp, DLIGHT_UNIFORM_COLOR, vector); vector[0] = origin[0]; vector[1] = origin[1]; vector[2] = origin[2]; vector[3] = scale; - GLSL_SetUniform_TCGen0Vector0(sp, vector); + GLSL_SetUniformVec4(sp, DLIGHT_UNIFORM_DLIGHTINFO, vector); GL_Bind( tr.dlightImage ); @@ -1167,7 +1198,7 @@ static void ProjectDlightTextureVBOGLSL( void ) { if (tess.multiDrawPrimitives) { - R_DrawMultiElementsVBO(tess.multiDrawPrimitives, (const GLvoid **) tess.multiDrawFirstIndex, tess.multiDrawNumIndexes); + R_DrawMultiElementsVBO(tess.multiDrawPrimitives, (const GLvoid **)tess.multiDrawFirstIndex, tess.multiDrawNumIndexes); } else { @@ -1225,29 +1256,70 @@ Blends a fog texture on top of everything else */ static void RB_FogPassVBOGLSL( void ) { fog_t *fog; + vec3_t local; vec4_t color; - matrix_t matrix; - shaderProgram_t *sp = GLSL_GetGenericShaderProgram(); + vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0}; + float eyeT; + shaderProgram_t *sp = &tr.fogShader; + + backEnd.pc.c_fogDraws++; GLSL_BindProgram(sp); fog = tr.world->fogs + tess.fogNum; - GLSL_SetUniform_FogAdjustColors(sp, 4); - GLSL_SetUniform_TCGen0(sp, TCGEN_IDENTITY); - Matrix16Identity(matrix); - GLSL_SetUniform_Texture0Matrix(sp, matrix); - GLSL_SetUniform_Texture1Env(sp, 0); - GLSL_SetUniform_ColorGen(sp, CGEN_CONST); - GLSL_SetUniform_AlphaGen(sp, AGEN_CONST); + GLSL_SetUniformMatrix16(sp, FOGPASS_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); + + GLSL_SetUniformFloat(sp, FOGPASS_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); + + // u_DeformGen + if(!ShaderRequiresCPUDeforms(tess.shader)) + { + deformStage_t *ds; + + // only support the first one + ds = &tess.shader->deforms[0]; + + switch (ds->deformation) + { + case DEFORM_WAVE: + GLSL_SetUniformInt(sp, FOGPASS_UNIFORM_DEFORMGEN, ds->deformationWave.func); + { + vec4_t v; + waveForm_t *wf = &ds->deformationWave; + VectorSet4(v, wf->base, wf->amplitude, wf->phase, wf->frequency); + GLSL_SetUniformVec4(sp, FOGPASS_UNIFORM_DEFORMWAVE, v); + } + GLSL_SetUniformFloat(sp, FOGPASS_UNIFORM_DEFORMSPREAD, ds->deformationSpread); + GLSL_SetUniformFloat(sp, FOGPASS_UNIFORM_TIME, tess.shaderTime); + break; + + case DEFORM_BULGE: + GLSL_SetUniformInt(sp, FOGPASS_UNIFORM_DEFORMGEN, DGEN_BULGE); + { + vec3_t v; + VectorSet(v, ds->bulgeWidth, ds->bulgeHeight, ds->bulgeSpeed); + GLSL_SetUniformVec3(sp, FOGPASS_UNIFORM_DEFORMBULGE, v); + } + GLSL_SetUniformFloat(sp, FOGPASS_UNIFORM_TIME, tess.shaderTime); + break; + + default: + GLSL_SetUniformInt(sp, FOGPASS_UNIFORM_DEFORMGEN, DGEN_NONE); + break; + } + } + else + { + GLSL_SetUniformInt(sp, FOGPASS_UNIFORM_DEFORMGEN, DGEN_NONE); + } color[0] = ((unsigned char *)(&fog->colorInt))[0] / 255.0f; color[1] = ((unsigned char *)(&fog->colorInt))[1] / 255.0f; color[2] = ((unsigned char *)(&fog->colorInt))[2] / 255.0f; color[3] = ((unsigned char *)(&fog->colorInt))[3] / 255.0f; - GLSL_SetUniform_Color(sp, color); + GLSL_SetUniformVec4(sp, FOGPASS_UNIFORM_COLOR, color); -#if 0 // already set // from RB_CalcFogTexCoords() VectorSubtract( backEnd.or.origin, backEnd.viewParms.or.origin, local ); fogDistanceVector[0] = -backEnd.or.modelMatrix[2]; @@ -1278,14 +1350,9 @@ static void RB_FogPassVBOGLSL( void ) { fogDistanceVector[3] += 1.0/512; - //ri.Printf(PRINT_ALL,"eyeT %f fogDistanceVector %f %f %f %f fogDepthVector %f %f %f %f\n", eyeT, fogDistanceVector[0], fogDistanceVector[1], fogDistanceVector[2], fogDistanceVector[3], fogDepthVector[0], fogDepthVector[1], fogDepthVector[2], fogDepthVector[3]); - //ri.Printf(PRINT_ALL, "fogsurface %f %f %f %f\n", fog->surface[0], fog->surface[1], fog->surface[2], fog->surface[3]); - - GLSL_SetUniform_TCGen0Vector0(sp, fogDistanceVector); - GLSL_SetUniform_TCGen0Vector1(sp, fogDepthVector); - GLSL_SetUniform_FogEyeT(sp, eyeT); -#endif - GL_Bind( tr.fogImage ); + GLSL_SetUniformVec4(sp, FOGPASS_UNIFORM_FOGDISTANCE, fogDistanceVector); + GLSL_SetUniformVec4(sp, FOGPASS_UNIFORM_FOGDEPTH, fogDepthVector); + GLSL_SetUniformFloat(sp, FOGPASS_UNIFORM_FOGEYET, eyeT); if ( tess.shader->fogPass == FP_EQUAL ) { GL_State( GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA | GLS_DEPTHFUNC_EQUAL ); @@ -1295,7 +1362,7 @@ static void RB_FogPassVBOGLSL( void ) { if (tess.multiDrawPrimitives) { - R_DrawMultiElementsVBO(tess.multiDrawPrimitives, (const GLvoid **) tess.multiDrawFirstIndex, tess.multiDrawNumIndexes); + R_DrawMultiElementsVBO(tess.multiDrawPrimitives, (const GLvoid **)tess.multiDrawFirstIndex, tess.multiDrawNumIndexes); } else { @@ -1879,6 +1946,8 @@ static void ComputeColorMatrix( shaderStage_t *pStage, float *outmatrix, qboolea outmatrix[15] = 0.0f; } break; + default: + break; } // @@ -2289,7 +2358,7 @@ static void RB_IterateStagesGenericVBO( shaderCommands_t *input ) if (input->multiDrawPrimitives) { - R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **) input->multiDrawFirstIndex, input->multiDrawNumIndexes); + R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **)input->multiDrawFirstIndex, input->multiDrawNumIndexes); } else { @@ -2324,18 +2393,18 @@ static void DrawMultitexturedVBOGLSL( shaderProgram_t *sp, shaderCommands_t *inp // // base // - GLSL_SetUniform_TCGen0(sp, pStage->bundle[0].tcGen); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TCGEN0, pStage->bundle[0].tcGen); if (pStage->bundle[0].tcGen == TCGEN_VECTOR) { vector[3] = 0.0f; VectorCopy(pStage->bundle[0].tcGenVectors[0], vector); - GLSL_SetUniform_TCGen0Vector0(sp, vector); + GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_TCGEN0VECTOR0, vector); VectorCopy(pStage->bundle[0].tcGenVectors[1], vector); - GLSL_SetUniform_TCGen0Vector1(sp, vector); + GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_TCGEN0VECTOR1, vector); } ComputeTexMatrix( pStage, 0, matrix ); - GLSL_SetUniform_Texture0Matrix(sp, matrix); + GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_TEXTURE0MATRIX, matrix); R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 ); @@ -2343,16 +2412,16 @@ static void DrawMultitexturedVBOGLSL( shaderProgram_t *sp, shaderCommands_t *inp // lightmap/secondary pass // if ( r_lightmap->integer ) { - GLSL_SetUniform_Texture1Env(sp, GL_REPLACE); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TEXTURE1ENV, GL_REPLACE); } else { - GLSL_SetUniform_Texture1Env(sp, tess.shader->multitextureEnv); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TEXTURE1ENV, tess.shader->multitextureEnv); } R_BindAnimatedImageToTMU( &pStage->bundle[1], 1 ); if (input->multiDrawPrimitives) { - R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **) input->multiDrawFirstIndex, input->multiDrawNumIndexes); + R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **)input->multiDrawFirstIndex, input->multiDrawNumIndexes); } else { @@ -2385,13 +2454,13 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input ) GLSL_BindProgram(sp); - GLSL_SetUniform_ModelViewProjectionMatrix(sp, glState.modelviewProjection); - GLSL_SetUniform_ViewOrigin(sp, backEnd.or.viewOrigin); + GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); + GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_VIEWORIGIN, backEnd.or.viewOrigin); - GLSL_SetUniform_VertexLerp(sp, glState.vertexAttribsInterpolation); + GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation); // u_DeformGen - if(input->shader->numDeforms) + if(!ShaderRequiresCPUDeforms(input->shader)) { deformStage_t *ds; @@ -2401,26 +2470,39 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input ) switch (ds->deformation) { case DEFORM_WAVE: - GLSL_SetUniform_DeformGen(sp, ds->deformationWave.func); - GLSL_SetUniform_DeformWave(sp, &ds->deformationWave); - GLSL_SetUniform_DeformSpread(sp, ds->deformationSpread); - GLSL_SetUniform_Time(sp, tess.shaderTime); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, ds->deformationWave.func); + { + vec4_t v; + waveForm_t *wf = &ds->deformationWave; + + VectorSet4(v, wf->base, wf->amplitude, wf->phase, wf->frequency); + + GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_DEFORMWAVE, v); + } + GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_DEFORMSPREAD, ds->deformationSpread); + GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime); break; case DEFORM_BULGE: - GLSL_SetUniform_DeformGen(sp, DGEN_BULGE); - GLSL_SetUniform_DeformBulge(sp, ds); - GLSL_SetUniform_Time(sp, tess.shaderTime); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, DGEN_BULGE); + { + vec3_t v; + + VectorSet(v, ds->bulgeWidth, ds->bulgeHeight, ds->bulgeSpeed); + + GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DEFORMBULGE, v); + } + GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime); break; default: - GLSL_SetUniform_DeformGen(sp, DGEN_NONE); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, DGEN_NONE); break; } } else { - GLSL_SetUniform_DeformGen(sp, DGEN_NONE); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, DGEN_NONE); } if ( input->fogNum ) { @@ -2455,9 +2537,9 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input ) eyeT = 1; // non-surface fog always has eye inside } - GLSL_SetUniform_FogDistance(sp, fogDistanceVector); - GLSL_SetUniform_FogDepth(sp, fogDepthVector); - GLSL_SetUniform_FogEyeT(sp, eyeT); + GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDISTANCE, fogDistanceVector); + GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDEPTH, fogDepthVector); + GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_FOGEYET, eyeT); } for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) @@ -2484,13 +2566,13 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input ) switch (pStage->alphaGen) { + case AGEN_SKIP: case AGEN_IDENTITY: case AGEN_LIGHTING_SPECULAR: case AGEN_VERTEX: case AGEN_ONE_MINUS_VERTEX: case AGEN_PORTAL: break; - case AGEN_SKIP: default: setcolor = qtrue; } @@ -2499,10 +2581,10 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input ) { vec4_t color; -// JBravo: silincing a compiler warning about color being uninitialized - MAKERGBA(color, 1.f, 1.f, 1.f, 1.f); + VectorSet4(color, 1.0f, 1.0f, 1.0f, 1.0f); + ComputeHelperColor (pStage, color); - GLSL_SetUniform_Color(sp, color); + GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_COLOR, color); } if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE) @@ -2510,29 +2592,29 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input ) vec3_t vec; VectorScale(backEnd.currentEntity->ambientLight, 1.0f / 255.0f, vec); - GLSL_SetUniform_AmbientLight(sp, vec); + GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, vec); VectorScale(backEnd.currentEntity->directedLight, 1.0f / 255.0f, vec); - GLSL_SetUniform_DirectedLight(sp, vec); + GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, vec); - GLSL_SetUniform_LightDir(sp, backEnd.currentEntity->lightDir); + GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_LIGHTDIR, backEnd.currentEntity->lightDir); } if (pStage->alphaGen == AGEN_PORTAL) { - GLSL_SetUniform_PortalRange(sp, tess.shader->portalRange); + GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_PORTALRANGE, tess.shader->portalRange); } - GLSL_SetUniform_ColorGen(sp, pStage->rgbGen); - GLSL_SetUniform_AlphaGen(sp, pStage->alphaGen); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_COLORGEN, pStage->rgbGen); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, pStage->alphaGen); if ( input->fogNum ) { - GLSL_SetUniform_FogAdjustColors(sp, pStage->adjustColorsForFog); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, pStage->adjustColorsForFog); } else { - GLSL_SetUniform_FogAdjustColors(sp, 0); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, 0); } // @@ -2544,20 +2626,20 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input ) } else { - GLSL_SetUniform_TCGen0(sp, pStage->bundle[0].tcGen); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TCGEN0, pStage->bundle[0].tcGen); if (pStage->bundle[0].tcGen == TCGEN_VECTOR) { vec4_t vector; VectorCopy(pStage->bundle[0].tcGenVectors[0], vector); vector[3] = 0.0f; - GLSL_SetUniform_TCGen0Vector0(sp, vector); + GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_TCGEN0VECTOR0, vector); VectorCopy(pStage->bundle[0].tcGenVectors[1], vector); - GLSL_SetUniform_TCGen0Vector1(sp, vector); + GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_TCGEN0VECTOR1, vector); } ComputeTexMatrix( pStage, 0, matrix ); - GLSL_SetUniform_Texture0Matrix(sp, matrix); + GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_TEXTURE0MATRIX, matrix); // // set state @@ -2569,7 +2651,7 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input ) else R_BindAnimatedImage( &pStage->bundle[0] ); - GLSL_SetUniform_Texture1Env(sp, 0); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TEXTURE1ENV, 0); // // draw @@ -2577,7 +2659,7 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input ) if (input->multiDrawPrimitives) { - R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **) input->multiDrawFirstIndex, input->multiDrawNumIndexes); + R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **)input->multiDrawFirstIndex, input->multiDrawNumIndexes); } else { @@ -2728,6 +2810,8 @@ void RB_StageIteratorGenericVBO( void ) return; } + backEnd.pc.c_genericDraws++; + if (tess.useInternalVBO) { RB_DeformTessGeometry(); @@ -2914,6 +2998,116 @@ void RB_StageIteratorVertexLitTexture( void ) //define REPLACE_MODE +void RB_StageIteratorLightmappedMultitextureVBOGLSL( void ) +{ + shaderCommands_t *input; + unsigned int vertexAttribs = 0; + shaderProgram_t *sp; + shaderStage_t *pStage; + matrix_t matrix; + + input = &tess; + + if (!input->numVertexes || !input->numIndexes) + { + return; + } + + backEnd.pc.c_lightmappedDraws++; + + vertexAttribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD; //RB_CalcShaderVertexAttribs( input ); + + if (tess.useInternalVBO) + { + RB_UpdateVBOs(vertexAttribs); + } + else + { + backEnd.pc.c_staticVboDraws++; + } + + // + // log this call + // + if ( r_logFile->integer ) + { + // don't just call LogComment, or we will get + // a call to va() every frame! + GLimp_LogComment( va("--- RB_StageIteratorLightmappedMultitextureVBOGLSL( %s ) ---\n", tess.shader->name) ); + } + + // + // set face culling appropriately + // + GL_Cull( input->shader->cullType ); + + // + // Set vertex attribs and pointers + // + if (glRefConfig.glsl && r_arb_shader_objects->integer) + { + GLSL_VertexAttribsState(vertexAttribs); + } + + // + // Bind lightmapped shader + // + sp = &tr.lightmappedShader; + GLSL_BindProgram(sp); + GLSL_SetUniformMatrix16(sp, LIGHTMAPPED_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); + + pStage = input->xstages[0]; + GL_State( pStage->stateBits ); + + // + // base + // + ComputeTexMatrix( pStage, 0, matrix ); + GLSL_SetUniformMatrix16(sp, LIGHTMAPPED_UNIFORM_TEXTURE0MATRIX, matrix); + + R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 ); + + // + // lightmap/secondary pass + // +#if 0 + if ( r_lightmap->integer ) { + GLSL_SetUniformInt(sp, LIGHTMAPPED_UNIFORM_TEXTURE1ENV, GL_REPLACE); + } else { + GLSL_SetUniformInt(sp, LIGHTMAPPED_UNIFORM_TEXTURE1ENV, tess.shader->multitextureEnv); + } +#endif + + R_BindAnimatedImageToTMU( &pStage->bundle[1], 1 ); + + // + // draw + // + if (input->multiDrawPrimitives) + { + R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **)input->multiDrawFirstIndex, input->multiDrawNumIndexes); + } + else + { + R_DrawElementsVBO(input->numIndexes, input->firstIndex); + } + + // + // now do any dynamic lighting needed + // + if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE + && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) { + ProjectDlightTextureVBOGLSL(); + } + + // + // now do fog + // + if ( tess.fogNum && tess.shader->fogPass ) { + RB_FogPassVBOGLSL(); + } +} + void RB_StageIteratorLightmappedMultitexture( void ) { shaderCommands_t *input; diff --git a/reaction/code/renderer/tr_shader.c b/reaction/code/renderer/tr_shader.c index daff3e35..742052cb 100644 --- a/reaction/code/renderer/tr_shader.c +++ b/reaction/code/renderer/tr_shader.c @@ -1656,8 +1656,11 @@ static void ComputeStageIteratorFunc( void ) if ( glRefConfig.vertexBufferObject && r_arb_vertex_buffer_object->integer ) { - // VBOs don't support the fast path! - return; + if (!(glRefConfig.glsl && r_arb_shader_objects->integer)) + { + // VBOs without shader objects don't support the fast path! + return; + } } // @@ -1677,7 +1680,14 @@ static void ComputeStageIteratorFunc( void ) { if ( !shader.numDeforms ) { - shader.optimalStageIteratorFunc = RB_StageIteratorVertexLitTexture; + if (glRefConfig.vertexBufferObject && r_arb_vertex_buffer_object->integer && glRefConfig.glsl && r_arb_shader_objects->integer) + { + //shader.optimalStageIteratorFunc = RB_StageIteratorVertexLitTextureVBOGLSL; + } + else + { + shader.optimalStageIteratorFunc = RB_StageIteratorVertexLitTexture; + } goto done; } } @@ -1701,9 +1711,16 @@ static void ComputeStageIteratorFunc( void ) { if ( !shader.numDeforms ) { - if ( shader.multitextureEnv ) + if ( shader.multitextureEnv == GL_MODULATE && !stages[0].adjustColorsForFog ) { - shader.optimalStageIteratorFunc = RB_StageIteratorLightmappedMultitexture; + if (glRefConfig.vertexBufferObject && r_arb_vertex_buffer_object->integer && glRefConfig.glsl && r_arb_shader_objects->integer) + { + shader.optimalStageIteratorFunc = RB_StageIteratorLightmappedMultitextureVBOGLSL; + } + else + { + shader.optimalStageIteratorFunc = RB_StageIteratorLightmappedMultitexture; + } goto done; } } diff --git a/reaction/code/renderer/tr_sky.c b/reaction/code/renderer/tr_sky.c index bd8ecab2..43899362 100644 --- a/reaction/code/renderer/tr_sky.c +++ b/reaction/code/renderer/tr_sky.c @@ -448,22 +448,22 @@ static void DrawSkySideVBO( struct image_s *image, const int mins[2], const int GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD); GLSL_BindProgram(sp); - GLSL_SetUniform_ModelViewProjectionMatrix(sp, glState.modelviewProjection); + GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); - GLSL_SetUniform_FogAdjustColors(sp, 0); - GLSL_SetUniform_DeformGen(sp, DGEN_NONE); - GLSL_SetUniform_TCGen0(sp, TCGEN_TEXTURE); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, 0); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, DGEN_NONE); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TCGEN0, TCGEN_TEXTURE); Matrix16Identity(matrix); - GLSL_SetUniform_Texture0Matrix(sp, matrix); - GLSL_SetUniform_Texture1Env(sp, 0); - GLSL_SetUniform_ColorGen(sp, CGEN_CONST); - GLSL_SetUniform_AlphaGen(sp, AGEN_CONST); + GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_TEXTURE0MATRIX, matrix); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TEXTURE1ENV, 0); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_COLORGEN, CGEN_CONST); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, AGEN_CONST); color[0] = tr.identityLight; color[1] = tr.identityLight; color[2] = tr.identityLight; color[3] = 1.0f; - GLSL_SetUniform_Color(sp, color); + GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_COLOR, color); } else { diff --git a/reaction/code/renderer/tr_surface.c b/reaction/code/renderer/tr_surface.c index 147a3203..b8ad5a86 100644 --- a/reaction/code/renderer/tr_surface.c +++ b/reaction/code/renderer/tr_surface.c @@ -173,8 +173,6 @@ based on Tess_InstantQuad from xreal */ void RB_InstantQuad(vec4_t quadVerts[4]) { - matrix_t matrix; - GLimp_LogComment("--- RB_InstantQuad ---\n"); tess.numVertexes = 0; @@ -216,25 +214,16 @@ void RB_InstantQuad(vec4_t quadVerts[4]) tess.indexes[tess.numIndexes++] = 2; tess.indexes[tess.numIndexes++] = 3; - // FIXME: A lot of this can probably be removed for speed RB_UpdateVBOs(ATTR_POSITION | ATTR_TEXCOORD); if (glRefConfig.glsl && r_arb_shader_objects->integer) { - shaderProgram_t *sp = &tr.genericShader[0]; + shaderProgram_t *sp = &tr.textureOnlyShader; + GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD); GLSL_BindProgram(sp); - - GLSL_SetUniform_ModelViewProjectionMatrix(sp, glState.modelviewProjection); - - GLSL_SetUniform_FogAdjustColors(sp, 0); - GLSL_SetUniform_DeformGen(sp, DGEN_NONE); - GLSL_SetUniform_TCGen0(sp, TCGEN_TEXTURE); - Matrix16Identity(matrix); - GLSL_SetUniform_Texture0Matrix(sp, matrix); - GLSL_SetUniform_Texture1Env(sp, 0); - GLSL_SetUniform_ColorGen(sp, CGEN_IDENTITY); - GLSL_SetUniform_AlphaGen(sp, AGEN_IDENTITY); + + GLSL_SetUniformMatrix16(sp, TEXTUREONLY_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); } else { @@ -592,22 +581,22 @@ static void RB_SurfaceBeam( void ) GLSL_VertexAttribsState(ATTR_POSITION); GLSL_BindProgram(sp); - GLSL_SetUniform_ModelViewProjectionMatrix(sp, glState.modelviewProjection); + GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection); - GLSL_SetUniform_FogAdjustColors(sp, 0); - GLSL_SetUniform_DeformGen(sp, DGEN_NONE); - GLSL_SetUniform_TCGen0(sp, TCGEN_IDENTITY); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, 0); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, DGEN_NONE); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TCGEN0, TCGEN_IDENTITY); Matrix16Identity(matrix); - GLSL_SetUniform_Texture0Matrix(sp, matrix); - GLSL_SetUniform_Texture1Env(sp, 0); - GLSL_SetUniform_ColorGen(sp, CGEN_CONST); - GLSL_SetUniform_AlphaGen(sp, AGEN_CONST); + GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_TEXTURE0MATRIX, matrix); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_TEXTURE1ENV, 0); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_COLORGEN, CGEN_CONST); + GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, AGEN_CONST); color[0] = 1.0f; color[1] = 0.0f; color[2] = 0.0f; color[3] = 1.0f; - GLSL_SetUniform_Color(sp, color); + GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_COLOR, color); } else {