VBOS-GLSL patch V14

This commit is contained in:
Richard Allen 2011-04-19 01:39:02 +00:00
parent 43fece54e0
commit cb12d2ca68
10 changed files with 1235 additions and 586 deletions

View file

@ -2655,11 +2655,18 @@ void R_LoadEntities( lump_t *l ) {
continue; continue;
} }
// check for deluxe mapping support
if(!Q_stricmp(keyname, "deluxeMapping") && !Q_stricmp(value, "1"))
{
ri.Printf(PRINT_ALL, "map features directional light mapping\n");
tr.worldDeluxeMapping = qtrue;
continue;
}
// check for deluxe mapping provided by NetRadiant's q3map2 // check for deluxe mapping provided by NetRadiant's q3map2
//FIXME: xmap2? //FIXME: xmap2?
if(!Q_stricmp(keyname, "_q3map2_cmdline")) if(!Q_stricmp(keyname, "_q3map2_cmdline"))
{ {
ri.Printf(PRINT_ALL, "wtf? %s %s\n", keyname, value);
s = strstr(value, "-deluxe"); s = strstr(value, "-deluxe");
if(s) if(s)
{ {

View file

@ -73,8 +73,8 @@ void R_PerformanceCounters( void ) {
{ {
ri.Printf( PRINT_ALL, "VBO draws: static %i dynamic %i\nMultidraws: %i merged %i\n", 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 ); 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", ri.Printf( PRINT_ALL, "GLSL binds: %i draws: gen %i light %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); backEnd.pc.c_glslShaderBinds, backEnd.pc.c_genericDraws, backEnd.pc.c_lightallDraws, backEnd.pc.c_fogDraws, backEnd.pc.c_dlightDraws);
} }
Com_Memset( &tr.pc, 0, sizeof( tr.pc ) ); Com_Memset( &tr.pc, 0, sizeof( tr.pc ) );

View file

@ -30,149 +30,120 @@ static const char *fallbackGenericShader_vp =
"e vec4 attr_TexCoord1;\r\nattribute vec3 attr_Normal;\r\nattribute vec4 att" "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" "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_" "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" "DiffuseTexMatrix;\r\nuniform vec3 u_ViewOrigin;\r\n\r\n#if defined(USE_TC"
"N)\r\nuniform int u_TCGen0;\r\nuniform vec4 u_TCGen0Vector0;\r\nunifor" "GEN)\r\nuniform int u_TCGen0;\r\nuniform vec4 u_TCGen0Vector0;\r\nunif"
"m vec4 u_TCGen0Vector1;\r\n#endif\r\n\r\n#if defined(USE_FOG)\r\nuniform " "orm vec4 u_TCGen0Vector1;\r\n#endif\r\n\r\n#if defined(USE_FOG)\r\nunifor"
"vec4 u_FogDistance;\r\nuniform vec4 u_FogDepth;\r\nuniform float u_Fog" "m vec4 u_FogDistance;\r\nuniform vec4 u_FogDepth;\r\nuniform float u_F"
"EyeT;\r\nuniform int u_FogAdjustColors;\r\n#endif\r\n\r\n#if defined(USE" "ogEyeT;\r\nuniform int u_FogAdjustColors;\r\n#endif\r\n\r\n#if defined(U"
"_DEFORM_VERTEXES)\r\nuniform int u_DeformGen;\r\nuniform vec4 u_Deform" "SE_DEFORM_VERTEXES)\r\nuniform int u_DeformGen;\r\nuniform vec4 u_Defo"
"Wave;\r\nuniform vec3 u_DeformBulge;\r\nuniform float u_DeformSpread;\r" "rmWave;\r\nuniform vec3 u_DeformBulge;\r\nuniform float u_DeformSpread;"
"\n#endif\r\n\r\nuniform float u_Time;\r\nuniform int u_ColorGen;\r\nuni" "\r\n#endif\r\n\r\nuniform float u_Time;\r\n\r\nuniform mat4 u_ModelViewP"
"form int u_AlphaGen;\r\nuniform vec4 u_Color;\r\nuniform mat4 u_Mode" "rojectionMatrix;\r\nuniform vec4 u_Color;\r\n\r\n#if defined(USE_RGBAGEN)"
"lViewProjectionMatrix;\r\nuniform vec3 u_AmbientLight;\r\nuniform vec3 " "\r\nuniform int u_ColorGen;\r\nuniform int u_AlphaGen;\r\nuniform vec"
"u_DirectedLight;\r\nuniform vec3 u_LightDir;\r\n\r\nuniform float u_Port" "3 u_AmbientLight;\r\nuniform vec3 u_DirectedLight;\r\nuniform vec4 u_"
"alRange;\r\n\r\n#if defined(USE_VERTEX_ANIMATION)\r\nuniform float u_Verte" "LightOrigin;\r\nuniform float u_PortalRange;\r\n#endif\r\n\r\n#if defined("
"xLerp;\r\n#endif\r\n\r\nvarying vec2 var_Tex1;\r\nvarying vec2 var_Tex2" "USE_VERTEX_ANIMATION)\r\nuniform float u_VertexLerp;\r\n#endif\r\n\r\nvary"
";\r\nvarying vec4 var_Color;\r\n\r\n#if defined(USE_DEFORM_VERTEXES)\r\nf" "ing vec2 var_DiffuseTex;\r\nvarying vec2 var_LightTex;\r\nvarying vec4 "
"loat triangle(float x)\r\n{\r\n\treturn max(1.0 - abs(x), 0);\r\n}\r\n\r\nf" " var_Color;\r\n\r\n#if defined(USE_DEFORM_VERTEXES)\r\nfloat triangle(floa"
"loat sawtooth(float x)\r\n{\r\n\treturn x - floor(x);\r\n}\r\n\r\nvec4 Defo" "t x)\r\n{\r\n\treturn max(1.0 - abs(x), 0);\r\n}\r\n\r\nfloat sawtooth(floa"
"rmPosition(const vec4 pos, const vec3 normal, const vec2 st)\r\n{\r\n\tvec4" "t x)\r\n{\r\n\treturn x - floor(x);\r\n}\r\n\r\nvec4 DeformPosition(const v"
" deformed = pos;\r\n\r\n\tif (u_DeformGen == DGEN_WAVE_SIN)\r\n\t{\r\n\t\tf" "ec4 pos, const vec3 normal, const vec2 st)\r\n{\r\n\tvec4 deformed = pos;\r"
"loat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u" "\n\r\n\tif (u_DeformGen == DGEN_WAVE_SIN)\r\n\t{\r\n\t\tfloat off = (pos.x "
"_DeformWave.x + sin((off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * 2" "+ pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave.x + s"
".0 * M_PI) * u_DeformWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t" "in((off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * 2.0 * M_PI) * u_Def"
"\tdeformed.xyz += offset;\r\n\t}\r\n\telse if (u_DeformGen == DGEN_WAVE_SQU" "ormWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += "
"ARE)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r" "offset;\r\n\t}\r\n\telse if (u_DeformGen == DGEN_WAVE_SQUARE)\r\n\t{\r\n\t"
"\n\t\tfloat scale = u_DeformWave.x + sign(sin((off + u_DeformWave.z + (u_T" "\tfloat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale "
"ime * u_DeformWave.w)) * 2.0 * M_PI)) * u_DeformWave.y;\r\n\t\tvec3 offset " "= u_DeformWave.x + sign(sin((off + u_DeformWave.z + (u_Time * u_DeformWave"
"= normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\telse if (u" ".w)) * 2.0 * M_PI)) * u_DeformWave.y;\r\n\t\tvec3 offset = normal * scale;"
"_DeformGen == DGEN_WAVE_TRIANGLE)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y " "\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\telse if (u_DeformGen == DGE"
"+ pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave.x + triangle(" "N_WAVE_TRIANGLE)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_Defo"
"off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * u_DeformWave.y;\r\n\t\t" "rmSpread;\r\n\t\tfloat scale = u_DeformWave.x + triangle(off + u_DeformWav"
"vec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n" "e.z + (u_Time * u_DeformWave.w)) * u_DeformWave.y;\r\n\t\tvec3 offset = nor"
"\telse if (u_DeformGen == DGEN_WAVE_SAWTOOTH)\r\n\t{\r\n\t\tfloat off = (po" "mal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\telse if (u_Defo"
"s.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave.x " "rmGen == DGEN_WAVE_SAWTOOTH)\r\n\t{\r\n\t\tfloat off = (pos.x + pos.y + pos"
" + sawtooth(off + u_DeformWave.z + (u_Time * u_DeformWave.w)) * u_DeformWav" ".z) * u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave.x + sawtooth(off +"
"e.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset" " u_DeformWave.z + (u_Time * u_DeformWave.w)) * u_DeformWave.y;\r\n\t\tvec3 "
";\r\n\t}\r\n\telse if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)\r\n\t{\r" "offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\tels"
"\n\t\tfloat off = (pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat sc" "e if (u_DeformGen == DGEN_WAVE_INVERSE_SAWTOOTH)\r\n\t{\r\n\t\tfloat off = "
"ale = u_DeformWave.x + (1.0 - sawtooth(off + u_DeformWave.z + (u_Time * u_D" "(pos.x + pos.y + pos.z) * u_DeformSpread;\r\n\t\tfloat scale = u_DeformWave"
"eformWave.w))) * u_DeformWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r" ".x + (1.0 - sawtooth(off + u_DeformWave.z + (u_Time * u_DeformWave.w))) * u"
"\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\telse if (u_DeformGen == DGEN_BULG" "_DeformWave.y;\r\n\t\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz"
"E)\r\n\t{\r\n\t\tfloat bulgeWidth = u_DeformBulge.x;\r\n\t\tfloat bulgeHeig" " += offset;\r\n\t}\r\n\telse if (u_DeformGen == DGEN_BULGE)\r\n\t{\r\n\t\tf"
"ht = u_DeformBulge.y;\r\n\t\tfloat bulgeSpeed = u_DeformBulge.z;\r\n\r\n\t" "loat bulgeWidth = u_DeformBulge.x;\r\n\t\tfloat bulgeHeight = u_DeformBulge"
"\tfloat now = u_Time * bulgeSpeed;\r\n\r\n\t\tfloat off = (M_PI * 0.25) * s" ".y;\r\n\t\tfloat bulgeSpeed = u_DeformBulge.z;\r\n\r\n\t\tfloat now = u_Tim"
"t.x * bulgeWidth + now;\r\n\t\tfloat scale = sin(off) * bulgeHeight;\r\n\t" "e * bulgeSpeed;\r\n\r\n\t\tfloat off = (M_PI * 0.25) * st.x * bulgeWidth + "
"\tvec3 offset = normal * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r" "now;\r\n\t\tfloat scale = sin(off) * bulgeHeight;\r\n\t\tvec3 offset = norm"
"\n\r\n\treturn deformed;\r\n}\r\n#endif\r\n\r\n#if defined(USE_TCGEN)\r\nve" "al * scale;\r\n\r\n\t\tdeformed.xyz += offset;\r\n\t}\r\n\r\n\treturn defor"
"c2 GenTexCoords(int TCGen, vec4 position, vec3 normal, mat4 texMatrix, vec4" "med;\r\n}\r\n#endif\r\n\r\n#if defined(USE_TCGEN)\r\nvec2 GenTexCoords(int "
" TCGenVector0, vec4 TCGenVector1)\r\n{\r\n\tvec2 tex = vec2(0.0);\r\n\r\n\t" "TCGen, vec4 position, vec3 normal, vec4 TCGenVector0, vec4 TCGenVector1)\r"
"if (TCGen == TCGEN_LIGHTMAP)\r\n\t{\r\n\t\ttex = attr_TexCoord1.st;\r\n\t}" "\n{\r\n\tvec2 tex = vec2(0.0);\r\n\r\n\tif (TCGen == TCGEN_LIGHTMAP)\r\n\t{"
"\r\n\telse if (TCGen == TCGEN_TEXTURE)\r\n\t{\r\n\t\ttex = attr_TexCoord0.s" "\r\n\t\ttex = attr_TexCoord1.st;\r\n\t}\r\n\telse if (TCGen == TCGEN_TEXTUR"
"t;\r\n\t}\r\n\telse if (TCGen == TCGEN_ENVIRONMENT_MAPPED)\r\n\t{\r\n\t\tve" "E)\r\n\t{\r\n\t\ttex = attr_TexCoord0.st;\r\n\t}\r\n\telse if (TCGen == TCG"
"c3 viewer = normalize(u_ViewOrigin - position.xyz);\r\n\r\n\t\tfloat d = do" "EN_ENVIRONMENT_MAPPED)\r\n\t{\r\n\t\tvec3 viewer = normalize(u_ViewOrigin -"
"t(normal, viewer);\r\n\r\n\t\tvec3 reflected = normal * 2.0 * d - viewer;\r" " position.xyz);\r\n\r\n\t\tfloat d = dot(normal, viewer);\r\n\r\n\t\tvec3 r"
"\n\r\n\t\ttex.s = 0.5 + reflected.y * 0.5;\r\n\t\ttex.t = 0.5 - reflected.z" "eflected = normal * 2.0 * d - viewer;\r\n\r\n\t\ttex.s = 0.5 + reflected.y "
" * 0.5;\r\n\t}\r\n\telse if (TCGen == TCGEN_VECTOR)\r\n\t{\r\n\t\ttex.s = d" "* 0.5;\r\n\t\ttex.t = 0.5 - reflected.z * 0.5;\r\n\t}\r\n\telse if (TCGen ="
"ot(position.xyz, TCGenVector0.xyz);\r\n\t\ttex.t = dot(position.xyz, TCGenV" "= TCGEN_VECTOR)\r\n\t{\r\n\t\ttex.s = dot(position.xyz, TCGenVector0.xyz);"
"ector1.xyz);\r\n\t}\r\n\t\r\n\treturn tex;\r\n}\r\n#endif\r\n\r\nvoid main(" "\r\n\t\ttex.t = dot(position.xyz, TCGenVector1.xyz);\r\n\t}\r\n\t\r\n\tretu"
")\r\n{\r\n\tvec4 position;\r\n\tvec3 normal;\r\n\tvec4 tex;\r\n\r\n#if defi" "rn tex;\r\n}\r\n#endif\r\n\r\nvoid main()\r\n{\r\n#if defined(USE_VERTEX_AN"
"ned(USE_VERTEX_ANIMATION)\r\n\tposition = mix(attr_Position, attr_Position2" "IMATION)\r\n\tvec4 position = mix(attr_Position, attr_Position2, u_VertexLe"
", u_VertexLerp);\r\n\tnormal = normalize(mix(attr_Normal, attr_Normal2, u_V" "rp);\r\n\tvec3 normal = normalize(mix(attr_Normal, attr_Normal2, u_VertexLe"
"ertexLerp));\r\n#else\r\n\tposition = attr_Position;\r\n\tnormal = attr_Nor" "rp));\r\n#else\r\n\tvec4 position = attr_Position;\r\n\tvec3 normal = attr_"
"mal;\r\n#endif\r\n\r\n#if defined(USE_DEFORM_VERTEXES)\r\n\tposition = Defo" "Normal;\r\n#endif\r\n\r\n#if defined(USE_DEFORM_VERTEXES)\r\n\tposition = D"
"rmPosition(position, normal, attr_TexCoord0.st);\r\n#endif\r\n\r\n\tgl_Posi" "eformPosition(position, normal, attr_TexCoord0.st);\r\n#endif\r\n\r\n\tgl_P"
"tion = u_ModelViewProjectionMatrix * position;\r\n\r\n\r\n\ttex = vec4(1.0," "osition = u_ModelViewProjectionMatrix * position;\r\n\r\n\r\n\tvec4 tex = v"
" 1.0, 1.0, 0.0);\r\n\r\n#if defined(USE_TCGEN)\r\n\ttex.st = GenTexCoords(u" "ec4(1.0, 1.0, 1.0, 0.0);\r\n\r\n#if defined(USE_TCGEN)\r\n\ttex.st = GenTex"
"_TCGen0, position, normal, u_Texture0Matrix, u_TCGen0Vector0, u_TCGen0Vecto" "Coords(u_TCGen0, position, normal, u_TCGen0Vector0, u_TCGen0Vector1);\r\n#e"
"r1);\r\n#else\r\n\ttex.st = attr_TexCoord0.st;\r\n#endif\r\n \r\n\tvar_T" "lse\r\n\ttex.st = attr_TexCoord0.st;\r\n#endif\r\n \r\n\tvar_DiffuseTex "
"ex1 = (u_Texture0Matrix * tex).st;\r\n\r\n\tvar_Tex1.s += sin(((position.x " "= (u_DiffuseTexMatrix * tex).st;\r\n\r\n\tvar_DiffuseTex.s += sin(((positio"
"+ position.z) * 1.0 / 128.0 * 0.125 + u_Texture0Matrix[3][1]) * 2.0 * M_PI)" "n.x + position.z) * 1.0 / 128.0 * 0.125 + u_DiffuseTexMatrix[3][1]) * 2.0 *"
" * u_Texture0Matrix[3][0];\r\n\tvar_Tex1.t += sin((position.y * 1.0 / 128.0" " M_PI) * u_DiffuseTexMatrix[3][0];\r\n\tvar_DiffuseTex.t += sin((position.y"
" * 0.125 + u_Texture0Matrix[3][1]) * 2.0 * M_PI) * u_Texture0Matrix[3][0];" " * 1.0 / 128.0 * 0.125 + u_DiffuseTexMatrix[3][1]) * 2.0 * M_PI) * u_Diffus"
"\r\n\r\n\tvar_Tex2 = attr_TexCoord1.st;\r\n\t\r\n\tvar_Color = u_Color;\r\n" "eTexMatrix[3][0];\r\n\r\n\tvar_LightTex = attr_TexCoord1.st;\r\n\t\r\n\tvar"
"\r\n\tif (u_ColorGen == CGEN_LIGHTING_DIFFUSE)\r\n\t{\r\n\t\tfloat incoming" "_Color = u_Color;\r\n\r\n#if defined(USE_RGBAGEN)\r\n\tif (u_ColorGen == CG"
" = max(dot(normal, u_LightDir), 0.0);\r\n\r\n\t\tvar_Color.rgb = min(u_Dire" "EN_LIGHTING_DIFFUSE)\r\n\t{\r\n\t\t// when CGEN_LIGHTING_DIFFUSE, u_LightOr"
"ctedLight * incoming + u_AmbientLight, 1.0);\r\n\t}\r\n\telse if (u_ColorGe" "igin is always at infinity, ie directional\r\n\t\tfloat incoming = max(dot("
"n == CGEN_EXACT_VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb = attr_Color.rgb;\r\n\t" "normal, u_LightOrigin.xyz), 0.0);\r\n\r\n\t\tvar_Color.rgb = min(u_Directed"
"}\r\n\telse if (u_ColorGen == CGEN_VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb *= a" "Light * incoming + u_AmbientLight, 1.0);\r\n\t}\r\n\telse if (u_ColorGen =="
"ttr_Color.rgb;\r\n\t}\r\n\telse if (u_ColorGen == CGEN_ONE_MINUS_VERTEX)\r" " CGEN_EXACT_VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb = attr_Color.rgb;\r\n\t}\r"
"\n\t{\r\n\t\tvar_Color.rgb *= (vec3(1.0) - attr_Color.rgb);\r\n\t}\r\n\r\n" "\n\telse if (u_ColorGen == CGEN_VERTEX)\r\n\t{\r\n\t\tvar_Color.rgb *= attr"
"\tif (u_AlphaGen == AGEN_LIGHTING_SPECULAR)\r\n\t{\r\n#if 0 // phong specul" "_Color.rgb;\r\n\t}\r\n\telse if (u_ColorGen == CGEN_ONE_MINUS_VERTEX)\r\n\t"
"ar\r\n\t\tvec3 lightDir = vec3(-960.0, -1980.0, 96.0) - position.xyz;\r\n\t" "{\r\n\t\tvar_Color.rgb *= (vec3(1.0) - attr_Color.rgb);\r\n\t}\r\n\r\n\tif "
"\tlightDir = normalize(lightDir);\r\n\r\n\t\tfloat d = dot(normal, lightDir" "(u_AlphaGen == AGEN_LIGHTING_SPECULAR)\r\n\t{\r\n\t\tvec3 lightDir = normal"
");\r\n\t\tvec3 reflected = normal * 2.0 * d - lightDir;\r\n\r\n\t\tvec3 vie"
"wer = u_ViewOrigin - position.xyz;\r\n\t\tfloat ilength = 1.0 / length(view"
"er);\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\te"
"lse\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#else // blinn specular\r\n\t\tvec3 lightDir = normal"
"ize(vec3(-960.0, -1980.0, 96.0) - position.xyz);\r\n\t\tvec3 viewer = norma" "ize(vec3(-960.0, -1980.0, 96.0) - position.xyz);\r\n\t\tvec3 viewer = norma"
"lize(u_ViewOrigin - position.xyz);\r\n\t\tvec3 halfangle = normalize(lightD" "lize(u_ViewOrigin - position.xyz);\r\n\t\tvec3 halfangle = normalize(lightD"
"ir + viewer);\r\n\t\t\r\n\t\tvar_Color.a = pow(max(dot(normal, halfangle), " "ir + viewer);\r\n\t\t\r\n\t\tvar_Color.a = pow(max(dot(normal, halfangle), "
"0.0), 4.0);\r\n#endif\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_VERTEX)\r\n\t" "0.0), 8.0);\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_VERTEX)\r\n\t{\r\n\t\tv"
"{\r\n\t\tvar_Color.a = attr_Color.a;\r\n\t}\r\n\telse if (u_AlphaGen == AGE" "ar_Color.a = attr_Color.a;\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_ONE_MINU"
"N_ONE_MINUS_VERTEX)\r\n\t{\r\n\t\tvar_Color.a = 1.0 - attr_Color.a;\r\n\t}" "S_VERTEX)\r\n\t{\r\n\t\tvar_Color.a = 1.0 - attr_Color.a;\r\n\t}\r\n\telse "
"\r\n\telse if (u_AlphaGen == AGEN_PORTAL)\r\n\t{\r\n\t\tfloat alpha = lengt" "if (u_AlphaGen == AGEN_PORTAL)\r\n\t{\r\n\t\tfloat alpha = length(position."
"h(position.xyz - u_ViewOrigin) / u_PortalRange;\r\n\r\n\t\tvar_Color.a = mi" "xyz - u_ViewOrigin) / u_PortalRange;\r\n\r\n\t\tvar_Color.a = min(alpha, 1."
"n(alpha, 1.0);\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_FRESNEL)\r\n\t{\r\n" "0);\r\n\t}\r\n\telse if (u_AlphaGen == AGEN_FRESNEL)\r\n\t{\r\n\t\tvec3 vie"
"\t\tvec3 viewer = normalize(u_ViewOrigin - position.xyz);\r\n\t\t\r\n\t\tva" "wer = normalize(u_ViewOrigin - position.xyz);\r\n\t\t\r\n\t\tvar_Color.a = "
"r_Color.a = dot(viewer, normal);\r\n\t}\r\n\r\n#if defined (USE_FOG)\r\n\ti" "dot(viewer, normal);\r\n\t}\r\n#endif\r\n\r\n#if defined (USE_FOG)\r\n\tif "
"f (u_FogAdjustColors != ACFF_NONE) \r\n\t{\r\n\t\tfloat s = max(dot(positio" "(u_FogAdjustColors != ACFF_NONE) \r\n\t{\r\n\t\tfloat s = max(dot(position."
"n.xyz, u_FogDistance.xyz) + u_FogDistance.a, 0.0);\r\n\t\tfloat t = max(dot" "xyz, u_FogDistance.xyz) + u_FogDistance.a, 0.0);\r\n\t\tfloat t = max(dot(p"
"(position.xyz, u_FogDepth.xyz) + u_FogDepth.a, 0.0);\r\n\t\t\r\n\t\tif (t >" "osition.xyz, u_FogDepth.xyz) + u_FogDepth.a, 0.0);\r\n\t\t\r\n\t\tif (t >= "
"= 1.0)\r\n\t\t{\r\n\t\t\ts *= t / (t - min(u_FogEyeT, 0.0));\r\n\t\t}\r\n\t" "1.0)\r\n\t\t{\r\n\t\t\ts *= t / (t - min(u_FogEyeT, 0.0));\r\n\t\t}\r\n\t\t"
"\t\r\n\t\ts = 1.0 - sqrt(min(s * 8.0, 1.0));\r\n\t\r\n\t\tif (u_FogAdjustCo" "\r\n\t\ts = 1.0 - sqrt(min(s * 8.0, 1.0));\r\n\t\r\n\t\tif (u_FogAdjustColo"
"lors == ACFF_MODULATE_RGB)\r\n\t\t{\r\n\t\t\tvar_Color.xyz *= s;\r\n\t\t}\r" "rs == ACFF_MODULATE_RGB)\r\n\t\t{\r\n\t\t\tvar_Color.xyz *= s;\r\n\t\t}\r\n"
"\n\t\telse if (u_FogAdjustColors == ACFF_MODULATE_ALPHA)\r\n\t\t{\r\n\t\t\t" "\t\telse if (u_FogAdjustColors == ACFF_MODULATE_ALPHA)\r\n\t\t{\r\n\t\t\tva"
"var_Color.a *= s;\r\n\t\t}\r\n\t\telse if (u_FogAdjustColors == ACFF_MODULA" "r_Color.a *= s;\r\n\t\t}\r\n\t\telse if (u_FogAdjustColors == ACFF_MODULATE"
"TE_RGBA)\r\n\t\t{\r\n\t\t\tvar_Color *= s;\r\n\t\t}\r\n\t}\r\n#endif\r\n}\r" "_RGBA)\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";
"\n";
static const char *fallbackGenericShader_fp = static const char *fallbackGenericShader_fp =
"uniform sampler2D u_Texture0Map;\r\nuniform sampler2D u_Texture1Map;\r\nuni" "uniform sampler2D u_DiffuseMap;\r\nuniform sampler2D u_LightMap;\r\nuniform"
"form int u_Texture1Env;\r\n\r\nvarying vec2 var_Tex1;\r\nvarying" " int u_Texture1Env;\r\n\r\nvarying vec2 var_DiffuseTex;\r\nvaryi"
" vec2 var_Tex2;\r\nvarying vec4 var_Color;\r\n\r\n\r\nvoid main()" "ng vec2 var_LightTex;\r\nvarying vec4 var_Color;\r\n\r\n\r\nvoid "
"\r\n{\r\n\tvec4 color;\r\n\r\n\tif (u_Texture1Env != 2)\r\n\t{\r\n\t\tcolor" "main()\r\n{\r\n\tvec4 color;\r\n\r\n\tif (u_Texture1Env != 2)\r\n\t{\r\n\t"
" = texture2D(u_Texture0Map, var_Tex1);\r\n\t}\r\n\r\n\tif (u_Texture1Env !=" "\tcolor = texture2D(u_DiffuseMap, var_DiffuseTex);\r\n\t}\r\n\r\n\tif (u_Te"
" 0)\r\n\t{\r\n\t\tvec4 color2 = texture2D(u_Texture1Map, var_Tex2);\r\n\r\n" "xture1Env != 0)\r\n\t{\r\n\t\tvec4 color2 = texture2D(u_LightMap, var_Light"
"\t\tif (u_Texture1Env == GL_MODULATE)\r\n\t\t{\r\n\t\t\tcolor *= color2;\r" "Tex);\r\n\r\n\t\tif (u_Texture1Env == GL_MODULATE)\r\n\t\t{\r\n\t\t\tcolor "
"\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_ADD)\r\n\t\t{\r\n"
"+= color2;\r\n\t\t}\r\n\t\t\telse // if (u_Texture1Env == GL_REPLACE)\r\n\t" "\t\t\tcolor += color2;\r\n\t\t}\r\n\t\t\telse // if (u_Texture1Env == GL_RE"
"\t{\r\n\t\t\tcolor = color2;\r\n\t\t}\r\n\t}\r\n\r\n\tcolor *= var_Color;\r" "PLACE)\r\n\t\t{\r\n\t\t\tcolor = color2;\r\n\t\t}\r\n\t}\r\n\r\n\tcolor *= "
"\n\r\n\tgl_FragColor = color;\r\n}\r\n"; "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 *fallbackTextureColorShader_vp = static const char *fallbackTextureColorShader_vp =
"#version 120\r\n\r\nattribute vec4 attr_Position;\r\nattribute vec4 attr_Te" "#version 120\r\n\r\nattribute vec4 attr_Position;\r\nattribute vec4 attr_Te"
@ -182,9 +153,9 @@ static const char *fallbackTextureColorShader_vp =
"\n"; "\n";
static const char *fallbackTextureColorShader_fp = static const char *fallbackTextureColorShader_fp =
"#version 120\r\n\r\nuniform sampler2D u_Texture0Map;\r\nuniform vec4 u" "#version 120\r\n\r\nuniform sampler2D u_DiffuseMap;\r\nuniform vec4 u_"
"_Color;\r\n\r\nvarying vec2 var_Tex1;\r\n\r\n\r\nvoid main()\r\n{\r" "Color;\r\n\r\nvarying vec2 var_Tex1;\r\n\r\n\r\nvoid main()\r\n{\r"
"\n\tgl_FragColor = texture2D(u_Texture0Map, var_Tex1) * u_Color;\r\n}\r\n"; "\n\tgl_FragColor = texture2D(u_DiffuseMap, var_Tex1) * u_Color;\r\n}\r\n";
static const char *fallbackFogPassShader_vp = static const char *fallbackFogPassShader_vp =
"attribute vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\nattribute" "attribute vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\nattribute"
@ -243,10 +214,10 @@ static const char *fallbackFogPassShader_vp =
"\r\n\tvar_Color.a = u_Color.a * s;\r\n}\r\n"; "\r\n\tvar_Color.a = u_Color.a * s;\r\n}\r\n";
static const char *fallbackFogPassShader_fp = static const char *fallbackFogPassShader_fp =
"varying vec4 var_Color;\r\n\r\n\r\nvoid\tmain()\r\n{\r\n\tgl_FragCo" "varying vec4 var_Color;\r\n\r\n\r\nvoid main()\r\n{\r\n\tgl_FragColor = var"
"lor = var_Color;\r\n}\r\n"; "_Color;\r\n}\r\n";
static const char *fallbackDlightShader_vp = static const char *fallbackDlightallShader_vp =
"attribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoord0;\r\nattribut" "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" "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_" " attr_Normal2;\r\n\r\nuniform vec4 u_DlightInfo;\r\n\r\nuniform int u_"
@ -299,59 +270,126 @@ static const char *fallbackDlightShader_vp =
"}\r\n\r\n\tvar_Tex1 = tex;\r\n\tvar_Color.rgb = u_Color.rgb * dlightmod;\r" "}\r\n\r\n\tvar_Tex1 = tex;\r\n\tvar_Color.rgb = u_Color.rgb * dlightmod;\r"
"\n\tvar_Color.a = u_Color.a;\r\n}\r\n"; "\n\tvar_Color.a = u_Color.a;\r\n}\r\n";
static const char *fallbackDlightShader_fp = static const char *fallbackDlightallShader_fp =
"uniform sampler2D u_Texture0Map;\r\n\r\nvarying vec2 var_Tex1;\r\nvary" "uniform sampler2D u_DiffuseMap;\r\n\r\nvarying vec2 var_Tex1;\r\nvaryi"
"ing vec4 var_Color;\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = text" "ng vec4 var_Color;\r\n\r\n\r\nvoid main()\r\n{\r\n\tvec4 color = textu"
"ure2D(u_Texture0Map, var_Tex1);\r\n\r\n\tgl_FragColor = color * var_Color;" "re2D(u_DiffuseMap, var_Tex1);\r\n\r\n\tgl_FragColor = color * var_Color;\r"
"\n}\n"; "\n}\r\n";
static const char *fallbackDeluxemappedShader_vp = static const char *fallbackLightallShader_vp =
"#version 120\r\n\r\n#ifndef M_PI\r\n#define M_PI 3.14159265358979323846f\r" "attribute vec4 attr_TexCoord0;\r\nattribute vec4 attr_TexCoord1;\r\n\r\natt"
"\n#endif\r\n\r\nattribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoo" "ribute vec4 attr_Position;\r\nattribute vec3 attr_Normal;\r\n\r\n#if define"
"rd0;\r\nattribute vec4 attr_TexCoord1;\r\nattribute vec4 attr_Tangent;\r\na" "d(USE_NORMALMAP)\r\nattribute vec3 attr_Tangent;\r\nattribute vec3 attr_Bit"
"ttribute vec4 attr_Bitangent;\r\nattribute vec4 attr_Normal;\r\n\r\nuniform" "angent;\r\n#endif\r\n\r\n#if defined(USE_VERTEX_ANIMATION)\r\nattribute vec"
" mat4 u_Texture0Matrix;\r\nuniform mat4 u_ModelViewProjectionMatrix;\r" "4 attr_Position2;\r\nattribute vec3 attr_Normal2;\r\n #if defined(USE_NORM"
"\n\r\nvarying vec2 var_Tex1;\r\nvarying vec2 var_Tex2;\r\nvarying vec3 " "ALMAP)\r\nattribute vec3 attr_Tangent2;\r\nattribute vec3 attr_Bitangent2;"
" var_Position;\r\n\r\nvarying vec3 var_Tangent;\r\nvarying vec3 var_Bi" "\r\n #endif\r\n#endif\r\n\r\nuniform mat4 u_DiffuseTexMatrix;\r\nuniform"
"tangent;\r\nvarying vec3 var_Normal;\r\n\r\nvoid main()\r\n{\r\n\tvec4 te" " vec3 u_ViewOrigin;\r\nuniform mat4 u_ModelViewProjectionMatrix;\r\n\r"
"x = vec4(1, 1, 1, 0);\r\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * " "\n#if defined(USE_MODELMATRIX)\r\nuniform mat4 u_ModelMatrix;\r\n#endif\r"
"attr_Position;\r\n\r\n\ttex.st = attr_TexCoord0.st;\r\n\r\n\tvar_Tex1 = (u_" "\n\r\n#if defined(USE_VERTEX_ANIMATION)\r\nuniform float u_VertexLerp;\r\n"
"Texture0Matrix * tex).st;\r\n\r\n\tif (u_Texture0Matrix[3][0] != 0)\r\n\t{" "#endif\r\n\r\nvarying vec2 var_DiffuseTex;\r\nvarying vec2 var_LightTex"
"\r\n\t\tvar_Tex1.s += sin(((attr_Position.x + attr_Position.z) * 1.0 / 128." ";\r\n\r\nvarying vec3 var_Position;\r\nvarying vec3 var_Normal;\r\n\r\n"
"0 * 0.125 + u_Texture0Matrix[3][1]) * 2.0 * M_PI) * u_Texture0Matrix[3][0];" "#if defined(USE_NORMALMAP)\r\nvarying vec3 var_Tangent;\r\nvarying vec3 "
"\r\n\t\tvar_Tex1.t += sin((attr_Position.y * 1.0 / 128.0 * 0.125 + u_Textur" " var_Bitangent;\r\n#endif\r\n\r\nvec2 DoTexMatrix(vec2 st, vec3 position, m"
"e0Matrix[3][1]) * 2.0 * M_PI) * u_Texture0Matrix[3][0];\r\n\t}\r\n\r\n\tvar" "at4 texMatrix)\r\n{\r\n\tvec4 st2 = vec4(st, 1, 0);\r\n\t\r\n\tst2.st = (te"
"_Tex2 = attr_TexCoord1.st;\r\n\r\n\tvar_Tangent = attr_Tangent.xyz;\r\n\t" "xMatrix * st2).st;\r\n\r\n\tvec2 texOffset;\r\n\tvec3 offsetPos = position."
"var_Bitangent = attr_Bitangent.xyz;\r\n\tvar_Normal = attr_Normal.xyz;\r" "xyz / 1024.0;\r\n\toffsetPos.x += offsetPos.z;\r\n\r\n\ttexOffset = sin((of"
"\n\t\r\n\tvar_Position = attr_Position.xyz;\r\n}\r\n"; "fsetPos.xy + vec2(texMatrix[3][1])) * 2.0 * M_PI);\r\n\t\r\n\treturn st2.st"
" + texOffset * texMatrix[3][0];\r\n}\r\n\r\nvoid main()\r\n{\r\n#if defined"
"(USE_VERTEX_ANIMATION)\r\n\tvec4 position = mix(attr_Position, attr_Positi"
"on2, u_VertexLerp);\r\n\tvec3 normal = normalize(mix(attr_Normal, att"
"r_Normal2, u_VertexLerp));\r\n #if defined(USE_NORMALMAP)\r\n\tvec3 tan"
"gent = normalize(mix(attr_Tangent, attr_Tangent2, u_VertexLerp));\r\n"
"\tvec3 bitangent = normalize(mix(attr_Bitangent, attr_Bitangent2, u_VertexL"
"erp));\r\n #endif\r\n#else\r\n\tvec4 position = attr_Position;\r\n\tvec3 "
"normal = attr_Normal;\r\n #if defined(USE_NORMALMAP)\r\n vec3 ta"
"ngent = attr_Tangent;\r\n vec3 bitangent = attr_Bitangent;\r\n #e"
"ndif\r\n#endif\r\n\r\n\tgl_Position = u_ModelViewProjectionMatrix * positio"
"n;\r\n\r\n#if defined(TCGEN_ENVIRONMENT)\r\n\t{\r\n\t\tvec2 tex;\r\n\t\tvec"
"3 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\t\r\n\t\tvar_DiffuseTex = DoTexMatrix(tex, position.xyz, u_Di"
"ffuseTexMatrix);\r\n\t}\r\n#else\r\n\tvar_DiffuseTex = DoTexMatrix(attr_Tex"
"Coord0.st, position.xyz, u_DiffuseTexMatrix);\r\n#endif\r\n\r\n\r\n\tvar_Li"
"ghtTex = attr_TexCoord1.st;\r\n\r\n#if defined(USE_MODELMATRIX)\r\n\tvar_Po"
"sition = (u_ModelMatrix * position).xyz;\r\n\tvar_Normal = (u_ModelMatr"
"ix * vec4(normal, 0.0)).xyz;\r\n\r\n #if defined(USE_NORMALMAP)\r\n\tvar_T"
"angent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz;\r\n\tvar_Bitangent = ("
"u_ModelMatrix * vec4(bitangent, 0.0)).xyz;\r\n #endif\r\n#else\r\n\tvar_Po"
"sition = position.xyz;\r\n\tvar_Normal = normal;\r\n\r\n #if defined(U"
"SE_NORMALMAP)\r\n\tvar_Tangent = tangent;\r\n\tvar_Bitangent = bitangent;"
"\r\n #endif\r\n#endif\r\n}\r\n";
static const char *fallbackDeluxemappedShader_fp = static const char *fallbackLightallShader_fp =
"#version 120\r\n\r\nuniform sampler2D u_Texture0Map;\r\nuniform sampler2D u" "uniform sampler2D u_DiffuseMap;\r\n\r\n#if defined(USE_LIGHTMAP)\r\nuniform"
"_Texture1Map;\r\nuniform sampler2D u_Texture2Map;\r\nuniform sampler2D u_Te" " sampler2D u_LightMap;\r\n#endif\r\n\r\n#if defined(USE_NORMALMAP)\r\nunifo"
"xture3Map;\r\nuniform sampler2D u_Texture4Map;\r\n\r\nuniform vec3 u_V" "rm sampler2D u_NormalMap;\r\n#endif\r\n\r\n#if defined(USE_DELUXEMAP)\r\nun"
"iewOrigin;\r\n\r\nvarying vec2 var_Tex1;\r\nvarying vec2 var_Tex2" "iform sampler2D u_DeluxeMap;\r\n#endif\r\n\r\n#if defined(USE_SPECULARMAP)"
";\r\nvarying vec3 var_Position;\r\n\r\nvarying vec3 var_Tangent;" "\r\nuniform sampler2D u_SpecularMap;\r\n#endif\r\n\r\nuniform vec3 u_V"
"\r\nvarying vec3 var_Bitangent;\r\nvarying vec3 var_Normal;\r\n\r" "iewOrigin;\r\nuniform vec4 u_Color;\r\n\r\n#if !defined(USE_LIGHTMAP)"
"\nvoid\tmain()\r\n{\r\n\tvec3 SampleToView = normalize(u_ViewOrigin - var_P" "\r\nuniform vec3 u_DirectedLight;\r\nuniform vec3 u_AmbientLight;"
"osition);\r\n\r\n\tmat3 tangentToWorld;\r\n\ttangentToWorld = mat3(var_Tang" "\r\nuniform vec4 u_LightOrigin;\r\nuniform float u_LightScaleSqr;"
"ent.xyz, var_Bitangent.xyz, var_Normal.xyz);\r\n\r\n\tmat3 worldToTangent;" "\r\n#endif\r\n\r\nvarying vec2 var_DiffuseTex;\r\nvarying vec2 va"
"\r\n\tworldToTangent = mat3(tangentToWorld[0][0], tangentToWorld[1][0], tan" "r_LightTex;\r\n\r\nvarying vec3 var_Position;\r\n\r\n#if defined(USE_N"
"gentToWorld[2][0],\r\n\t\ttangentToWorld[0][1], tangentToWorld[1][1], tange" "ORMALMAP)\r\nvarying vec3 var_Tangent;\r\nvarying vec3 var_Bitang"
"ntToWorld[2][1], \r\n\t\ttangentToWorld[0][2], tangentToWorld[1][2], tangen" "ent;\r\n#endif\r\n\r\nvarying vec3 var_Normal;\r\n\r\n\r\nfloat RayInt"
"tToWorld[2][2]);\r\n\t\t\t\t\t\t\t\t\t\r\n\tfloat height = 0.02 * texture2D" "ersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap)\r\n{\r\n\tconst in"
"(u_Texture2Map, var_Tex1).a - (0.02 / 2.0);\r\n\t\r\n\tvec2 offsetDir = nor" "t linearSearchSteps = 5;\r\n\tconst int binarySearchSteps = 5;\r\n\r\n\tflo"
"malize(worldToTangent * SampleToView).st;\r\n\tvec2 finalTex = var_Tex1 + o" "at depthStep = 1.0 / float(linearSearchSteps);\r\n\r\n\t// current size of "
"ffsetDir * height;\r\n\t\r\n\tvec4 diffuse = texture2D(u_Texture0Map, fina" "search window\r\n\tfloat size = depthStep;\r\n\r\n\t// current depth positi"
"lTex);\r\n\tvec4 lightmap = texture2D(u_Texture1Map, var_Tex2);\r\n\tvec4 n" "on\r\n\tfloat depth = 0.0;\r\n\r\n\t// best match found (starts with last p"
"ormal = texture2D(u_Texture2Map, finalTex);\r\n\tvec4 deluxe = texture2" "osition 1.0)\r\n\tfloat bestDepth = 1.0;\r\n\r\n\t// search front to back f"
"D(u_Texture3Map, var_Tex2);\r\n\tvec4 specular = texture2D(u_Texture4Map, f" "or first point inside object\r\n\tfor(int i = 0; i < linearSearchSteps - 1;"
"inalTex);\r\n\r\n\tvec3 worldNormal = tangentToWorld * normalize(2.0 * nor" " ++i)\r\n\t{\r\n\t\tdepth += size;\r\n\t\t\r\n\t\tvec4 t = texture2D(normal"
"mal.xyz - vec3(1.0));\r\n\tvec3 worldLight = normalize(2.0 * deluxe.xyz -" "Map, dp + ds * depth);\r\n\r\n\t\tif(bestDepth > 0.996)\t\t// if no depth f"
" vec3(1.0));\r\n\tvec3 HalfAngle = normalize(worldLight + SampleToView);" "ound yet\r\n\t\t\tif(depth >= t.w)\r\n\t\t\t\tbestDepth = depth;\t// store "
"\r\n\t\r\n\tdiffuse.rgb *= lightmap.rgb * max(dot(worldNormal, worldLight)," "best depth\r\n\t}\r\n\r\n\tdepth = bestDepth;\r\n\t\r\n\t// recurse around "
" 0.0);\r\n\tspecular.rgb *= lightmap.rgb * pow(max(dot(worldNormal, HalfAng" "first point (depth) for closest match\r\n\tfor(int i = 0; i < binarySearchS"
"le), 0.0), 16.0);\r\n\t\t\r\n\tgl_FragColor = diffuse;\r\n\tgl_FragColor.rg" "teps; ++i)\r\n\t{\r\n\t\tsize *= 0.5;\r\n\r\n\t\tvec4 t = texture2D(normalM"
"b += specular.rgb;\r\n}\r\n"; "ap, dp + ds * depth);\r\n\t\t\r\n\t\tif(depth >= t.w)\r\n\t\t{\r\n\t\t\tbes"
"tDepth = depth;\r\n\t\t\tdepth -= 2.0 * size;\r\n\t\t}\r\n\r\n\t\tdepth += "
"size;\r\n\t}\r\n\r\n\treturn bestDepth;\r\n}\r\n\r\nvoid main()\r\n{\r\n#if"
" defined(USE_LIGHTMAP)\r\n\tvec4 light = texture2D(u_LightMap, var_LightTex"
");\r\n #if defined(USE_DELUXEMAP)\r\n\tvec4 deluxe = texture2D(u_DeluxeMap"
", var_LightTex);\r\n\tvec3 worldLight = normalize(2.0 * deluxe.xyz - vec3(1"
".0));\r\n #else\r\n\tvec3 worldLight = normalize(var_Normal);\r\n #endif"
"\r\n#else\r\n\tvec3 worldLight = u_LightOrigin.xyz - (var_Position * u_Ligh"
"tOrigin.w);\r\n #if defined(USE_INVSQRLIGHT)\r\n\tfloat intensity = 1.0f /"
" dot(worldLight, worldLight);\r\n #else\r\n\tfloat intensity = clamp((1.0 "
"- dot(worldLight, worldLight) * u_LightScaleSqr) * 1.07, 0.0, 1.0);\r\n #e"
"ndif\t\r\n\tworldLight = normalize(worldLight);\r\n\tvec3 directedLight = u"
"_DirectedLight * intensity;\r\n\tvec3 ambientLight = u_AmbientLight; \r\n"
"#endif\r\n\r\n\tvec3 SampleToView = normalize(u_ViewOrigin - var_Position);"
"\r\n\tvec2 texOffset = vec2(0.0);\r\n\r\n#if defined(USE_NORMALMAP)\r\n\tma"
"t3 tangentToWorld = mat3(var_Tangent.xyz, var_Bitangent.xyz, var_Normal.xyz"
");\r\n\r\n #if defined(USE_PARALLAXMAP)\r\n\tvec3 offsetDir = normalize(Sa"
"mpleToView * tangentToWorld);\r\n #if 0\r\n\tfloat dist = 0.02 * texture"
"2D(u_NormalMap, var_DiffuseTex).w - (0.02 / 2.0);\r\n #else\r\n\toffsetD"
"ir.xy *= 0.02 / offsetDir.z;\r\n\tfloat dist = RayIntersectDisplaceMap(var_"
"NormalTex, offsetDir.xy, u_NormalMap);\r\n #endif\t\r\n\ttexOffset = off"
"setDir.xy * dist;\r\n #endif\r\n \r\n\tvec3 normal = texture2D(u_NormalMa"
"p, var_DiffuseTex + texOffset).xyz;\r\n\tvec3 worldNormal = normalize(tange"
"ntToWorld * (2.0 * normal.xyz - vec3(1.0)));\r\n#else\r\n\tvec3 worldNormal"
" = normalize(var_Normal);\r\n#endif\r\n\r\n\tvec4 diffuse = texture2D(u_Dif"
"fuseMap, var_DiffuseTex + texOffset) * u_Color;\r\n\r\n#if defined(USE_LIGH"
"TMAP)\r\n\tdiffuse.rgb *= light.rgb;\r\n #if defined(USE_DELUXEMAP)\r\n "
" #if defined(USE_NORMALMAP)\r\n #if defined(r_normalAmbient)\r\n "
" diffuse.rgb *= mix(max(dot(worldNormal, worldLight), 0.0), normal.z, r_no"
"rmalAmbient);\r\n #else\r\n diffuse.rgb *= max(dot(worldNormal,"
" worldLight), 0.0);\r\n #endif\r\n #endif\r\n #else\r\n #if def"
"ined(USE_NORMALMAP)\r\n #if defined(r_normalAmbient)\r\n diffus"
"e.rgb *= mix(1.0, normal.z, r_normalAmbient);\r\n #endif\r\n #endif"
"\r\n #endif\r\n#else\r\n #if defined(USE_NORMALMAP) && defined(r_normalAm"
"bient)\r\n ambientLight *= normal.z;\r\n #endif\r\n\tdiffuse.rgb *="
" min(directedLight * max(dot(worldNormal, worldLight), 0.0) + ambientLight,"
" 1.0);\r\n#endif\r\n\r\n\tgl_FragColor = diffuse;\r\n\r\n#if defined(USE_SP"
"ECULARMAP)\r\n\tvec4 specular = texture2D(u_SpecularMap, var_DiffuseTex + t"
"exOffset);\r\n\tvec3 halfAngle = normalize(worldLight + SampleToView);\r\n"
"\r\n #if defined(USE_LIGHTMAP)\r\n\tspecular.rgb *= light.rgb;\r\n #else"
"\r\n\tspecular.rgb *= directedLight;\r\n #endif\r\n\r\n\tspecular.rgb *= p"
"ow(max(dot(worldNormal, halfAngle), 0.0), 255 * specular.a);\r\n\r\n\tgl_Fr"
"agColor.rgb += specular.rgb;\r\n#endif\r\n}\r\n";
static void GLSL_PrintInfoLog(GLhandleARB object, qboolean developerOnly) static void GLSL_PrintInfoLog(GLhandleARB object, qboolean developerOnly)
@ -510,14 +548,12 @@ static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, c
"#define CGEN_ONE_MINUS_VERTEX %i\n" "#define CGEN_ONE_MINUS_VERTEX %i\n"
"#define CGEN_EXACT_VERTEX %i\n" "#define CGEN_EXACT_VERTEX %i\n"
"#define CGEN_LIGHTING_DIFFUSE %i\n" "#define CGEN_LIGHTING_DIFFUSE %i\n"
"#define CGEN_DLIGHT %i\n"
"#endif\n", "#endif\n",
CGEN_IDENTITY, CGEN_IDENTITY,
CGEN_VERTEX, CGEN_VERTEX,
CGEN_ONE_MINUS_VERTEX, CGEN_ONE_MINUS_VERTEX,
CGEN_EXACT_VERTEX, CGEN_EXACT_VERTEX,
CGEN_LIGHTING_DIFFUSE, CGEN_LIGHTING_DIFFUSE));
CGEN_DLIGHT));
Q_strcat(bufferExtra, sizeof(bufferExtra), Q_strcat(bufferExtra, sizeof(bufferExtra),
va("#ifndef alphaGen_t\n" va("#ifndef alphaGen_t\n"
@ -571,14 +607,11 @@ static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, c
GL_ADD, GL_ADD,
GL_REPLACE)); GL_REPLACE));
fbufWidthScale = 1.0f / ((float)glConfig.vidWidth); fbufWidthScale = 1.0f / ((float)glConfig.vidWidth);
fbufHeightScale = 1.0f / ((float)glConfig.vidHeight); fbufHeightScale = 1.0f / ((float)glConfig.vidHeight);
Q_strcat(bufferExtra, sizeof(bufferExtra), Q_strcat(bufferExtra, sizeof(bufferExtra),
va("#ifndef r_FBufScale\n#define r_FBufScale vec2(%f, %f)\n#endif\n", fbufWidthScale, fbufHeightScale)); va("#ifndef r_FBufScale\n#define r_FBufScale vec2(%f, %f)\n#endif\n", fbufWidthScale, fbufHeightScale));
if (extra) if (extra)
{ {
Q_strcat(bufferExtra, sizeof(bufferExtra), extra); Q_strcat(bufferExtra, sizeof(bufferExtra), extra);
@ -653,7 +686,7 @@ static int GLSL_LoadGPUShader(GLhandleARB program, GLhandleARB *prevShader, cons
Com_sprintf(filename, sizeof(filename), "glsl/%s_fp.glsl", name); Com_sprintf(filename, sizeof(filename), "glsl/%s_fp.glsl", name);
} }
ri.Printf(PRINT_ALL, "...loading '%s'\n", filename); ri.Printf(PRINT_DEVELOPER, "...loading '%s'\n", filename);
size = ri.FS_ReadFile(filename, (void **)&buffer); size = ri.FS_ReadFile(filename, (void **)&buffer);
if(!buffer) if(!buffer)
{ {
@ -812,7 +845,7 @@ static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name, int a
{ {
if (fallback_vp) if (fallback_vp)
{ {
ri.Printf(PRINT_ALL, "compiling fallback...\n"); ri.Printf(PRINT_DEVELOPER, "compiling fallback...\n");
if (!GLSL_CompileGPUShader(program->program, &program->vertexShader, fallback_vp, strlen(fallback_vp), GL_VERTEX_SHADER_ARB, extra, addHeader)) if (!GLSL_CompileGPUShader(program->program, &program->vertexShader, fallback_vp, strlen(fallback_vp), GL_VERTEX_SHADER_ARB, extra, addHeader))
{ {
ri.Printf(PRINT_ALL, "GLSL_InitGPUShader: Unable to load \"%s\" as GL_VERTEX_SHADER_ARB\n", name); ri.Printf(PRINT_ALL, "GLSL_InitGPUShader: Unable to load \"%s\" as GL_VERTEX_SHADER_ARB\n", name);
@ -833,7 +866,7 @@ static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name, int a
{ {
if (fallback_fp) if (fallback_fp)
{ {
ri.Printf(PRINT_ALL, "compiling fallback...\n"); ri.Printf(PRINT_DEVELOPER, "compiling fallback...\n");
if (!GLSL_CompileGPUShader(program->program, &program->fragmentShader, fallback_fp, strlen(fallback_fp), GL_FRAGMENT_SHADER_ARB, extra, addHeader)) if (!GLSL_CompileGPUShader(program->program, &program->fragmentShader, fallback_fp, strlen(fallback_fp), GL_FRAGMENT_SHADER_ARB, extra, addHeader))
{ {
ri.Printf(PRINT_ALL, "GLSL_InitGPUShader: Unable to load \"%s\" as GL_FRAGMENT_SHADER_ARB\n", name); ri.Printf(PRINT_ALL, "GLSL_InitGPUShader: Unable to load \"%s\" as GL_FRAGMENT_SHADER_ARB\n", name);
@ -888,6 +921,12 @@ static int GLSL_InitGPUShader(shaderProgram_t * program, const char *name, int a
if(attribs & ATTR_NORMAL2) if(attribs & ATTR_NORMAL2)
qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2"); qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2");
if(attribs & ATTR_TANGENT2)
qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2");
if(attribs & ATTR_BITANGENT2)
qglBindAttribLocationARB(program->program, ATTR_INDEX_BITANGENT2, "attr_Bitangent2");
GLSL_LinkProgram(program->program); GLSL_LinkProgram(program->program);
program->numUniforms = numUniforms; program->numUniforms = numUniforms;
@ -1172,28 +1211,33 @@ void GLSL_InitGPUShaders(void)
startTime = ri.Milliseconds(); startTime = ri.Milliseconds();
for (i = 0; i < GLSLDEF_COUNT; i++) for (i = 0; i < GENERICDEF_COUNT; i++)
{ {
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'; extradefines[0] = '\0';
if (i & GLSLDEF_USE_DEFORM_VERTEXES) if (i & GENERICDEF_USE_DEFORM_VERTEXES)
Q_strcat(extradefines, 1024, "#define USE_DEFORM_VERTEXES\n"); Q_strcat(extradefines, 1024, "#define USE_DEFORM_VERTEXES\n");
if (i & GLSLDEF_USE_TCGEN) if (i & GENERICDEF_USE_TCGEN)
Q_strcat(extradefines, 1024, "#define USE_TCGEN\n"); Q_strcat(extradefines, 1024, "#define USE_TCGEN\n");
if (i & GLSLDEF_USE_VERTEX_ANIMATION) if (i & GENERICDEF_USE_VERTEX_ANIMATION)
{ {
Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n"); Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n");
attribs |= ATTR_POSITION2 | ATTR_NORMAL2; attribs |= ATTR_POSITION2 | ATTR_NORMAL2;
} }
if (i & GLSLDEF_USE_FOG) if (i & GENERICDEF_USE_FOG)
{ {
Q_strcat(extradefines, 1024, "#define USE_FOG\n"); Q_strcat(extradefines, 1024, "#define USE_FOG\n");
} }
if (i & GENERICDEF_USE_RGBAGEN)
{
Q_strcat(extradefines, 1024, "#define USE_RGBAGEN\n");
}
if (!GLSL_InitGPUShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines, qtrue, fallbackGenericShader_vp, fallbackGenericShader_fp, GENERIC_UNIFORM_COUNT)) if (!GLSL_InitGPUShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines, qtrue, fallbackGenericShader_vp, fallbackGenericShader_fp, GENERIC_UNIFORM_COUNT))
{ {
ri.Error(ERR_FATAL, "Could not load generic shader!\n"); ri.Error(ERR_FATAL, "Could not load generic shader!\n");
@ -1207,14 +1251,14 @@ void GLSL_InitGPUShaders(void)
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_COLORGEN, "u_ColorGen", GLSL_INT); GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_COLORGEN, "u_ColorGen", GLSL_INT);
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_ALPHAGEN, "u_AlphaGen", GLSL_INT); GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_ALPHAGEN, "u_AlphaGen", GLSL_INT);
if (i & GLSLDEF_USE_TCGEN) if (i & GENERICDEF_USE_TCGEN)
{ {
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TCGEN0, "u_TCGen0", GLSL_INT); 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_TCGEN0VECTOR0, "u_TCGen0Vector0", GLSL_VEC4);
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TCGEN0VECTOR1, "u_TCGen0Vector1", GLSL_VEC4); GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TCGEN0VECTOR1, "u_TCGen0Vector1", GLSL_VEC4);
} }
if (i & GLSLDEF_USE_FOG) if (i & GENERICDEF_USE_FOG)
{ {
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_FOGADJUSTCOLORS, "u_FogAdjustColors", GLSL_INT); 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_FOGDISTANCE, "u_FogDistance", GLSL_VEC4);
@ -1222,7 +1266,7 @@ void GLSL_InitGPUShaders(void)
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_FOGEYET, "u_FogEyeT", GLSL_FLOAT); GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_FOGEYET, "u_FogEyeT", GLSL_FLOAT);
} }
if (i & GLSLDEF_USE_DEFORM_VERTEXES) if (i & GENERICDEF_USE_DEFORM_VERTEXES)
{ {
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_DEFORMGEN, "u_DeformGen", GLSL_INT); 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_DEFORMWAVE, "u_DeformWave", GLSL_VEC4);
@ -1234,17 +1278,17 @@ void GLSL_InitGPUShaders(void)
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_COLOR, "u_Color", GLSL_VEC4); 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_AMBIENTLIGHT, "u_AmbientLight", GLSL_VEC3);
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_DIRECTEDLIGHT, "u_DirectedLight", 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_LIGHTORIGIN, "u_LightOrigin", GLSL_VEC4);
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_VIEWORIGIN, "u_ViewOrigin", 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_DIFFUSETEXMATRIX, "u_DiffuseTexMatrix", GLSL_MAT16);
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE1ENV, "u_Texture1Env", GLSL_INT); GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE1ENV, "u_Texture1Env", GLSL_INT);
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE0MAP, "u_Texture0Map", GLSL_INT); GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_DIFFUSEMAP, "u_DiffuseMap", GLSL_INT);
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE1MAP, "u_Texture1Map", GLSL_INT); GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_LIGHTMAP, "u_LightMap", GLSL_INT);
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_PORTALRANGE, "u_PortalRange", GLSL_FLOAT); GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_PORTALRANGE, "u_PortalRange", GLSL_FLOAT);
if (i & GLSLDEF_USE_VERTEX_ANIMATION) if (i & GENERICDEF_USE_VERTEX_ANIMATION)
{ {
GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_VERTEXLERP, "u_VertexLerp", GLSL_FLOAT); GLSL_AddUniform(&tr.genericShader[i], GENERIC_UNIFORM_VERTEXLERP, "u_VertexLerp", GLSL_FLOAT);
} }
@ -1252,33 +1296,12 @@ void GLSL_InitGPUShaders(void)
GLSL_FinishGPUShader(&tr.genericShader[i]); GLSL_FinishGPUShader(&tr.genericShader[i]);
qglUseProgramObjectARB(tr.genericShader[i].program); qglUseProgramObjectARB(tr.genericShader[i].program);
GLSL_SetUniformInt(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE0MAP, 0); GLSL_SetUniformInt(&tr.genericShader[i], GENERIC_UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
GLSL_SetUniformInt(&tr.genericShader[i], GENERIC_UNIFORM_TEXTURE1MAP, 1); GLSL_SetUniformInt(&tr.genericShader[i], GENERIC_UNIFORM_LIGHTMAP, TB_LIGHTMAP);
qglUseProgramObjectARB(0); qglUseProgramObjectARB(0);
} }
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; attribs = ATTR_POSITION | ATTR_TEXCOORD;
if (!GLSL_InitGPUShader(&tr.textureColorShader, "texturecolor", attribs, qtrue, NULL, qfalse, fallbackTextureColorShader_vp, fallbackTextureColorShader_fp, TEXTURECOLOR_UNIFORM_COUNT)) if (!GLSL_InitGPUShader(&tr.textureColorShader, "texturecolor", attribs, qtrue, NULL, qfalse, fallbackTextureColorShader_vp, fallbackTextureColorShader_fp, TEXTURECOLOR_UNIFORM_COUNT))
@ -1288,12 +1311,12 @@ void GLSL_InitGPUShaders(void)
GLSL_AddUniform(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16); GLSL_AddUniform(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16);
GLSL_AddUniform(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_COLOR, "u_Color", GLSL_VEC4); GLSL_AddUniform(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_COLOR, "u_Color", GLSL_VEC4);
GLSL_AddUniform(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_TEXTURE0MAP, "u_Texture0Map", GLSL_INT); GLSL_AddUniform(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_DIFFUSEMAP, "u_DiffuseMap", GLSL_INT);
GLSL_FinishGPUShader(&tr.textureColorShader); GLSL_FinishGPUShader(&tr.textureColorShader);
qglUseProgramObjectARB(tr.textureColorShader.program); qglUseProgramObjectARB(tr.textureColorShader.program);
GLSL_SetUniformInt(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_TEXTURE0MAP, 0); GLSL_SetUniformInt(&tr.textureColorShader, TEXTURECOLOR_UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
qglUseProgramObjectARB(0); qglUseProgramObjectARB(0);
@ -1321,51 +1344,116 @@ void GLSL_InitGPUShaders(void)
attribs = ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TEXCOORD; 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)) if (!GLSL_InitGPUShader(&tr.dlightallShader, "dlight", attribs, qtrue, NULL, qtrue, fallbackDlightallShader_vp, fallbackDlightallShader_fp, DLIGHT_UNIFORM_COUNT))
{ {
ri.Error(ERR_FATAL, "Could not load dlight shader!\n"); ri.Error(ERR_FATAL, "Could not load dlight shader!\n");
} }
GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_DLIGHTINFO, "u_DlightInfo", GLSL_VEC4); GLSL_AddUniform(&tr.dlightallShader, DLIGHT_UNIFORM_DLIGHTINFO, "u_DlightInfo", GLSL_VEC4);
GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_DEFORMGEN, "u_DeformGen", GLSL_INT); GLSL_AddUniform(&tr.dlightallShader, DLIGHT_UNIFORM_DEFORMGEN, "u_DeformGen", GLSL_INT);
GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_DEFORMWAVE, "u_DeformWave", GLSL_VEC4); GLSL_AddUniform(&tr.dlightallShader, DLIGHT_UNIFORM_DEFORMWAVE, "u_DeformWave", GLSL_VEC4);
GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_DEFORMBULGE, "u_DeformBulge", GLSL_VEC3); GLSL_AddUniform(&tr.dlightallShader, DLIGHT_UNIFORM_DEFORMBULGE, "u_DeformBulge", GLSL_VEC3);
GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_DEFORMSPREAD, "u_DeformSpread", GLSL_FLOAT); GLSL_AddUniform(&tr.dlightallShader, DLIGHT_UNIFORM_DEFORMSPREAD, "u_DeformSpread", GLSL_FLOAT);
GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_TIME, "u_Time", GLSL_FLOAT); GLSL_AddUniform(&tr.dlightallShader, DLIGHT_UNIFORM_TIME, "u_Time", GLSL_FLOAT);
GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_COLOR, "u_Color", GLSL_VEC4); GLSL_AddUniform(&tr.dlightallShader, DLIGHT_UNIFORM_COLOR, "u_Color", GLSL_VEC4);
GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16); GLSL_AddUniform(&tr.dlightallShader, DLIGHT_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16);
GLSL_AddUniform(&tr.dlightShader, DLIGHT_UNIFORM_VERTEXLERP, "u_VertexLerp", GLSL_FLOAT); GLSL_AddUniform(&tr.dlightallShader, DLIGHT_UNIFORM_VERTEXLERP, "u_VertexLerp", GLSL_FLOAT);
GLSL_FinishGPUShader(&tr.dlightShader); GLSL_FinishGPUShader(&tr.dlightallShader);
qglUseProgramObjectARB(tr.dlightallShader.program);
attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_NORMAL | ATTR_COLOR | ATTR_TANGENT | ATTR_BITANGENT; GLSL_SetUniformInt(&tr.dlightallShader, DLIGHT_UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
if (!GLSL_InitGPUShader(&tr.deluxemappedShader, "deluxemapped", attribs, qtrue, extradefines, qfalse, fallbackDeluxemappedShader_vp, fallbackDeluxemappedShader_fp, GENERIC_UNIFORM_COUNT))
{
ri.Error(ERR_FATAL, "Could not load generic shader!\n");
}
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16);
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_MODELMATRIX, "u_ModelMatrix", GLSL_MAT16);
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE0MATRIX, "u_Texture0Matrix", GLSL_MAT16);
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_VIEWORIGIN, "u_ViewOrigin", GLSL_VEC3);
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE0MAP, "u_Texture0Map", GLSL_INT);
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE1MAP, "u_Texture1Map", GLSL_INT);
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE2MAP, "u_Texture2Map", GLSL_INT);
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE3MAP, "u_Texture3Map", GLSL_INT);
GLSL_AddUniform(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE4MAP, "u_Texture4Map", GLSL_INT);
GLSL_FinishGPUShader(&tr.deluxemappedShader);
qglUseProgramObjectARB(tr.deluxemappedShader.program);
GLSL_SetUniformInt(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE0MAP, 0);
GLSL_SetUniformInt(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE1MAP, 1);
GLSL_SetUniformInt(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE2MAP, 2);
GLSL_SetUniformInt(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE3MAP, 3);
GLSL_SetUniformInt(&tr.deluxemappedShader, GENERIC_UNIFORM_TEXTURE4MAP, 4);
qglUseProgramObjectARB(0); qglUseProgramObjectARB(0);
for (i = 0; i < LIGHTDEF_COUNT; i++)
{
// skip impossible combos
if (!(i & LIGHTDEF_USE_LIGHTMAP) && (i & LIGHTDEF_USE_DELUXEMAP))
continue;
if (!(i & LIGHTDEF_USE_NORMALMAP) && (i & LIGHTDEF_USE_PARALLAXMAP))
continue;
if ((i & LIGHTDEF_USE_LIGHTMAP) && (i & LIGHTDEF_ENTITY))
continue;
attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_NORMAL;
extradefines[0] = '\0';
if (r_normalAmbient->value > 0.003f)
Q_strcat(extradefines, 1024, va("#define r_normalAmbient %f\n", r_normalAmbient->value));
if (i & LIGHTDEF_USE_LIGHTMAP)
{
Q_strcat(extradefines, 1024, "#define USE_LIGHTMAP\n");
attribs |= ATTR_LIGHTCOORD;
}
if (i & LIGHTDEF_USE_NORMALMAP && r_normalMapping->integer)
{
Q_strcat(extradefines, 1024, "#define USE_NORMALMAP\n");
attribs |= ATTR_TANGENT | ATTR_BITANGENT;
}
if (i & LIGHTDEF_USE_SPECULARMAP && r_specularMapping->integer)
Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n");
if (i & LIGHTDEF_USE_DELUXEMAP && r_deluxeMapping->integer)
Q_strcat(extradefines, 1024, "#define USE_DELUXEMAP\n");
if (i & LIGHTDEF_USE_PARALLAXMAP && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer)
Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n");
if (i & LIGHTDEF_TCGEN_ENVIRONMENT)
Q_strcat(extradefines, 1024, "#define TCGEN_ENVIRONMENT\n");
if (i & LIGHTDEF_ENTITY)
{
Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n#define USE_MODELMATRIX\n");
attribs |= ATTR_POSITION2 | ATTR_NORMAL2;
if (i & LIGHTDEF_USE_NORMALMAP && r_normalMapping->integer)
{
attribs |= ATTR_TANGENT2 | ATTR_BITANGENT2;
}
}
if (!GLSL_InitGPUShader(&tr.lightallShader[i], "lightall", attribs, qtrue, extradefines, qtrue, fallbackLightallShader_vp, fallbackLightallShader_fp, GENERIC_UNIFORM_COUNT))
{
ri.Error(ERR_FATAL, "Could not load lightall shader!\n");
}
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, "u_ModelViewProjectionMatrix", GLSL_MAT16);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_MODELMATRIX, "u_ModelMatrix", GLSL_MAT16);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_DIFFUSETEXMATRIX, "u_DiffuseTexMatrix", GLSL_MAT16);
//GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_NORMALTEXMATRIX, "u_NormalTexMatrix", GLSL_MAT16);
//GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_SPECULARTEXMATRIX, "u_SpecularTexMatrix", GLSL_MAT16);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_VIEWORIGIN, "u_ViewOrigin", GLSL_VEC3);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_DIFFUSEMAP, "u_DiffuseMap", GLSL_INT);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_LIGHTMAP, "u_LightMap", GLSL_INT);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_NORMALMAP, "u_NormalMap", GLSL_INT);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_DELUXEMAP, "u_DeluxeMap", GLSL_INT);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_SPECULARMAP, "u_SpecularMap", GLSL_INT);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_AMBIENTLIGHT, "u_AmbientLight", GLSL_VEC3);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_DIRECTEDLIGHT, "u_DirectedLight", GLSL_VEC3);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_LIGHTORIGIN, "u_LightOrigin", GLSL_VEC4);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_LIGHTSCALESQR, "u_LightScaleSqr", GLSL_FLOAT);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_COLOR, "u_Color", GLSL_VEC4);
GLSL_AddUniform(&tr.lightallShader[i], GENERIC_UNIFORM_VERTEXLERP, "u_VertexLerp", GLSL_FLOAT);
GLSL_FinishGPUShader(&tr.lightallShader[i]);
qglUseProgramObjectARB(tr.lightallShader[i].program);
GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_LIGHTMAP, TB_LIGHTMAP);
GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_NORMALMAP, TB_NORMALMAP);
GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_DELUXEMAP, TB_DELUXEMAP);
GLSL_SetUniformInt(&tr.lightallShader[i], GENERIC_UNIFORM_SPECULARMAP, TB_SPECULARMAP);
qglUseProgramObjectARB(0);
}
endTime = ri.Milliseconds(); endTime = ri.Milliseconds();
@ -1383,22 +1471,27 @@ void GLSL_ShutdownGPUShaders(void)
qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION); qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION);
qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION2); qglDisableVertexAttribArrayARB(ATTR_INDEX_POSITION2);
qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL); qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL);
qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2);
qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT); qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT);
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT); qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT);
qglDisableVertexAttribArrayARB(ATTR_INDEX_NORMAL2);
qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2);
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2);
qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR); qglDisableVertexAttribArrayARB(ATTR_INDEX_COLOR);
GLSL_BindNullProgram(); GLSL_BindNullProgram();
for ( i = 0; i < GLSLDEF_COUNT; i++) for ( i = 0; i < GENERICDEF_COUNT; i++)
{ {
GLSL_DeleteGPUShader(&tr.genericShader[i]); GLSL_DeleteGPUShader(&tr.genericShader[i]);
} }
GLSL_DeleteGPUShader(&tr.textureColorShader); GLSL_DeleteGPUShader(&tr.textureColorShader);
GLSL_DeleteGPUShader(&tr.lightmappedShader);
GLSL_DeleteGPUShader(&tr.fogShader); GLSL_DeleteGPUShader(&tr.fogShader);
GLSL_DeleteGPUShader(&tr.dlightShader); GLSL_DeleteGPUShader(&tr.dlightallShader);
GLSL_DeleteGPUShader(&tr.deluxemappedShader);
for ( i = 0; i < LIGHTDEF_COUNT; i++)
{
GLSL_DeleteGPUShader(&tr.lightallShader[i]);
}
glState.currentProgram = 0; glState.currentProgram = 0;
qglUseProgramObjectARB(0); qglUseProgramObjectARB(0);
@ -1581,6 +1674,34 @@ void GLSL_VertexAttribsState(uint32_t stateBits)
} }
} }
if(diff & ATTR_TANGENT2)
{
if(stateBits & ATTR_TANGENT2)
{
GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_TANGENT2 )\n");
qglEnableVertexAttribArrayARB(ATTR_INDEX_TANGENT2);
}
else
{
GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_TANGENT2 )\n");
qglDisableVertexAttribArrayARB(ATTR_INDEX_TANGENT2);
}
}
if(diff & ATTR_BITANGENT2)
{
if(stateBits & ATTR_BITANGENT2)
{
GLimp_LogComment("qglEnableVertexAttribArrayARB( ATTR_INDEX_BITANGENT2 )\n");
qglEnableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2);
}
else
{
GLimp_LogComment("qglDisableVertexAttribArrayARB( ATTR_INDEX_BITANGENT2 )\n");
qglDisableVertexAttribArrayARB(ATTR_INDEX_BITANGENT2);
}
}
glState.vertexAttribsState = stateBits; glState.vertexAttribsState = stateBits;
} }
@ -1667,41 +1788,71 @@ void GLSL_VertexAttribPointers(uint32_t attribBits)
glState.vertexAttribPointersSet |= ATTR_NORMAL2; glState.vertexAttribPointersSet |= ATTR_NORMAL2;
} }
if((attribBits & ATTR_TANGENT2) && !(glState.vertexAttribPointersSet & ATTR_TANGENT2))
{
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_TANGENT2 )\n");
qglVertexAttribPointerARB(ATTR_INDEX_TANGENT2, 3, GL_FLOAT, 0, glState.currentVBO->stride_tangent, BUFFER_OFFSET(glState.currentVBO->ofs_tangent + glState.vertexAttribsOldFrame * glState.currentVBO->size_normal)); // FIXME
glState.vertexAttribPointersSet |= ATTR_TANGENT2;
}
if((attribBits & ATTR_BITANGENT2) && !(glState.vertexAttribPointersSet & ATTR_BITANGENT2))
{
GLimp_LogComment("qglVertexAttribPointerARB( ATTR_INDEX_BITANGENT2 )\n");
qglVertexAttribPointerARB(ATTR_INDEX_BITANGENT2, 3, GL_FLOAT, 0, glState.currentVBO->stride_bitangent, BUFFER_OFFSET(glState.currentVBO->ofs_bitangent + glState.vertexAttribsOldFrame * glState.currentVBO->size_normal)); // FIXME
glState.vertexAttribPointersSet |= ATTR_BITANGENT2;
}
} }
shaderProgram_t *GLSL_GetGenericShaderProgram() shaderProgram_t *GLSL_GetGenericShaderProgram(int stage)
{ {
shaderStage_t *pStage = tess.xstages[stage];
int shaderAttribs = 0; int shaderAttribs = 0;
if (tess.fogNum) if ( tess.fogNum && pStage->adjustColorsForFog)
{ {
int stage; shaderAttribs |= GENERICDEF_USE_FOG;
}
for ( stage = 0; stage < MAX_SHADER_STAGES; stage++ ) switch (pStage->rgbGen)
{
shaderStage_t *pStage = tess.xstages[stage];
if ( !pStage )
{ {
case CGEN_EXACT_VERTEX:
case CGEN_LIGHTING_DIFFUSE:
case CGEN_VERTEX:
case CGEN_ONE_MINUS_VERTEX:
shaderAttribs |= GENERICDEF_USE_RGBAGEN;
break;
default:
break; break;
} }
if ( pStage->adjustColorsForFog) switch (pStage->alphaGen)
{ {
shaderAttribs |= GLSLDEF_USE_FOG; case AGEN_LIGHTING_SPECULAR:
case AGEN_VERTEX:
case AGEN_ONE_MINUS_VERTEX:
case AGEN_PORTAL:
case AGEN_FRESNEL:
shaderAttribs |= GENERICDEF_USE_RGBAGEN;
break;
default:
break; break;
} }
}
}
// swapping these two out causes the worse case frame time to increase due to too many context switches if (pStage->bundle[0].tcGen != TCGEN_TEXTURE)
// think about doing actual checks if the sort is changed
shaderAttribs |= GLSLDEF_USE_DEFORM_VERTEXES;
shaderAttribs |= GLSLDEF_USE_TCGEN;
if (backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity)
{ {
shaderAttribs |= GLSLDEF_USE_VERTEX_ANIMATION; shaderAttribs |= GENERICDEF_USE_TCGEN;
}
if (!ShaderRequiresCPUDeforms(tess.shader))
{
shaderAttribs |= GENERICDEF_USE_DEFORM_VERTEXES;
}
if (glState.vertexAttribsInterpolation > 0.0f && backEnd.currentEntity && backEnd.currentEntity != &tr.worldEntity)
{
shaderAttribs |= GENERICDEF_USE_VERTEX_ANIMATION;
} }
return &tr.genericShader[shaderAttribs]; return &tr.genericShader[shaderAttribs];

View file

@ -101,6 +101,12 @@ cvar_t *r_ext_framebuffer_object;
cvar_t *r_mergeMultidraws; cvar_t *r_mergeMultidraws;
cvar_t *r_mergeLeafSurfaces; cvar_t *r_mergeLeafSurfaces;
cvar_t *r_normalMapping;
cvar_t *r_specularMapping;
cvar_t *r_deluxeMapping;
cvar_t *r_parallaxMapping;
cvar_t *r_normalAmbient;
cvar_t *r_ignoreGLErrors; cvar_t *r_ignoreGLErrors;
cvar_t *r_logFile; cvar_t *r_logFile;
@ -836,7 +842,28 @@ void GfxInfo_f( void )
ri.Printf( PRINT_ALL, "\nGL_VENDOR: %s\n", glConfig.vendor_string ); ri.Printf( PRINT_ALL, "\nGL_VENDOR: %s\n", glConfig.vendor_string );
ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glConfig.renderer_string ); ri.Printf( PRINT_ALL, "GL_RENDERER: %s\n", glConfig.renderer_string );
ri.Printf( PRINT_ALL, "GL_VERSION: %s\n", glConfig.version_string ); ri.Printf( PRINT_ALL, "GL_VERSION: %s\n", glConfig.version_string );
// this was really bugging me
if (strlen(glConfig.extensions_string) > 1008)
{
char buffer[1024];
char *p;
int size = strlen(glConfig.extensions_string);
ri.Printf( PRINT_ALL, "GL_EXTENSIONS: ");
p = glConfig.extensions_string;
while(size > 0)
{
Q_strncpyz(buffer, p, 1024);
ri.Printf( PRINT_ALL, "%s", buffer );
p += 1023;
size -= 1023;
}
ri.Printf( PRINT_ALL, "\n" );
}
else
{
ri.Printf( PRINT_ALL, "GL_EXTENSIONS: %s\n", glConfig.extensions_string ); ri.Printf( PRINT_ALL, "GL_EXTENSIONS: %s\n", glConfig.extensions_string );
}
ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize ); ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize );
ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_UNITS_ARB: %d\n", glConfig.numTextureUnits ); ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_UNITS_ARB: %d\n", glConfig.numTextureUnits );
ri.Printf( PRINT_ALL, "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits ); ri.Printf( PRINT_ALL, "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
@ -964,6 +991,12 @@ void R_Register( void )
r_greyscale = ri.Cvar_Get("r_greyscale", "0", CVAR_ARCHIVE | CVAR_LATCH); r_greyscale = ri.Cvar_Get("r_greyscale", "0", CVAR_ARCHIVE | CVAR_LATCH);
ri.Cvar_CheckRange(r_greyscale, 0, 1, qfalse); ri.Cvar_CheckRange(r_greyscale, 0, 1, qfalse);
r_normalMapping = ri.Cvar_Get( "r_normalMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_specularMapping = ri.Cvar_Get( "r_specularMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_normalAmbient = ri.Cvar_Get( "r_normalAmbient", "0", CVAR_ARCHIVE | CVAR_LATCH );
// //
// temporary latched variables that can only change over a restart // temporary latched variables that can only change over a restart
// //

View file

@ -371,10 +371,19 @@ void R_SetupEntityLighting( const trRefdef_t *refdef, trRefEntity_t *ent ) {
((byte *)&ent->ambientLightInt)[3] = 0xff; ((byte *)&ent->ambientLightInt)[3] = 0xff;
// transform the direction to local space // transform the direction to local space
// no need to do this if using lightentity glsl shader
VectorNormalize( lightDir ); VectorNormalize( lightDir );
if (glRefConfig.vertexBufferObject && r_arb_vertex_buffer_object->integer &&
glRefConfig.glsl && r_arb_shader_objects->integer)
{
VectorCopy(lightDir, ent->lightDir);
}
else
{
ent->lightDir[0] = DotProduct( lightDir, ent->e.axis[0] ); ent->lightDir[0] = DotProduct( lightDir, ent->e.axis[0] );
ent->lightDir[1] = DotProduct( lightDir, ent->e.axis[1] ); ent->lightDir[1] = DotProduct( lightDir, ent->e.axis[1] );
ent->lightDir[2] = DotProduct( lightDir, ent->e.axis[2] ); ent->lightDir[2] = DotProduct( lightDir, ent->e.axis[2] );
}
} }
/* /*

View file

@ -99,6 +99,7 @@ typedef struct {
vec3_t axis[3]; // orientation in world vec3_t axis[3]; // orientation in world
vec3_t viewOrigin; // viewParms->or.origin in local coordinates vec3_t viewOrigin; // viewParms->or.origin in local coordinates
float modelMatrix[16]; float modelMatrix[16];
float transformMatrix[16];
} orientationr_t; } orientationr_t;
typedef struct image_s { typedef struct image_s {
@ -277,8 +278,7 @@ typedef enum {
CGEN_WAVEFORM, // programmatically generated CGEN_WAVEFORM, // programmatically generated
CGEN_LIGHTING_DIFFUSE, CGEN_LIGHTING_DIFFUSE,
CGEN_FOG, // standard fog CGEN_FOG, // standard fog
CGEN_CONST, // fixed color CGEN_CONST // fixed color
CGEN_DLIGHT
} colorGen_t; } colorGen_t;
typedef enum typedef enum
@ -404,6 +404,7 @@ typedef enum
ST_COLORMAP = 0, // vanilla Q3A style shader treatening ST_COLORMAP = 0, // vanilla Q3A style shader treatening
ST_DIFFUSEMAP = 0, // treat color and diffusemap the same ST_DIFFUSEMAP = 0, // treat color and diffusemap the same
ST_NORMALMAP, ST_NORMALMAP,
ST_NORMALPARALLAXMAP,
ST_SPECULARMAP, ST_SPECULARMAP,
ST_GLSL ST_GLSL
} stageType_t; } stageType_t;
@ -438,7 +439,8 @@ typedef struct {
qboolean isDetail; qboolean isDetail;
struct shaderProgram_s *glslShader; struct shaderProgram_s *glslShaderGroup;
int glslShaderIndex;
} shaderStage_t; } shaderStage_t;
struct shaderCommands_s; struct shaderCommands_s;
@ -706,12 +708,26 @@ enum
enum enum
{ {
GLSLDEF_USE_DEFORM_VERTEXES = 0x0001, GENERICDEF_USE_DEFORM_VERTEXES = 0x0001,
GLSLDEF_USE_TCGEN = 0x0002, GENERICDEF_USE_TCGEN = 0x0002,
GLSLDEF_USE_VERTEX_ANIMATION = 0x0004, GENERICDEF_USE_VERTEX_ANIMATION = 0x0004,
GLSLDEF_USE_FOG = 0x0008, GENERICDEF_USE_FOG = 0x0008,
GLSLDEF_ALL = 0x000F, GENERICDEF_USE_RGBAGEN = 0x0010,
GLSLDEF_COUNT = 0x0010, GENERICDEF_ALL = 0x001F,
GENERICDEF_COUNT = 0x0020,
};
enum
{
LIGHTDEF_USE_LIGHTMAP = 0x0001,
LIGHTDEF_USE_NORMALMAP = 0x0002,
LIGHTDEF_USE_SPECULARMAP = 0x0004,
LIGHTDEF_USE_DELUXEMAP = 0x0008,
LIGHTDEF_USE_PARALLAXMAP = 0x0010,
LIGHTDEF_TCGEN_ENVIRONMENT = 0x0020,
LIGHTDEF_ENTITY = 0x0040,
LIGHTDEF_ALL = 0x007F,
LIGHTDEF_COUNT = 0x0080
}; };
enum enum
@ -744,21 +760,10 @@ typedef struct shaderProgram_s
} shaderProgram_t; } shaderProgram_t;
enum
{
LIGHTMAPPED_UNIFORM_MODELVIEWPROJECTIONMATRIX = 0,
LIGHTMAPPED_UNIFORM_TEXTURE0MATRIX,
LIGHTMAPPED_UNIFORM_TEXTURE1ENV,
LIGHTMAPPED_UNIFORM_TEXTURE0MAP,
LIGHTMAPPED_UNIFORM_TEXTURE1MAP,
LIGHTMAPPED_UNIFORM_COUNT
};
enum enum
{ {
TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX = 0, TEXTURECOLOR_UNIFORM_MODELVIEWPROJECTIONMATRIX = 0,
TEXTURECOLOR_UNIFORM_TEXTURE0MAP, TEXTURECOLOR_UNIFORM_DIFFUSEMAP,
TEXTURECOLOR_UNIFORM_COLOR, TEXTURECOLOR_UNIFORM_COLOR,
TEXTURECOLOR_UNIFORM_COUNT TEXTURECOLOR_UNIFORM_COUNT
}; };
@ -783,7 +788,8 @@ enum
enum enum
{ {
DLIGHT_UNIFORM_DLIGHTINFO = 0, DLIGHT_UNIFORM_DIFFUSEMAP = 0,
DLIGHT_UNIFORM_DLIGHTINFO,
DLIGHT_UNIFORM_DEFORMGEN, DLIGHT_UNIFORM_DEFORMGEN,
DLIGHT_UNIFORM_DEFORMWAVE, DLIGHT_UNIFORM_DEFORMWAVE,
DLIGHT_UNIFORM_DEFORMBULGE, DLIGHT_UNIFORM_DEFORMBULGE,
@ -798,12 +804,14 @@ enum
enum enum
{ {
GENERIC_UNIFORM_TEXTURE0MAP = 0, GENERIC_UNIFORM_DIFFUSEMAP = 0,
GENERIC_UNIFORM_TEXTURE1MAP, GENERIC_UNIFORM_LIGHTMAP,
GENERIC_UNIFORM_TEXTURE2MAP, GENERIC_UNIFORM_NORMALMAP,
GENERIC_UNIFORM_TEXTURE3MAP, GENERIC_UNIFORM_DELUXEMAP,
GENERIC_UNIFORM_TEXTURE4MAP, GENERIC_UNIFORM_SPECULARMAP,
GENERIC_UNIFORM_TEXTURE0MATRIX, GENERIC_UNIFORM_DIFFUSETEXMATRIX,
GENERIC_UNIFORM_NORMALTEXMATRIX,
GENERIC_UNIFORM_SPECULARTEXMATRIX,
GENERIC_UNIFORM_TEXTURE1ENV, GENERIC_UNIFORM_TEXTURE1ENV,
GENERIC_UNIFORM_VIEWORIGIN, GENERIC_UNIFORM_VIEWORIGIN,
GENERIC_UNIFORM_TCGEN0, GENERIC_UNIFORM_TCGEN0,
@ -818,7 +826,8 @@ enum
GENERIC_UNIFORM_COLOR, GENERIC_UNIFORM_COLOR,
GENERIC_UNIFORM_AMBIENTLIGHT, GENERIC_UNIFORM_AMBIENTLIGHT,
GENERIC_UNIFORM_DIRECTEDLIGHT, GENERIC_UNIFORM_DIRECTEDLIGHT,
GENERIC_UNIFORM_LIGHTDIR, GENERIC_UNIFORM_LIGHTORIGIN,
GENERIC_UNIFORM_LIGHTSCALESQR,
GENERIC_UNIFORM_PORTALRANGE, GENERIC_UNIFORM_PORTALRANGE,
GENERIC_UNIFORM_FOGDISTANCE, GENERIC_UNIFORM_FOGDISTANCE,
GENERIC_UNIFORM_FOGDEPTH, GENERIC_UNIFORM_FOGDEPTH,
@ -1315,6 +1324,8 @@ typedef struct
{ {
vec3_t xyz; vec3_t xyz;
vec3_t normal; vec3_t normal;
vec3_t tangent;
vec3_t bitangent;
} mdvVertex_t; } mdvVertex_t;
typedef struct typedef struct
@ -1526,7 +1537,7 @@ typedef struct {
int c_glslShaderBinds; int c_glslShaderBinds;
int c_genericDraws; int c_genericDraws;
int c_lightmappedDraws; int c_lightallDraws;
int c_fogDraws; int c_fogDraws;
int c_dlightDraws; int c_dlightDraws;
@ -1636,12 +1647,11 @@ typedef struct {
// GPU shader programs // GPU shader programs
// //
shaderProgram_t genericShader[GLSLDEF_COUNT]; shaderProgram_t genericShader[GENERICDEF_COUNT];
shaderProgram_t lightmappedShader;
shaderProgram_t textureColorShader; shaderProgram_t textureColorShader;
shaderProgram_t fogShader; shaderProgram_t fogShader;
shaderProgram_t dlightShader; shaderProgram_t dlightallShader;
shaderProgram_t deluxemappedShader; shaderProgram_t lightallShader[LIGHTDEF_COUNT];
// ----------------------------------------- // -----------------------------------------
@ -1839,6 +1849,12 @@ extern cvar_t *r_anaglyphMode;
extern cvar_t *r_mergeMultidraws; extern cvar_t *r_mergeMultidraws;
extern cvar_t *r_mergeLeafSurfaces; extern cvar_t *r_mergeLeafSurfaces;
extern cvar_t *r_normalMapping;
extern cvar_t *r_specularMapping;
extern cvar_t *r_deluxeMapping;
extern cvar_t *r_parallaxMapping;
extern cvar_t *r_normalAmbient;
extern cvar_t *r_greyscale; extern cvar_t *r_greyscale;
extern cvar_t *r_ignoreGLErrors; extern cvar_t *r_ignoreGLErrors;
@ -1879,6 +1895,8 @@ void R_DecomposeSort( unsigned sort, int *entityNum, shader_t **shader,
void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, int fogIndex, int dlightMap ); void R_AddDrawSurf( surfaceType_t *surface, shader_t *shader, int fogIndex, int dlightMap );
void R_CalcTangentSpace(vec3_t tangent, vec3_t bitangent, vec3_t normal,
const vec3_t v0, const vec3_t v1, const vec3_t v2, const vec2_t t0, const vec2_t t1, const vec2_t t2);
qboolean R_CalcTangentVectors(srfVert_t * dv[3]); qboolean R_CalcTangentVectors(srfVert_t * dv[3]);
void R_CalcSurfaceTriangleNeighbors(int numTriangles, srfTriangle_t * triangles); void R_CalcSurfaceTriangleNeighbors(int numTriangles, srfTriangle_t * triangles);
void R_CalcSurfaceTrianglePlanes(int numTriangles, srfTriangle_t * triangles, srfVert_t * verts); void R_CalcSurfaceTrianglePlanes(int numTriangles, srfTriangle_t * triangles, srfVert_t * verts);
@ -2100,7 +2118,6 @@ void RB_StageIteratorGeneric( void );
void RB_StageIteratorGenericVBO( void ); void RB_StageIteratorGenericVBO( void );
void RB_StageIteratorSky( void ); void RB_StageIteratorSky( void );
void RB_StageIteratorVertexLitTexture( void ); void RB_StageIteratorVertexLitTexture( void );
void RB_StageIteratorLightmappedMultitextureVBOGLSL( void );
void RB_StageIteratorLightmappedMultitexture( void ); void RB_StageIteratorLightmappedMultitexture( void );
void RB_AddQuadStamp( vec3_t origin, vec3_t left, vec3_t up, byte *color ); void RB_AddQuadStamp( vec3_t origin, vec3_t left, vec3_t up, byte *color );
@ -2272,7 +2289,7 @@ void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t
void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_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); void GLSL_SetUniformMatrix16(shaderProgram_t *program, int uniformNum, const matrix_t matrix);
shaderProgram_t *GLSL_GetGenericShaderProgram(void); shaderProgram_t *GLSL_GetGenericShaderProgram(int stage);
/* /*
============================================================ ============================================================

View file

@ -916,6 +916,7 @@ void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms,
glMatrix[11] = 0; glMatrix[11] = 0;
glMatrix[15] = 1; glMatrix[15] = 1;
Matrix16Copy(glMatrix, or->transformMatrix);
myGlMultMatrix( glMatrix, viewParms->world.modelMatrix, or->modelMatrix ); myGlMultMatrix( glMatrix, viewParms->world.modelMatrix, or->modelMatrix );
// calculate the viewer origin in the model's space // calculate the viewer origin in the model's space

View file

@ -259,7 +259,7 @@ R_LoadMD3
*/ */
static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, const char *modName) static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize, const char *modName)
{ {
int i, j; int f, i, j, k;
md3Header_t *md3Model; md3Header_t *md3Model;
md3Frame_t *md3Frame; md3Frame_t *md3Frame;
@ -447,13 +447,16 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
md3xyz = (md3XyzNormal_t *) ((byte *) md3Surf + md3Surf->ofsXyzNormals); md3xyz = (md3XyzNormal_t *) ((byte *) md3Surf + md3Surf->ofsXyzNormals);
for(j = 0; j < md3Surf->numVerts * md3Surf->numFrames; j++, md3xyz++, v++) for(j = 0; j < md3Surf->numVerts * md3Surf->numFrames; j++, md3xyz++, v++)
{ {
#if 0
unsigned lat, lng; unsigned lat, lng;
unsigned short normal; unsigned short normal;
#endif
v->xyz[0] = LittleShort(md3xyz->xyz[0]) * MD3_XYZ_SCALE; v->xyz[0] = LittleShort(md3xyz->xyz[0]) * MD3_XYZ_SCALE;
v->xyz[1] = LittleShort(md3xyz->xyz[1]) * MD3_XYZ_SCALE; v->xyz[1] = LittleShort(md3xyz->xyz[1]) * MD3_XYZ_SCALE;
v->xyz[2] = LittleShort(md3xyz->xyz[2]) * MD3_XYZ_SCALE; v->xyz[2] = LittleShort(md3xyz->xyz[2]) * MD3_XYZ_SCALE;
#if 0
normal = LittleShort(md3xyz->normal); normal = LittleShort(md3xyz->normal);
lat = ( normal >> 8 ) & 0xff; lat = ( normal >> 8 ) & 0xff;
@ -468,6 +471,7 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
v->normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; v->normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng];
v->normal[1] = tr.sinTable[lat] * tr.sinTable[lng]; v->normal[1] = tr.sinTable[lat] * tr.sinTable[lng];
v->normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; v->normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK];
#endif
} }
// swap all the ST // swap all the ST
@ -480,6 +484,64 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
st->st[1] = LittleFloat(md3st->st[1]); st->st[1] = LittleFloat(md3st->st[1]);
} }
// calc tangent spaces
{
const float *v0, *v1, *v2;
const float *t0, *t1, *t2;
vec3_t tangent;
vec3_t bitangent;
vec3_t normal;
for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++)
{
VectorClear(v->tangent);
VectorClear(v->bitangent);
VectorClear(v->normal);
}
for(f = 0; f < mdvModel->numFrames; f++)
{
for(j = 0, tri = surf->triangles; j < surf->numTriangles; j++, tri++)
{
v0 = surf->verts[surf->numVerts * f + tri->indexes[0]].xyz;
v1 = surf->verts[surf->numVerts * f + tri->indexes[1]].xyz;
v2 = surf->verts[surf->numVerts * f + tri->indexes[2]].xyz;
t0 = surf->st[tri->indexes[0]].st;
t1 = surf->st[tri->indexes[1]].st;
t2 = surf->st[tri->indexes[2]].st;
#if 1
R_CalcTangentSpace(tangent, bitangent, normal, v0, v1, v2, t0, t1, t2);
#else
R_CalcNormalForTriangle(normal, v0, v1, v2);
R_CalcTangentsForTriangle(tangent, bitangent, v0, v1, v2, t0, t1, t2);
#endif
for(k = 0; k < 3; k++)
{
float *v;
v = surf->verts[surf->numVerts * f + tri->indexes[k]].tangent;
VectorAdd(v, tangent, v);
v = surf->verts[surf->numVerts * f + tri->indexes[k]].bitangent;
VectorAdd(v, bitangent, v);
v = surf->verts[surf->numVerts * f + tri->indexes[k]].normal;
VectorAdd(v, normal, v);
}
}
}
for(j = 0, v = surf->verts; j < (surf->numVerts * mdvModel->numFrames); j++, v++)
{
VectorNormalize(v->tangent);
VectorNormalize(v->bitangent);
VectorNormalize(v->normal);
}
}
// find the next surface // find the next surface
md3Surf = (md3Surface_t *) ((byte *) md3Surf + md3Surf->ofsEnd); md3Surf = (md3Surface_t *) ((byte *) md3Surf + md3Surf->ofsEnd);
surf++; surf++;
@ -499,12 +561,14 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
{ {
vec3_t *verts; vec3_t *verts;
vec3_t *normals; vec3_t *normals;
vec3_t *tangents;
vec3_t *bitangents;
vec2_t *texcoords; vec2_t *texcoords;
byte *data; byte *data;
int dataSize; int dataSize;
int ofs_xyz, ofs_normal, ofs_st; int ofs_xyz, ofs_normal, ofs_st, ofs_tangent, ofs_bitangent;
dataSize = 0; dataSize = 0;
@ -512,7 +576,13 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*verts); dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*verts);
ofs_normal = dataSize; ofs_normal = dataSize;
dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*verts); dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*normals);
ofs_tangent = dataSize;
dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*tangents);
ofs_bitangent = dataSize;
dataSize += surf->numVerts * mdvModel->numFrames * sizeof(*bitangents);
ofs_st = dataSize; ofs_st = dataSize;
dataSize += surf->numVerts * sizeof(*texcoords); dataSize += surf->numVerts * sizeof(*texcoords);
@ -521,6 +591,8 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
verts = (void *)(data + ofs_xyz); verts = (void *)(data + ofs_xyz);
normals = (void *)(data + ofs_normal); normals = (void *)(data + ofs_normal);
tangents = (void *)(data + ofs_tangent);
bitangents = (void *)(data + ofs_bitangent);
texcoords = (void *)(data + ofs_st); texcoords = (void *)(data + ofs_st);
v = surf->verts; v = surf->verts;
@ -528,6 +600,8 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
{ {
VectorCopy(v->xyz, verts[j]); VectorCopy(v->xyz, verts[j]);
VectorCopy(v->normal, normals[j]); VectorCopy(v->normal, normals[j]);
VectorCopy(v->tangent, tangents[j]);
VectorCopy(v->bitangent, bitangents[j]);
} }
st = surf->st; st = surf->st;
@ -545,10 +619,14 @@ static qboolean R_LoadMD3(model_t * mod, int lod, void *buffer, int bufferSize,
vboSurf->vbo->ofs_xyz = ofs_xyz; vboSurf->vbo->ofs_xyz = ofs_xyz;
vboSurf->vbo->ofs_normal = ofs_normal; vboSurf->vbo->ofs_normal = ofs_normal;
vboSurf->vbo->ofs_tangent = ofs_tangent;
vboSurf->vbo->ofs_bitangent = ofs_bitangent;
vboSurf->vbo->ofs_st = ofs_st; vboSurf->vbo->ofs_st = ofs_st;
vboSurf->vbo->stride_xyz = sizeof(*verts); vboSurf->vbo->stride_xyz = sizeof(*verts);
vboSurf->vbo->stride_normal = sizeof(*normals); vboSurf->vbo->stride_normal = sizeof(*normals);
vboSurf->vbo->stride_tangent = sizeof(*tangents);
vboSurf->vbo->stride_bitangent = sizeof(*bitangents);
vboSurf->vbo->stride_st = sizeof(*st); vboSurf->vbo->stride_st = sizeof(*st);
vboSurf->vbo->size_xyz = sizeof(*verts) * surf->numVerts; vboSurf->vbo->size_xyz = sizeof(*verts) * surf->numVerts;

View file

@ -551,8 +551,9 @@ static void ComputeTexMatrix( shaderStage_t *pStage, int bundleNum, float *outma
case TMOD_TURBULENT: case TMOD_TURBULENT:
RB_CalcTurbulentTexMatrix( &bundle->texMods[tm].wave, RB_CalcTurbulentTexMatrix( &bundle->texMods[tm].wave,
matrix ); matrix );
currentmatrix[12] = matrix[12]; outmatrix[12] = matrix[12];
currentmatrix[13] = matrix[13]; outmatrix[13] = matrix[13];
Matrix16Copy(outmatrix, currentmatrix);
break; break;
case TMOD_ENTITY_TRANSLATE: case TMOD_ENTITY_TRANSLATE:
@ -1124,7 +1125,7 @@ static void ProjectDlightTextureVBOGLSL( void ) {
radius = dl->radius; radius = dl->radius;
scale = 1.0f / radius; scale = 1.0f / radius;
sp = &tr.dlightShader; sp = &tr.dlightallShader;
backEnd.pc.c_dlightDraws++; backEnd.pc.c_dlightDraws++;
@ -1214,6 +1215,254 @@ static void ProjectDlightTextureVBOGLSL( void ) {
} }
static void ComputeHelperColor( shaderStage_t *pStage, vec4_t color);
static void ForwardDlightVBOGLSL( void ) {
int l;
vec3_t origin;
float scale;
float radius;
int deformGen;
vec4_t deformWave;
vec3_t deformBulge;
float deformSpread;
vec4_t fogDistanceVector, fogDepthVector = {0, 0, 0, 0};
float eyeT;
shaderCommands_t *input = &tess;
shaderStage_t *pStage = tess.xstages[0];
if ( !backEnd.refdef.num_dlights ) {
return;
}
// u_DeformGen
deformGen = DGEN_NONE;
if(!ShaderRequiresCPUDeforms(input->shader))
{
deformStage_t *ds;
// only support the first one
ds = &input->shader->deforms[0];
switch (ds->deformation)
{
case DEFORM_WAVE:
deformGen = ds->deformationWave.func;
{
waveForm_t *wf = &ds->deformationWave;
VectorSet4(deformWave, wf->base, wf->amplitude, wf->phase, wf->frequency);
}
deformSpread = ds->deformationSpread;
break;
case DEFORM_BULGE:
deformGen = DGEN_BULGE;
VectorSet(deformBulge, ds->bulgeWidth, ds->bulgeHeight, ds->bulgeSpeed);
break;
default:
break;
}
}
if ( input->fogNum ) {
fog_t *fog;
vec3_t local;
fog = tr.world->fogs + tess.fogNum;
VectorSubtract( backEnd.or.origin, backEnd.viewParms.or.origin, local );
fogDistanceVector[0] = -backEnd.or.modelMatrix[2];
fogDistanceVector[1] = -backEnd.or.modelMatrix[6];
fogDistanceVector[2] = -backEnd.or.modelMatrix[10];
fogDistanceVector[3] = DotProduct( local, backEnd.viewParms.or.axis[0] );
// scale the fog vectors based on the fog's thickness
VectorScale4(fogDistanceVector, fog->tcScale, fogDistanceVector);
// rotate the gradient vector for this orientation
if ( fog->hasSurface ) {
fogDepthVector[0] = fog->surface[0] * backEnd.or.axis[0][0] +
fog->surface[1] * backEnd.or.axis[0][1] + fog->surface[2] * backEnd.or.axis[0][2];
fogDepthVector[1] = fog->surface[0] * backEnd.or.axis[1][0] +
fog->surface[1] * backEnd.or.axis[1][1] + fog->surface[2] * backEnd.or.axis[1][2];
fogDepthVector[2] = fog->surface[0] * backEnd.or.axis[2][0] +
fog->surface[1] * backEnd.or.axis[2][1] + fog->surface[2] * backEnd.or.axis[2][2];
fogDepthVector[3] = -fog->surface[3] + DotProduct( backEnd.or.origin, fog->surface );
eyeT = DotProduct( backEnd.or.viewOrigin, fogDepthVector ) + fogDepthVector[3];
} else {
eyeT = 1; // non-surface fog always has eye inside
}
}
for ( l = 0 ; l < backEnd.refdef.num_dlights ; l++ ) {
dlight_t *dl;
shaderProgram_t *sp;
vec4_t vector;
qboolean setcolor;
if ( !( tess.dlightBits & ( 1 << l ) ) ) {
continue; // this surface definately doesn't have any of this light
}
dl = &backEnd.refdef.dlights[l];
VectorCopy( dl->transformed, origin );
radius = dl->radius;
scale = 1.0f / radius;
//if (pStage->glslShaderGroup == tr.lightallShader)
{
sp = &tr.lightallShader[pStage->glslShaderIndex & ~LIGHTDEF_USE_LIGHTMAP];
}
backEnd.pc.c_lightallDraws++;
GLSL_BindProgram(sp);
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_VIEWORIGIN, backEnd.or.viewOrigin);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_DEFORMGEN, deformGen);
switch(deformGen)
{
case DGEN_WAVE_SIN:
case DGEN_WAVE_SQUARE:
case DGEN_WAVE_TRIANGLE:
case DGEN_WAVE_SAWTOOTH:
case DGEN_WAVE_INVERSE_SAWTOOTH:
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_DEFORMWAVE, deformWave);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_DEFORMSPREAD, deformSpread);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime);
break;
case DGEN_BULGE:
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DEFORMBULGE, deformBulge);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_TIME, tess.shaderTime);
break;
default:
break;
}
if ( input->fogNum ) {
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDISTANCE, fogDistanceVector);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_FOGDEPTH, fogDepthVector);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_FOGEYET, eyeT);
}
switch (pStage->rgbGen)
{
case CGEN_EXACT_VERTEX:
case CGEN_LIGHTING_DIFFUSE:
break;
default:
setcolor = qtrue;
}
switch (pStage->alphaGen)
{
case AGEN_LIGHTING_SPECULAR:
case AGEN_VERTEX:
case AGEN_ONE_MINUS_VERTEX:
case AGEN_PORTAL:
case AGEN_FRESNEL:
break;
default:
setcolor = qtrue;
}
if (setcolor)
{
vec4_t color;
VectorSet4(color, 1.0f, 1.0f, 1.0f, 1.0f);
ComputeHelperColor (pStage, color);
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_COLOR, color);
}
if (pStage->alphaGen == AGEN_PORTAL)
{
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_PORTALRANGE, tess.shader->portalRange);
}
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_COLORGEN, pStage->rgbGen);
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_ALPHAGEN, pStage->alphaGen);
if ( input->fogNum )
{
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, pStage->adjustColorsForFog);
}
else
{
GLSL_SetUniformInt(sp, GENERIC_UNIFORM_FOGADJUSTCOLORS, 0);
}
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, dl->color);
VectorSet(vector, 0, 0, 0);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, vector);
VectorCopy(dl->origin, vector);
vector[3] = 1.0f;
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, vector);
GLSL_SetUniformFloat(sp, GENERIC_UNIFORM_LIGHTSCALESQR, scale * scale);
// include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light
// where they aren't rendered
GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHFUNC_EQUAL );
{
matrix_t matrix;
Matrix16Identity(matrix);
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, matrix);
if (pStage->bundle[TB_DIFFUSEMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_DIFFUSEMAP], TB_DIFFUSEMAP);
if (pStage->bundle[TB_NORMALMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_NORMALMAP], TB_NORMALMAP);
if (pStage->bundle[TB_SPECULARMAP].image[0])
R_BindAnimatedImageToTMU( &pStage->bundle[TB_SPECULARMAP], TB_SPECULARMAP);
ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix );
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_DIFFUSETEXMATRIX, matrix);
//ComputeTexMatrix( pStage, TB_NORMALMAP, matrix );
//GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_NORMALTEXMATRIX, matrix);
//ComputeTexMatrix( pStage, TB_SPECULARMAP, matrix );
//GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_SPECULARTEXMATRIX, matrix);
//
// draw
//
if (input->multiDrawPrimitives)
{
R_DrawMultiElementsVBO(input->multiDrawPrimitives, (const GLvoid **)input->multiDrawFirstIndex, input->multiDrawNumIndexes);
}
else
{
R_DrawElementsVBO(input->numIndexes, input->firstIndex);
}
}
backEnd.pc.c_totalIndexes += tess.numIndexes;
backEnd.pc.c_dlightIndexes += tess.numIndexes;
}
}
/* /*
=================== ===================
RB_FogPass RB_FogPass
@ -2414,7 +2663,7 @@ static void DrawMultitexturedVBOGLSL( shaderProgram_t *sp, shaderCommands_t *inp
} }
ComputeTexMatrix( pStage, 0, matrix ); ComputeTexMatrix( pStage, 0, matrix );
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_TEXTURE0MATRIX, matrix); GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_DIFFUSETEXMATRIX, matrix);
R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 ); R_BindAnimatedImageToTMU( &pStage->bundle[0], 0 );
@ -2449,6 +2698,8 @@ static unsigned int RB_CalcShaderVertexAttribs( shaderCommands_t *input )
if (vertexAttribs & ATTR_NORMAL) if (vertexAttribs & ATTR_NORMAL)
{ {
vertexAttribs |= ATTR_NORMAL2; vertexAttribs |= ATTR_NORMAL2;
vertexAttribs |= ATTR_TANGENT2;
vertexAttribs |= ATTR_BITANGENT2;
} }
} }
@ -2542,13 +2793,20 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
break; break;
} }
if (pStage->glslShader) if (pStage->glslShaderGroup)
{ {
sp = pStage->glslShader; sp = &pStage->glslShaderGroup[pStage->glslShaderIndex];
if (pStage->glslShaderGroup == tr.lightallShader)
{
backEnd.pc.c_lightallDraws++;
}
} }
else else
{ {
sp = GLSL_GetGenericShaderProgram(); sp = GLSL_GetGenericShaderProgram(stage);
backEnd.pc.c_genericDraws++;
} }
GLSL_BindProgram(sp); GLSL_BindProgram(sp);
@ -2619,7 +2877,7 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE) if (pStage->rgbGen == CGEN_LIGHTING_DIFFUSE)
{ {
vec3_t vec; vec4_t vec;
VectorScale(backEnd.currentEntity->ambientLight, 1.0f / 255.0f, vec); VectorScale(backEnd.currentEntity->ambientLight, 1.0f / 255.0f, vec);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, vec); GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_AMBIENTLIGHT, vec);
@ -2627,7 +2885,9 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
VectorScale(backEnd.currentEntity->directedLight, 1.0f / 255.0f, vec); VectorScale(backEnd.currentEntity->directedLight, 1.0f / 255.0f, vec);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, vec); GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_DIRECTEDLIGHT, vec);
GLSL_SetUniformVec3(sp, GENERIC_UNIFORM_LIGHTDIR, backEnd.currentEntity->lightDir); VectorCopy(backEnd.currentEntity->lightDir, vec);
vec[3] = 0.0f;
GLSL_SetUniformVec4(sp, GENERIC_UNIFORM_LIGHTORIGIN, vec);
} }
if (pStage->alphaGen == AGEN_PORTAL) if (pStage->alphaGen == AGEN_PORTAL)
@ -2650,11 +2910,11 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
// //
// do multitexture // do multitexture
// //
if ( pStage->glslShader ) if ( pStage->glslShaderGroup )
{ {
int i; int i;
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, backEnd.or.modelMatrix); GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_MODELMATRIX, backEnd.or.transformMatrix);
for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) for (i = 0; i < NUM_TEXTURE_BUNDLES; i++)
{ {
@ -2664,8 +2924,14 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
} }
} }
ComputeTexMatrix( pStage, 0, matrix ); ComputeTexMatrix( pStage, TB_DIFFUSEMAP, matrix );
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_TEXTURE0MATRIX, matrix); GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_DIFFUSETEXMATRIX, matrix);
//ComputeTexMatrix( pStage, TB_NORMALMAP, matrix );
//GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_NORMALTEXMATRIX, matrix);
//ComputeTexMatrix( pStage, TB_SPECULARMAP, matrix );
//GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_SPECULARTEXMATRIX, matrix);
// //
// draw // draw
@ -2699,7 +2965,7 @@ static void RB_IterateStagesGenericVBOGLSL( shaderCommands_t *input )
} }
ComputeTexMatrix( pStage, 0, matrix ); ComputeTexMatrix( pStage, 0, matrix );
GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_TEXTURE0MATRIX, matrix); GLSL_SetUniformMatrix16(sp, GENERIC_UNIFORM_DIFFUSETEXMATRIX, matrix);
// //
// set state // set state
@ -2870,8 +3136,6 @@ void RB_StageIteratorGenericVBO( void )
return; return;
} }
backEnd.pc.c_genericDraws++;
if (tess.useInternalVBO) if (tess.useInternalVBO)
{ {
RB_DeformTessGeometry(); RB_DeformTessGeometry();
@ -2937,9 +3201,16 @@ void RB_StageIteratorGenericVBO( void )
if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE
&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) { && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) {
if (glRefConfig.glsl && r_arb_shader_objects->integer) if (glRefConfig.glsl && r_arb_shader_objects->integer)
{
if (tess.shader->numUnfoggedPasses == 1 && tess.xstages[0]->glslShaderGroup == tr.lightallShader)
{
ForwardDlightVBOGLSL();
}
else
{ {
ProjectDlightTextureVBOGLSL(); ProjectDlightTextureVBOGLSL();
} }
}
else else
{ {
// FIXME // FIXME
@ -3058,115 +3329,6 @@ void RB_StageIteratorVertexLitTexture( void )
//define REPLACE_MODE //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 ) { void RB_StageIteratorLightmappedMultitexture( void ) {
shaderCommands_t *input; shaderCommands_t *input;

View file

@ -835,6 +835,10 @@ static qboolean ParseStage( shaderStage_t *stage, char **text )
{ {
stage->type = ST_NORMALMAP; stage->type = ST_NORMALMAP;
} }
else if(!Q_stricmp(token, "normalParallaxMap") || !Q_stricmp(token, "bumpParallaxMap"))
{
stage->type = ST_NORMALPARALLAXMAP;
}
else if(!Q_stricmp(token, "specularMap")) else if(!Q_stricmp(token, "specularMap"))
{ {
stage->type = ST_SPECULARMAP; stage->type = ST_SPECULARMAP;
@ -1706,12 +1710,9 @@ static void ComputeStageIteratorFunc( void )
if ( glRefConfig.vertexBufferObject && r_arb_vertex_buffer_object->integer ) if ( glRefConfig.vertexBufferObject && r_arb_vertex_buffer_object->integer )
{ {
if (!(glRefConfig.glsl && r_arb_shader_objects->integer)) // VBOs have alternate methods for doing fast path
{
// VBOs without shader objects don't support the fast path!
return; return;
} }
}
// //
// see if this can go into the vertex lit fast path // see if this can go into the vertex lit fast path
@ -1729,15 +1730,8 @@ static void ComputeStageIteratorFunc( void )
if ( !shader.multitextureEnv ) if ( !shader.multitextureEnv )
{ {
if ( !shader.numDeforms ) if ( !shader.numDeforms )
{
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; shader.optimalStageIteratorFunc = RB_StageIteratorVertexLitTexture;
}
goto done; goto done;
} }
} }
@ -1761,16 +1755,9 @@ static void ComputeStageIteratorFunc( void )
{ {
if ( !shader.numDeforms ) if ( !shader.numDeforms )
{ {
if ( shader.multitextureEnv == GL_MODULATE && !stages[0].adjustColorsForFog ) if ( shader.multitextureEnv )
{
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; shader.optimalStageIteratorFunc = RB_StageIteratorLightmappedMultitexture;
}
goto done; goto done;
} }
} }
@ -1795,7 +1782,8 @@ static void ComputeVertexAttribs(void)
{ {
int i, stage; int i, stage;
shader.vertexAttribs = ATTR_POSITION; // dlights always need ATTR_NORMAL
shader.vertexAttribs = ATTR_POSITION | ATTR_NORMAL;
// portals always need normals, for SurfIsOffscreen() // portals always need normals, for SurfIsOffscreen()
if (shader.isPortal) if (shader.isPortal)
@ -1857,7 +1845,7 @@ static void ComputeVertexAttribs(void)
break; break;
} }
if (pStage->glslShader) if (pStage->glslShaderGroup)
{ {
shader.vertexAttribs |= ATTR_NORMAL | ATTR_BITANGENT | ATTR_TANGENT; shader.vertexAttribs |= ATTR_NORMAL | ATTR_BITANGENT | ATTR_TANGENT;
} }
@ -2080,45 +2068,127 @@ static qboolean CollapseMultitexture( void ) {
return qtrue; return qtrue;
} }
static void CollapseStagesToLightall(shaderStage_t *diffuse,
shaderStage_t *normal, shaderStage_t *specular, shaderStage_t *lightmap,
qboolean isWorld, qboolean parallax, qboolean environment)
{
int defs = 0;
//ri.Printf(PRINT_ALL, "shader %s has diffuse %s", shader.name, diffuse->bundle[0].image[0]->imgName);
// reuse diffuse, mark others inactive
diffuse->type = ST_GLSL;
if (lightmap)
{
//ri.Printf(PRINT_ALL, ", lightmap");
diffuse->bundle[TB_LIGHTMAP] = lightmap->bundle[0];
defs |= LIGHTDEF_USE_LIGHTMAP;
}
if (tr.worldDeluxeMapping && lightmap)
{
//ri.Printf(PRINT_ALL, ", deluxemap");
diffuse->bundle[TB_DELUXEMAP] = lightmap->bundle[0];
diffuse->bundle[TB_DELUXEMAP].image[0] = tr.deluxemaps[shader.lightmapIndex];
defs |= LIGHTDEF_USE_DELUXEMAP;
if (parallax)
defs |= LIGHTDEF_USE_PARALLAXMAP;
}
if (normal)
{
//ri.Printf(PRINT_ALL, ", normalmap %s", normal->bundle[0].image[0]->imgName);
diffuse->bundle[TB_NORMALMAP] = normal->bundle[0];
defs |= LIGHTDEF_USE_NORMALMAP;
}
if (specular)
{
//ri.Printf(PRINT_ALL, ", specularmap %s", specular->bundle[0].image[0]->imgName);
diffuse->bundle[TB_SPECULARMAP] = specular->bundle[0];
defs |= LIGHTDEF_USE_SPECULARMAP;
}
if (!isWorld)
{
defs |= LIGHTDEF_ENTITY;
}
if (environment)
{
defs |= LIGHTDEF_TCGEN_ENVIRONMENT;
}
//ri.Printf(PRINT_ALL, ".\n");
diffuse->glslShaderGroup = tr.lightallShader;
diffuse->glslShaderIndex = defs;
}
static qboolean CollapseStagesToGLSL(void) static qboolean CollapseStagesToGLSL(void)
{ {
int i, numStages; int i, j, numStages;
shaderStage_t *diffuse, *lightmap, *normal, *specular; qboolean skip = qfalse;
diffuse = NULL; // skip shaders with deforms
lightmap = NULL; if (!(shader.numDeforms == 0 && glRefConfig.vertexBufferObject && r_arb_vertex_buffer_object->integer && glRefConfig.glsl && r_arb_shader_objects->integer))
normal = NULL; {
specular = NULL; skip = qtrue;
}
// find all the stages that are important if (!skip)
{
// scan for shaders that aren't supported
for (i = 0; i < MAX_SHADER_STAGES; i++) for (i = 0; i < MAX_SHADER_STAGES; i++)
{ {
shaderStage_t *pStage = &stages[i]; shaderStage_t *pStage = &stages[i];
int blendbits;
if (!pStage->active) if (!pStage->active)
continue; continue;
blendbits = pStage->stateBits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS); if (pStage->bundle[0].isLightmap && i != 0)
{
int blendBits = pStage->stateBits & ( GLS_DSTBLEND_BITS | GLS_SRCBLEND_BITS );
if (pStage->bundle[0].isLightmap && if (blendBits != (GLS_DSTBLEND_SRC_COLOR | GLS_SRCBLEND_ZERO)
(blendbits == (GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO) || && blendBits != (GLS_DSTBLEND_ZERO | GLS_SRCBLEND_DST_COLOR))
blendbits == (GLS_SRCBLEND_ZERO | GLS_DSTBLEND_SRC_COLOR)))
{ {
lightmap = pStage; skip = qtrue;
} }
else }
switch(pStage->bundle[0].tcGen)
{ {
switch (pStage->type) case TCGEN_TEXTURE:
case TCGEN_LIGHTMAP:
case TCGEN_ENVIRONMENT_MAPPED:
break;
default:
skip = qtrue;
break;
}
switch(pStage->rgbGen)
{ {
case ST_DIFFUSEMAP: //case CGEN_LIGHTING_DIFFUSE:
diffuse = pStage; case CGEN_EXACT_VERTEX:
case CGEN_VERTEX:
case CGEN_ONE_MINUS_VERTEX:
skip = qtrue;
break; break;
case ST_NORMALMAP: default:
normal = pStage;
break; break;
case ST_SPECULARMAP: }
specular = pStage; switch(pStage->alphaGen)
{
case AGEN_LIGHTING_SPECULAR:
case AGEN_VERTEX:
case AGEN_ONE_MINUS_VERTEX:
case AGEN_PORTAL:
case AGEN_FRESNEL:
skip = qtrue;
break; break;
default: default:
break; break;
@ -2126,48 +2196,169 @@ static qboolean CollapseStagesToGLSL(void)
} }
} }
// if we've got these, use deluxemapped shader if (!skip)
if (diffuse && lightmap && normal)
{ {
if (tr.worldDeluxeMapping) qboolean processedColormap = qfalse;
{
// reuse diffuse, mark others inactive
diffuse->type = ST_GLSL;
diffuse->glslShader = &tr.deluxemappedShader;
diffuse->bundle[TB_LIGHTMAP] = lightmap->bundle[0]; for (i = 0; i < MAX_SHADER_STAGES; i++)
diffuse->bundle[TB_NORMALMAP] = normal->bundle[0];
if (specular)
{ {
diffuse->bundle[TB_SPECULARMAP] = specular->bundle[0]; shaderStage_t *pStage = &stages[i];
shaderStage_t *diffuse, *normal, *specular, *lightmap;
qboolean parallax, environment;
int stateBits;
if (!pStage->active)
continue;
if (pStage->type != ST_COLORMAP) // same as diffusemap and lightmap
continue;
diffuse = NULL;
normal = NULL;
parallax = qfalse;
specular = NULL;
lightmap = NULL;
if (pStage->bundle[0].isLightmap)
{
// stop processing if we've already done all the previous colormaps
if (processedColormap)
break;
lightmap = pStage;
}
for (j = i + 1; j < MAX_SHADER_STAGES; j++)
{
shaderStage_t *pStage2 = &stages[j];
if (!pStage2->active)
continue;
if (pStage2->type == ST_NORMALMAP && !normal)
{
normal = pStage2;
continue;
}
if (pStage2->type == ST_NORMALPARALLAXMAP && !normal)
{
normal = pStage2;
parallax = qtrue;
continue;
}
if (pStage2->type == ST_SPECULARMAP && !specular)
{
specular = pStage2;
continue;
}
if (pStage2->type != ST_COLORMAP) // same as diffusemap and lightmap
continue;
// stop if
// - we hit another diffusemap after a lightmap
// - we hit the lightmap
if (lightmap)
{
if (pStage2->bundle[0].isLightmap)
{
// wtf? two lightmaps in one shader?
ri.Printf(PRINT_WARNING, "Found two lightmap passes in shader %s\n", shader.name);
break;
}
diffuse = pStage2;
break;
}
else if (pStage2->bundle[0].isLightmap)
{
lightmap = pStage2;
break;
}
}
if (lightmap == pStage)
{
// after light map
// deal with two lightmap stages problem
if (!diffuse)
break;
stateBits = lightmap->stateBits;
} }
else else
{ {
diffuse->bundle[TB_SPECULARMAP] = diffuse->bundle[0]; // before light map
diffuse->bundle[TB_SPECULARMAP].image[0] = tr.blackImage; diffuse = pStage;
stateBits = diffuse->stateBits;
} }
diffuse->bundle[TB_DELUXEMAP] = lightmap->bundle[0]; environment = qfalse;
diffuse->bundle[TB_DELUXEMAP].image[0] = tr.deluxemaps[shader.lightmapIndex]; if (diffuse->bundle[0].tcGen == TCGEN_ENVIRONMENT_MAPPED)
lightmap->active = qfalse;
normal->active = qfalse;
if (specular)
{ {
specular->active = qfalse; environment = qtrue;
} }
}
else if (diffuse->rgbGen == CGEN_LIGHTING_DIFFUSE)
{ {
// no deluxe mapping, turn off normal and specular CollapseStagesToLightall(diffuse, normal, specular, NULL, qfalse, parallax, environment);
normal->active = qfalse; }
specular->active = qfalse; else if (lightmap)
{
CollapseStagesToLightall(diffuse, normal, specular, lightmap, qtrue, parallax, environment);
}
processedColormap = qtrue;
diffuse->stateBits = stateBits;
if (lightmap == pStage)
break;
}
// deactivate lightmap stages
for (i = 0; i < MAX_SHADER_STAGES; i++)
{
shaderStage_t *pStage = &stages[i];
if (!pStage->active)
continue;
if (pStage->bundle[0].isLightmap)
{
pStage->active = qfalse;
}
} }
} }
// condense stages // deactivate normal and specular stages
for (i = 0; i < MAX_SHADER_STAGES; i++)
{
shaderStage_t *pStage = &stages[i];
if (!pStage->active)
continue;
if (pStage->type == ST_NORMALMAP)
{
pStage->active = qfalse;
}
if (pStage->type == ST_NORMALPARALLAXMAP)
{
pStage->active = qfalse;
}
if (pStage->type == ST_SPECULARMAP)
{
pStage->active = qfalse;
}
}
// remove inactive stages
numStages = 0; numStages = 0;
for (i = 0; i < MAX_SHADER_STAGES; i++) for (i = 0; i < MAX_SHADER_STAGES; i++)
{ {
@ -2185,7 +2376,7 @@ static qboolean CollapseStagesToGLSL(void)
numStages++; numStages++;
} }
if (numStages == i && i == 2 && CollapseMultitexture()) if (numStages == i && i >= 2 && CollapseMultitexture())
numStages--; numStages--;
return numStages; return numStages;