implemented MATERIALFLAG_REFRACTION
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 15 Oct 2007 12:07:28 +0000 (12:07 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 15 Oct 2007 12:07:28 +0000 (12:07 +0000)
changed syntax of dp_refract, dp_reflect, added dp_water
moved SHADERPERMUTATION and friends to gl_rmain.c
eliminated SHADERPERMUTATION_MASK by separating out SHADERTYPE_USES
other cleanup

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7634 d7cf8633-e32d-0410-b094-e92efae38249

gl_rmain.c
model_brush.c
model_brush.h
model_shared.c
model_shared.h
render.h

index e7e4750..8b0aec6 100644 (file)
@@ -188,11 +188,6 @@ rtexture_t *r_texture_normalizationcube;
 rtexture_t *r_texture_fogattenuation;
 //rtexture_t *r_texture_fogintensity;
 
-// information about each possible shader permutation
-r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_MAX];
-// currently selected permutation
-r_glsl_permutation_t *r_glsl_permutation;
-
 char r_qwskincache[MAX_SCOREBOARD][MAX_QPATH];
 skinframe_t *r_qwskincache_skinframe[MAX_SCOREBOARD];
 
@@ -452,8 +447,12 @@ static const char *builtinshaderstring =
 "//#ifdef USEWATER\n"
 "varying vec4 ModelViewProjectionPosition;\n"
 "//#else\n"
-"//# ifdef USEREFLECTION\n"
+"//# ifdef USEREFRACTION\n"
+"//varying vec4 ModelViewProjectionPosition;\n"
+"//# else\n"
+"//#  ifdef USEREFLECTION\n"
 "//varying vec4 ModelViewProjectionPosition;\n"
+"//#  endif\n"
 "//# endif\n"
 "//#endif\n"
 "\n"
@@ -529,8 +528,12 @@ static const char *builtinshaderstring =
 "#ifdef USEWATER\n"
 "      ModelViewProjectionPosition = gl_Position;\n"
 "#else\n"
-"# ifdef USEREFLECTION\n"
+"# ifdef USEWATER\n"
+"      ModelViewProjectionPosition = gl_Position;\n"
+"# else\n"
+"#  ifdef USEREFLECTION\n"
 "      ModelViewProjectionPosition = gl_Position;\n"
+"#  endif\n"
 "# endif\n"
 "#endif\n"
 "}\n"
@@ -570,8 +573,8 @@ static const char *builtinshaderstring =
 "uniform vec4 DistortScaleRefractReflect;\n"
 "uniform vec4 ScreenScaleRefractReflect;\n"
 "uniform vec4 ScreenCenterRefractReflect;\n"
-"uniform myhvec3 RefractColor;\n"
-"uniform myhvec3 ReflectColor;\n"
+"uniform myhvec4 RefractColor;\n"
+"uniform myhvec4 ReflectColor;\n"
 "uniform myhalf ReflectFactor;\n"
 "uniform myhalf ReflectOffset;\n"
 "//#else\n"
@@ -776,20 +779,28 @@ static const char *builtinshaderstring =
 "# ifdef USEWATER\n"
 "      color.rgb *= color.a;\n"
 "# endif\n"
+"# ifdef USEREFRACTION\n"
+"      color.rgb *= color.a;\n"
+"# endif\n"
 "#else\n"
 "# ifdef USEWATER\n"
 "      vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
 "      //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
 "      vec4 ScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect + vec3(normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
 "      myhalf Fresnel = myhalf(pow(min(1.0, 1.0 - float(normalize(EyeVector).z)), 2.0)) * ReflectFactor + ReflectOffset;\n"
-"      color.rgb = mix(mix(myhvec3(texture2D(Texture_Refraction, ScreenTexCoord.xy)) * RefractColor, myhvec3(texture2D(Texture_Reflection, ScreenTexCoord.zw)) * ReflectColor, Fresnel), color.rgb, color.a);\n"
-"# else\n"
-"#  ifdef USEREFLECTION\n"
+"      color.rgb = mix(mix(myhvec3(texture2D(Texture_Refraction, ScreenTexCoord.xy)) * RefractColor.rgb, myhvec3(texture2D(Texture_Reflection, ScreenTexCoord.zw)) * ReflectColor.rgb, Fresnel), color.rgb, color.a);\n"
+"# endif\n"
+"# ifdef USEREFRACTION\n"
 "      vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
 "      //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
 "      vec4 ScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect + vec3(normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
-"      color.rgb += myhvec3(texture2D(Texture_Reflection, ScreenTexCoord.zw)) * ReflectColor;\n"
-"#  endif\n"
+"      color.rgb = mix(myhvec3(texture2D(Texture_Refraction, ScreenTexCoord.xy)) * RefractColor.rgb, color.rgb, color.a);\n"
+"# endif\n"
+"# ifdef USEREFLECTION\n"
+"      vec4 ScreenScaleRefractReflectIW = ScreenScaleRefractReflect * (1.0 / ModelViewProjectionPosition.w);\n"
+"      //vec4 ScreenTexCoord = (ModelViewProjectionPosition.xyxy + normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5)).xyxy * DistortScaleRefractReflect * 100) * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect;\n"
+"      vec4 ScreenTexCoord = ModelViewProjectionPosition.xyxy * ScreenScaleRefractReflectIW + ScreenCenterRefractReflect + vec3(normalize(myhvec3(texture2D(Texture_Normal, TexCoord)) - myhvec3(0.5))).xyxy * DistortScaleRefractReflect;\n"
+"      color.rgb = mix(color.rgb, myhvec3(texture2D(Texture_Reflection, ScreenTexCoord.zw)) * ReflectColor.rgb, ReflectColor.a);\n"
 "# endif\n"
 "#endif\n"
 "\n"
@@ -814,6 +825,27 @@ static const char *builtinshaderstring =
 "#endif // FRAGMENT_SHADER\n"
 ;
 
+#define SHADERPERMUTATION_MODE_LIGHTMAP (1<<0) // (lightmap) use directional pixel shading from fixed light direction (q3bsp)
+#define SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE (1<<1) // (lightmap) use directional pixel shading from texture containing modelspace light directions (deluxemap)
+#define SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE (1<<2) // (lightmap) use directional pixel shading from texture containing tangentspace light directions (deluxemap)
+#define SHADERPERMUTATION_MODE_LIGHTDIRECTION (1<<3) // (lightmap) use directional pixel shading from fixed light direction (q3bsp)
+#define SHADERPERMUTATION_MODE_LIGHTSOURCE (1<<4) // (lightsource) use directional pixel shading from light source (rtlight)
+#define SHADERPERMUTATION_WATER (1<<5) // normalmap-perturbed refraction of the background, performed behind the surface (the texture or material must be transparent to see it)
+#define SHADERPERMUTATION_REFRACTION (1<<6) // normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
+#define SHADERPERMUTATION_REFLECTION (1<<7) // normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
+#define SHADERPERMUTATION_GLOW (1<<8) // (lightmap) blend in an additive glow texture
+#define SHADERPERMUTATION_FOG (1<<9) // tint the color by fog color or black if using additive blend mode
+#define SHADERPERMUTATION_COLORMAPPING (1<<10) // indicates this is a colormapped skin
+#define SHADERPERMUTATION_DIFFUSE (1<<11) // (lightsource) whether to use directional shading
+#define SHADERPERMUTATION_CONTRASTBOOST (1<<12) // r_glsl_contrastboost boosts the contrast at low color levels (similar to gamma)
+#define SHADERPERMUTATION_SPECULAR (1<<13) // (lightsource or deluxemapping) render specular effects
+#define SHADERPERMUTATION_CUBEFILTER (1<<14) // (lightsource) use cubemap light filter
+#define SHADERPERMUTATION_OFFSETMAPPING (1<<15) // adjust texcoords to roughly simulate a displacement mapped surface
+#define SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING (1<<16) // adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
+
+#define SHADERPERMUTATION_INDICES (1<<17) // how many permutations are possible
+#define SHADERPERMUTATION_MASK (SHADERPERMUTATION_INDICES - 1) // mask of valid indexing bits for r_glsl_permutations[] array
+
 // NOTE: MUST MATCH ORDER OF SHADERPERMUTATION_* DEFINES!
 const char *permutationinfo[][2] =
 {
@@ -823,6 +855,7 @@ const char *permutationinfo[][2] =
        {"#define MODE_LIGHTDIRECTION\n", " lightdirection"},
        {"#define MODE_LIGHTSOURCE\n", " lightsource"},
        {"#define USEWATER\n", " water"},
+       {"#define USEREFRACTION\n", " refraction"},
        {"#define USEREFLECTION\n", " reflection"},
        {"#define USEGLOW\n", " glow"},
        {"#define USEFOG\n", " fog"},
@@ -836,11 +869,70 @@ const char *permutationinfo[][2] =
        {NULL, NULL}
 };
 
-void R_GLSL_CompilePermutation(const char *filename, int permutation)
+typedef struct r_glsl_permutation_s
+{
+       // indicates if we have tried compiling this permutation already
+       qboolean compiled;
+       // 0 if compilation failed
+       int program;
+       // locations of detected uniforms in program object, or -1 if not found
+       int loc_Texture_Normal;
+       int loc_Texture_Color;
+       int loc_Texture_Gloss;
+       int loc_Texture_Cube;
+       int loc_Texture_Attenuation;
+       int loc_Texture_FogMask;
+       int loc_Texture_Pants;
+       int loc_Texture_Shirt;
+       int loc_Texture_Lightmap;
+       int loc_Texture_Deluxemap;
+       int loc_Texture_Glow;
+       int loc_Texture_Refraction;
+       int loc_Texture_Reflection;
+       int loc_FogColor;
+       int loc_LightPosition;
+       int loc_EyePosition;
+       int loc_LightColor;
+       int loc_Color_Pants;
+       int loc_Color_Shirt;
+       int loc_FogRangeRecip;
+       int loc_AmbientScale;
+       int loc_DiffuseScale;
+       int loc_SpecularScale;
+       int loc_SpecularPower;
+       int loc_GlowScale;
+       int loc_SceneBrightness; // or: Scenebrightness * ContrastBoost
+       int loc_OffsetMapping_Scale;
+       int loc_AmbientColor;
+       int loc_DiffuseColor;
+       int loc_SpecularColor;
+       int loc_LightDir;
+       int loc_ContrastBoostCoeff; // 1 - 1/ContrastBoost
+       int loc_DistortScaleRefractReflect;
+       int loc_ScreenScaleRefractReflect;
+       int loc_ScreenCenterRefractReflect;
+       int loc_RefractColor;
+       int loc_ReflectColor;
+       int loc_ReflectFactor;
+       int loc_ReflectOffset;
+}
+r_glsl_permutation_t;
+
+// information about each possible shader permutation
+r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_INDICES];
+// currently selected permutation
+r_glsl_permutation_t *r_glsl_permutation;
+
+// these are additional flags used only by R_GLSL_CompilePermutation
+#define SHADERTYPE_USES_VERTEXSHADER (1<<0)
+#define SHADERTYPE_USES_GEOMETRYSHADER (1<<1)
+#define SHADERTYPE_USES_FRAGMENTSHADER (1<<2)
+
+static void R_GLSL_CompilePermutation(const char *filename, int permutation, int shadertype)
 {
        int i;
        qboolean shaderfound;
-       r_glsl_permutation_t *p = r_glsl_permutations + (permutation & SHADERPERMUTATION_MASK);
+       r_glsl_permutation_t *p = r_glsl_permutations + permutation;
        int vertstrings_count;
        int geomstrings_count;
        int fragstrings_count;
@@ -881,7 +973,7 @@ void R_GLSL_CompilePermutation(const char *filename, int permutation)
        shaderfound = false;
        if (shaderstring)
        {
-               Con_DPrintf("GLSL shader text for \"%s\" loaded from disk\n", filename);
+               Con_DPrint("from disk... ");
                vertstrings_list[vertstrings_count++] = shaderstring;
                geomstrings_list[geomstrings_count++] = shaderstring;
                fragstrings_list[fragstrings_count++] = shaderstring;
@@ -889,18 +981,17 @@ void R_GLSL_CompilePermutation(const char *filename, int permutation)
        }
        else if (!strcmp(filename, "glsl/default.glsl"))
        {
-               Con_DPrintf("GLSL shader text for \"%s\" loaded from engine\n", filename);
                vertstrings_list[vertstrings_count++] = builtinshaderstring;
                geomstrings_list[geomstrings_count++] = builtinshaderstring;
                fragstrings_list[fragstrings_count++] = builtinshaderstring;
                shaderfound = true;
        }
        // clear any lists that are not needed by this shader
-       if (!(permutation & SHADERPERMUTATION_USES_VERTEXSHADER))
+       if (!(shadertype & SHADERTYPE_USES_VERTEXSHADER))
                vertstrings_count = 0;
-       if (!(permutation & SHADERPERMUTATION_USES_GEOMETRYSHADER))
+       if (!(shadertype & SHADERTYPE_USES_GEOMETRYSHADER))
                geomstrings_count = 0;
-       if (!(permutation & SHADERPERMUTATION_USES_FRAGMENTSHADER))
+       if (!(shadertype & SHADERTYPE_USES_FRAGMENTSHADER))
                fragstrings_count = 0;
        // compile the shader program
        if (shaderfound && vertstrings_count + geomstrings_count + fragstrings_count)
@@ -966,9 +1057,16 @@ void R_GLSL_CompilePermutation(const char *filename, int permutation)
                if (p->loc_Texture_Reflection >= 0) qglUniform1iARB(p->loc_Texture_Reflection, 12);
                CHECKGLERROR
                qglUseProgramObjectARB(0);CHECKGLERROR
+               if (developer.integer)
+                       Con_Printf("GLSL shader %s :%s compiled.\n", filename, permutationname);
        }
        else
-               Con_Printf("permutation%s failed for shader %s, some features may not work properly!\n", permutationname, filename);
+       {
+               if (developer.integer)
+                       Con_Printf("GLSL shader %s :%s failed!  source code line offset for above errors is %i.\n", permutationname, filename, -(vertstrings_count - 1));
+               else
+                       Con_Printf("GLSL shader %s :%s failed!  some features may not work properly.\n", permutationname, filename);
+       }
        if (shaderstring)
                Mem_Free(shaderstring);
 }
@@ -976,7 +1074,7 @@ void R_GLSL_CompilePermutation(const char *filename, int permutation)
 void R_GLSL_Restart_f(void)
 {
        int i;
-       for (i = 0;i < SHADERPERMUTATION_MAX;i++)
+       for (i = 0;i < SHADERPERMUTATION_INDICES;i++)
                if (r_glsl_permutations[i].program)
                        GL_Backend_FreeProgram(r_glsl_permutations[i].program);
        memset(r_glsl_permutations, 0, sizeof(r_glsl_permutations));
@@ -1015,14 +1113,16 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
        // fragment shader on features that are not being used
        const char *shaderfilename = NULL;
        unsigned int permutation = 0;
+       unsigned int shadertype = 0;
        rtexture_t *nmap;
        r_glsl_permutation = NULL;
+       shaderfilename = "glsl/default.glsl";
+       shadertype = SHADERTYPE_USES_VERTEXSHADER | SHADERTYPE_USES_FRAGMENTSHADER;
        // TODO: implement geometry-shader based shadow volumes someday
        if (rsurface.rtlight)
        {
                // light source
-               shaderfilename = "glsl/default.glsl";
-               permutation = SHADERPERMUTATION_MODE_LIGHTSOURCE | SHADERPERMUTATION_USES_VERTEXSHADER | SHADERPERMUTATION_USES_FRAGMENTSHADER;
+               permutation = SHADERPERMUTATION_MODE_LIGHTSOURCE;
                if (rsurface.rtlight->currentcubemap != r_texture_whitecube)
                        permutation |= SHADERPERMUTATION_CUBEFILTER;
                if (diffusescale > 0)
@@ -1049,8 +1149,6 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
        else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
        {
                // bright unshaded geometry
-               shaderfilename = "glsl/default.glsl";
-               permutation = SHADERPERMUTATION_USES_VERTEXSHADER | SHADERPERMUTATION_USES_FRAGMENTSHADER;
                permutation |= SHADERPERMUTATION_MODE_LIGHTMAP;
                if (rsurface.texture->currentskinframe->glow)
                        permutation |= SHADERPERMUTATION_GLOW;
@@ -1074,8 +1172,6 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
        else if (modellighting)
        {
                // directional model lighting
-               shaderfilename = "glsl/default.glsl";
-               permutation = SHADERPERMUTATION_USES_VERTEXSHADER | SHADERPERMUTATION_USES_FRAGMENTSHADER;
                permutation |= SHADERPERMUTATION_MODE_LIGHTDIRECTION;
                if (rsurface.texture->currentskinframe->glow)
                        permutation |= SHADERPERMUTATION_GLOW;
@@ -1101,8 +1197,6 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
        else
        {
                // lightmapped wall
-               shaderfilename = "glsl/default.glsl";
-               permutation = SHADERPERMUTATION_USES_VERTEXSHADER | SHADERPERMUTATION_USES_FRAGMENTSHADER;
                if (r_glsl_deluxemapping.integer >= 1 && rsurface.uselightmaptexture && r_refdef.worldmodel && r_refdef.worldmodel->brushq3.deluxemapping)
                {
                        // deluxemapping (light direction texture)
@@ -1144,15 +1238,15 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
                if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION)
                        permutation |= SHADERPERMUTATION_REFLECTION;
        }
-       if (!r_glsl_permutations[permutation & SHADERPERMUTATION_MASK].program)
+       if (!r_glsl_permutations[permutation].program)
        {
-               if (!r_glsl_permutations[permutation & SHADERPERMUTATION_MASK].compiled)
-                       R_GLSL_CompilePermutation(shaderfilename, permutation);
-               if (!r_glsl_permutations[permutation & SHADERPERMUTATION_MASK].program)
+               if (!r_glsl_permutations[permutation].compiled)
+                       R_GLSL_CompilePermutation(shaderfilename, permutation, shadertype);
+               if (!r_glsl_permutations[permutation].program)
                {
                        // remove features until we find a valid permutation
                        unsigned int i;
-                       for (i = (SHADERPERMUTATION_MAX >> 1);;i>>=1)
+                       for (i = (SHADERPERMUTATION_INDICES >> 1);;i>>=1)
                        {
                                if (!i)
                                {
@@ -1164,14 +1258,14 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
                                if (!(permutation & i))
                                        continue;
                                permutation &= ~i;
-                               if (!r_glsl_permutations[permutation & SHADERPERMUTATION_MASK].compiled)
-                                       R_GLSL_CompilePermutation(shaderfilename, permutation);
-                               if (r_glsl_permutations[permutation & SHADERPERMUTATION_MASK].program)
+                               if (!r_glsl_permutations[permutation].compiled)
+                                       R_GLSL_CompilePermutation(shaderfilename, permutation, shadertype);
+                               if (r_glsl_permutations[permutation].program)
                                        break;
                        }
                }
        }
-       r_glsl_permutation = r_glsl_permutations + (permutation & SHADERPERMUTATION_MASK);
+       r_glsl_permutation = r_glsl_permutations + permutation;
        CHECKGLERROR
        qglUseProgramObjectARB(r_glsl_permutation->program);CHECKGLERROR
        R_Mesh_TexMatrix(0, &rsurface.texture->currenttexmatrix);
@@ -1218,7 +1312,7 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
        if (r_glsl_permutation->loc_Texture_Normal >= 0) R_Mesh_TexBind(0, R_GetTexture(nmap));
        if (r_glsl_permutation->loc_Texture_Color >= 0) R_Mesh_TexBind(1, R_GetTexture(rsurface.texture->basetexture));
        if (r_glsl_permutation->loc_Texture_Gloss >= 0) R_Mesh_TexBind(2, R_GetTexture(rsurface.texture->glosstexture));
-       //if (r_glsl_permutation->loc_Texture_Cube >= 0 && permutation & SHADERPERMUTATION_MODE_LIGHTSOURCE) R_Mesh_TexBindCubeMap(3, R_GetTexture(rsurface.rtlight->currentcubemap));
+       //if (r_glsl_permutation->loc_Texture_Cube >= 0 && rsurface.rtlight) R_Mesh_TexBindCubeMap(3, R_GetTexture(rsurface.rtlight->currentcubemap));
        if (r_glsl_permutation->loc_Texture_Attenuation >= 0) R_Mesh_TexBind(10, R_GetTexture(r_shadow_attenuationgradienttexture));
        if (r_glsl_permutation->loc_Texture_FogMask >= 0) R_Mesh_TexBind(4, R_GetTexture(r_texture_fogattenuation));
        if (r_glsl_permutation->loc_Texture_Pants >= 0) R_Mesh_TexBind(5, R_GetTexture(rsurface.texture->currentskinframe->pants));
@@ -1271,28 +1365,17 @@ int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, fl
        if (r_glsl_permutation->loc_FogRangeRecip >= 0) qglUniform1fARB(r_glsl_permutation->loc_FogRangeRecip, r_refdef.fograngerecip);
        if (r_glsl_permutation->loc_SpecularPower >= 0) qglUniform1fARB(r_glsl_permutation->loc_SpecularPower, rsurface.texture->specularpower);
        if (r_glsl_permutation->loc_OffsetMapping_Scale >= 0) qglUniform1fARB(r_glsl_permutation->loc_OffsetMapping_Scale, r_glsl_offsetmapping_scale.value);
-       if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value, r_water_reflectdistort.value);
+       if (r_glsl_permutation->loc_DistortScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_DistortScaleRefractReflect, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_refractdistort.value * rsurface.texture->refractfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor, r_water_reflectdistort.value * rsurface.texture->reflectfactor);
        if (r_glsl_permutation->loc_ScreenScaleRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenScaleRefractReflect, r_waterstate.screenscale[0], r_waterstate.screenscale[1], r_waterstate.screenscale[0], r_waterstate.screenscale[1]);
        if (r_glsl_permutation->loc_ScreenCenterRefractReflect >= 0) qglUniform4fARB(r_glsl_permutation->loc_ScreenCenterRefractReflect, r_waterstate.screencenter[0], r_waterstate.screencenter[1], r_waterstate.screencenter[0], r_waterstate.screencenter[1]);
-       if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform3fvARB(r_glsl_permutation->loc_RefractColor, 1, rsurface.texture->refractcolor);
-       if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform3fvARB(r_glsl_permutation->loc_ReflectColor, 1, rsurface.texture->reflectcolor);
-       if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->refractmax - rsurface.texture->refractmin);
-       if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectOffset, 1 - rsurface.texture->refractmax);
+       if (r_glsl_permutation->loc_RefractColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_RefractColor, 1, rsurface.texture->refractcolor4f);
+       if (r_glsl_permutation->loc_ReflectColor >= 0) qglUniform4fvARB(r_glsl_permutation->loc_ReflectColor, 1, rsurface.texture->reflectcolor4f);
+       if (r_glsl_permutation->loc_ReflectFactor >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectFactor, rsurface.texture->reflectmax - rsurface.texture->reflectmin);
+       if (r_glsl_permutation->loc_ReflectOffset >= 0) qglUniform1fARB(r_glsl_permutation->loc_ReflectOffset, rsurface.texture->reflectmin);
        CHECKGLERROR
        return permutation;
 }
 
-void R_SwitchSurfaceShader(int permutation)
-{
-       if (r_glsl_permutation != r_glsl_permutations + (permutation & SHADERPERMUTATION_MASK))
-       {
-               r_glsl_permutation = r_glsl_permutations + (permutation & SHADERPERMUTATION_MASK);
-               CHECKGLERROR
-               qglUseProgramObjectARB(r_glsl_permutation->program);
-               CHECKGLERROR
-       }
-}
-
 #define SKINFRAME_HASH 1024
 
 struct
@@ -2550,7 +2633,7 @@ static void R_Water_AddWaterPlane(msurface_t *surface)
        // merge this surface's materialflags into the waterplane
        p->materialflags |= surface->texture->currentframe->currentmaterialflags;
        // merge this surface's PVS into the waterplane
-       if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION) && r_refdef.worldmodel && r_refdef.worldmodel->brush.FatPVS)
+       if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) && r_refdef.worldmodel && r_refdef.worldmodel->brush.FatPVS)
        {
                r_refdef.worldmodel->brush.FatPVS(r_refdef.worldmodel, r_view.origin, 2, p->pvsbits, sizeof(p->pvsbits), p->pvsvalid);
                p->pvsvalid = true;
@@ -2568,7 +2651,7 @@ static void R_Water_ProcessPlanes(void)
        // make sure enough textures are allocated
        for (planeindex = 0, p = r_waterstate.waterplanes;planeindex < r_waterstate.numwaterplanes;planeindex++, p++)
        {
-               if (p->materialflags & MATERIALFLAG_WATERSHADER)
+               if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
                {
                        if (!p->texture_refraction)
                                p->texture_refraction = R_LoadTexture2D(r_main_texturepool, va("waterplane%i_refraction", planeindex), r_waterstate.texturewidth, r_waterstate.textureheight, NULL, TEXTYPE_RGBA, TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_ALWAYSPRECACHE, NULL);
@@ -2596,7 +2679,7 @@ static void R_Water_ProcessPlanes(void)
 
                // render the normal view scene and copy into texture
                // (except that a clipping plane should be used to hide everything on one side of the water, and the viewer's weapon model should be omitted)
-               if (p->materialflags & MATERIALFLAG_WATERSHADER)
+               if (p->materialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION))
                {
                        r_view.clipplane = p->plane;
                        VectorNegate(r_view.clipplane.normal, r_view.clipplane.normal);
@@ -3831,10 +3914,7 @@ void R_UpdateTextureInfo(const entity_render_t *ent, texture_t *t)
                */
        }
        if(!r_waterstate.enabled)
-       {
-               t->currentmaterialflags &= ~MATERIALFLAG_WATERSHADER;
-               t->currentmaterialflags &= ~MATERIALFLAG_REFLECTION;
-       }
+               t->currentmaterialflags &= ~(MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION);
        if (!(ent->flags & RENDER_LIGHT))
                t->currentmaterialflags |= MATERIALFLAG_FULLBRIGHT;
        if (ent->effects & EF_ADDITIVE)
@@ -5735,7 +5815,7 @@ void R_QueueSurfaceList(entity_render_t *ent, int numsurfaces, msurface_t **surf
        if (addwaterplanes)
        {
                for (i = 0;i < numsurfaces;i++)
-                       if (surfacelist[i]->texture->currentframe->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
+                       if (surfacelist[i]->texture->currentframe->currentmaterialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION))
                                R_Water_AddWaterPlane(surfacelist[i]);
                return;
        }
@@ -6014,7 +6094,7 @@ void R_DrawWorldSurfaces(qboolean skysurfaces, qboolean writedepth, qboolean dep
        }
 
        R_UpdateAllTextureInfo(r_refdef.worldentity);
-       flagsmask = addwaterplanes ? (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION) : (skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL));
+       flagsmask = addwaterplanes ? (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) : (skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL));
 
        if (debug)
        {
@@ -6101,7 +6181,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr
        }
 
        R_UpdateAllTextureInfo(ent);
-       flagsmask = addwaterplanes ? (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION) : (skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL));
+       flagsmask = addwaterplanes ? (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION) : (skysurfaces ? MATERIALFLAG_SKY : (MATERIALFLAG_WATER | MATERIALFLAG_WALL));
 
        if (debug)
        {
index c67e956..0b1293a 100644 (file)
@@ -1394,6 +1394,14 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                        tx->surfaceflags = mod_q1bsp_texture_solid.surfaceflags;
                }
                tx->currentframe = tx;
+
+               // clear water settings
+               tx->reflectmin = 0;
+               tx->reflectmax = 1;
+               tx->refractfactor = 1;
+               Vector4Set(tx->refractcolor4f, 1, 1, 1, 1);
+               tx->reflectfactor = 1;
+               Vector4Set(tx->reflectcolor4f, 1, 1, 1, 1);
        }
 
        if (!m)
@@ -1553,14 +1561,7 @@ static void Mod_Q1BSP_LoadTextures(lump_t *l)
                                if (strncmp(tx->name,"*lava",5)
                                 && strncmp(tx->name,"*teleport",9)
                                 && strncmp(tx->name,"*rift",5)) // Scourge of Armagon texture
-                                {
                                        tx->basematerialflags |= MATERIALFLAG_WATERALPHA | MATERIALFLAG_NOSHADOW | MATERIALFLAG_WATERSHADER;
-                                       VectorSet(tx->reflectcolor, 1, 1, 1);
-                                       VectorSet(tx->refractcolor, 1, 1, 1);
-                                       tx->refractmin = 0;
-                                       tx->refractmax = 1;
-                                       tx->refractfactor = 1;
-                               }
                                tx->basematerialflags |= MATERIALFLAG_WATER | MATERIALFLAG_LIGHTBOTHSIDES | MATERIALFLAG_NOSHADOW;
                        }
                        else if (!strncmp(tx->name, "sky", 3))
@@ -3686,7 +3687,7 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
                                // we only need to have a drawsky function if it is used(usually only on world model)
                                if (surface->texture->basematerialflags & MATERIALFLAG_SKY)
                                        mod->DrawSky = R_Q1BSP_DrawSky;
-                               if (surface->texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
+                               if (surface->texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION))
                                        mod->DrawAddWaterPlanes = R_Q1BSP_DrawAddWaterPlanes;
                                // calculate bounding shapes
                                for (k = 0, vec = (loadmodel->surfmesh.data_vertex3f + 3 * surface->num_firstvertex);k < surface->num_vertices;k++, vec += 3)
@@ -5790,7 +5791,7 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer, void *bufferend)
                        mod->DrawSky = NULL;
 
                for (j = 0;j < mod->nummodelsurfaces;j++)
-                       if (mod->data_surfaces[j + mod->firstmodelsurface].texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFLECTION))
+                       if (mod->data_surfaces[j + mod->firstmodelsurface].texture->basematerialflags & (MATERIALFLAG_WATERSHADER | MATERIALFLAG_REFRACTION | MATERIALFLAG_REFLECTION))
                                break;
                if (j < mod->nummodelsurfaces)
                        mod->DrawAddWaterPlanes = R_Q1BSP_DrawAddWaterPlanes;
index b4cce7b..cd46206 100644 (file)
@@ -98,12 +98,16 @@ mplane_t;
 #define MATERIALFLAG_NOCULLFACE 65536
 // render with a very short depth range (like 10% of normal), this causes entities to appear infront of most of the scene
 #define MATERIALFLAG_SHORTDEPTHRANGE 131072
-// render refraction and reflection (note: this is always opaque, the shader does the alpha effect)
+// render water, comprising refraction and reflection (note: this is always opaque, the shader does the alpha effect)
 #define MATERIALFLAG_WATERSHADER 262144
-// render reflection only
-#define MATERIALFLAG_REFLECTION 524288
+// render refraction (note: this is just a way to distort the background, otherwise useless)
+#define MATERIALFLAG_REFRACTION 524288
+// render reflection
+#define MATERIALFLAG_REFLECTION 1048576
+// render water, comprising refraction and reflection (note: this is always opaque, the shader does the alpha effect)
+#define MATERIALFLAG_SORTTRANSPARENT 2097152
 // combined mask of all attributes that require depth sorted rendering
-#define MATERIALFLAGMASK_DEPTHSORTED (MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST)
+#define MATERIALFLAGMASK_DEPTHSORTED (MATERIALFLAG_SORTTRANSPARENT | MATERIALFLAG_BLENDED | MATERIALFLAG_NODEPTHTEST)
 
 typedef struct medge_s
 {
index 880d5f3..4db8ee9 100644 (file)
@@ -1135,11 +1135,12 @@ void Mod_LoadQ3Shaders(void)
                        shader = q3shaders_shaders + q3shaders_numshaders++;
 
                        memset(shader, 0, sizeof(*shader));
-                       VectorSet(shader->reflectcolor, 1, 1, 1);
-                       VectorSet(shader->refractcolor, 1, 1, 1);
-                       shader->refractmin = 0;
-                       shader->refractmax = 1;
+                       shader->reflectmin = 0;
+                       shader->reflectmax = 1;
                        shader->refractfactor = 1;
+                       Vector4Set(shader->refractcolor4f, 1, 1, 1, 1);
+                       shader->reflectfactor = 1;
+                       Vector4Set(shader->reflectcolor4f, 1, 1, 1, 1);
 
                        strlcpy(shader->name, com_token, sizeof(shader->name));
                        if (!COM_ParseToken_QuakeC(&text, false) || strcasecmp(com_token, "{"))
@@ -1500,27 +1501,27 @@ void Mod_LoadQ3Shaders(void)
                                        shader->textureflags |= Q3TEXTUREFLAG_NOPICMIP;
                                else if (!strcasecmp(parameter[0], "polygonoffset"))
                                        shader->textureflags |= Q3TEXTUREFLAG_POLYGONOFFSET;
-                               else if (!strcasecmp(parameter[0], "dp_reflect"))
+                               else if (!strcasecmp(parameter[0], "dp_refract") && numparameters >= 5)
+                               {
+                                       shader->textureflags |= Q3TEXTUREFLAG_REFRACTION;
+                                       shader->refractfactor = atof(parameter[1]);
+                                       Vector4Set(shader->refractcolor4f, atof(parameter[2]), atof(parameter[3]), atof(parameter[4]), 1);
+                               }
+                               else if (!strcasecmp(parameter[0], "dp_reflect") && numparameters >= 6)
                                {
                                        shader->textureflags |= Q3TEXTUREFLAG_REFLECTION;
-                                       if(numparameters >= 2)
-                                               VectorSet(shader->reflectcolor, atof(parameter[1]), atof(parameter[1]), atof(parameter[1])); // grey
-                                       if(numparameters >= 4)
-                                               VectorSet(shader->reflectcolor, atof(parameter[1]), atof(parameter[2]), atof(parameter[3]));
+                                       shader->reflectfactor = atof(parameter[1]);
+                                       Vector4Set(shader->reflectcolor4f, atof(parameter[2]), atof(parameter[3]), atof(parameter[4]), atof(parameter[5]));
                                }
-                               else if (!strcasecmp(parameter[0], "dp_refract"))
+                               else if (!strcasecmp(parameter[0], "dp_water") && numparameters >= 11)
                                {
                                        shader->textureflags |= Q3TEXTUREFLAG_WATERSHADER;
-                                       if(numparameters >= 2)
-                                               shader->refractmin = atof(parameter[1]);
-                                       if(numparameters >= 3)
-                                               shader->refractmax = atof(parameter[2]);
-                                       if(numparameters >= 4)
-                                               shader->refractfactor = atof(parameter[3]);
-                                       if(numparameters >= 5)
-                                               VectorSet(shader->refractcolor, atof(parameter[4]), atof(parameter[4]), atof(parameter[4])); // grey
-                                       if(numparameters >= 7)
-                                               VectorSet(shader->refractcolor, atof(parameter[4]), atof(parameter[5]), atof(parameter[6]));
+                                       shader->reflectmin = atof(parameter[1]);
+                                       shader->reflectmax = atof(parameter[2]);
+                                       shader->refractfactor = atof(parameter[3]);
+                                       shader->reflectfactor = atof(parameter[4]);
+                                       Vector4Set(shader->refractcolor4f, atof(parameter[5]), atof(parameter[6]), atof(parameter[7]), 1);
+                                       Vector4Set(shader->reflectcolor4f, atof(parameter[8]), atof(parameter[9]), atof(parameter[10]), 1);
                                }
                                else if (!strcasecmp(parameter[0], "deformvertexes") && numparameters >= 2)
                                {
@@ -1584,7 +1585,7 @@ void Mod_LoadQ3Shaders(void)
                        }
                        // fix up multiple reflection types
                        if(shader->textureflags & Q3TEXTUREFLAG_WATERSHADER)
-                               shader->textureflags &= ~Q3TEXTUREFLAG_REFLECTION;
+                               shader->textureflags &= ~(Q3TEXTUREFLAG_REFRACTION | Q3TEXTUREFLAG_REFLECTION);
                }
                Mem_Free(f);
        }
@@ -1640,6 +1641,8 @@ qboolean Mod_LoadTextureFromQ3Shader(texture_t *texture, const char *name, qbool
                        texture->basematerialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE;
                if (shader->textureflags & Q3TEXTUREFLAG_POLYGONOFFSET)
                        texture->basepolygonoffset -= 2;
+               if (shader->textureflags & Q3TEXTUREFLAG_REFRACTION)
+                       texture->basematerialflags |= MATERIALFLAG_REFRACTION;
                if (shader->textureflags & Q3TEXTUREFLAG_REFLECTION)
                        texture->basematerialflags |= MATERIALFLAG_REFLECTION;
                if (shader->textureflags & Q3TEXTUREFLAG_WATERSHADER)
@@ -1725,11 +1728,12 @@ nothing                GL_ZERO GL_ONE
                        }
                }
                memcpy(texture->deforms, shader->deforms, sizeof(texture->deforms));
-               texture->refractmin = shader->refractmin;
-               texture->refractmax = shader->refractmax;
+               texture->reflectmin = shader->reflectmin;
+               texture->reflectmax = shader->reflectmax;
                texture->refractfactor = shader->refractfactor;
-               VectorCopy(shader->reflectcolor, texture->reflectcolor);
-               VectorCopy(shader->refractcolor, texture->refractcolor);
+               Vector4Copy(shader->refractcolor4f, texture->refractcolor4f);
+               texture->reflectfactor = shader->reflectfactor;
+               Vector4Copy(shader->reflectcolor4f, texture->reflectcolor4f);
        }
        else if (!strcmp(texture->name, "noshader"))
        {
index 058073f..7c81f0a 100644 (file)
@@ -187,8 +187,9 @@ shadowmesh_t;
 #define Q3TEXTUREFLAG_TWOSIDED 1
 #define Q3TEXTUREFLAG_NOPICMIP 16
 #define Q3TEXTUREFLAG_POLYGONOFFSET 32
-#define Q3TEXTUREFLAG_REFLECTION 256
-#define Q3TEXTUREFLAG_WATERSHADER 512
+#define Q3TEXTUREFLAG_REFRACTION 256
+#define Q3TEXTUREFLAG_REFLECTION 512
+#define Q3TEXTUREFLAG_WATERSHADER 1024
 
 #define Q3PATHLENGTH 64
 #define TEXTURE_MAXFRAMES 64
@@ -365,10 +366,12 @@ typedef struct q3shaderinfo_s
        char skyboxname[Q3PATHLENGTH];
        q3shaderinfo_deform_t deforms[Q3MAXDEFORMS];
 
-       vec3_t reflectcolor, refractcolor;
-       float refractmin; // when refraction is used, minimum amount of reflection (when looking straight down)
-       float refractmax; // when refraction is used, maximum amount of reflection (when looking parallel to water)
-       float refractfactor; // amount of refraction distort (1.0 = like the cvar specifies; note that reflection distort is not configurable because that's what the bumpmap should do)
+       float reflectmin; // when refraction is used, minimum amount of reflection (when looking straight down)
+       float reflectmax; // when refraction is used, maximum amount of reflection (when looking parallel to water)
+       float refractfactor; // amount of refraction distort (1.0 = like the cvar specifies)
+       vec4_t refractcolor4f; // color tint of refraction (including alpha factor)
+       float reflectfactor; // amount of reflection distort (1.0 = like the cvar specifies)
+       vec4_t reflectcolor4f; // color tint of reflection (including alpha factor)
 }
 q3shaderinfo_t;
 
@@ -483,10 +486,12 @@ typedef struct texture_s
        int textureflags;
 
        // reflection
-       vec3_t reflectcolor, refractcolor;
-       float refractmin; // when refraction is used, minimum amount of reflection (when looking straight down)
-       float refractmax; // when refraction is used, maximum amount of reflection (when looking parallel to water)
-       float refractfactor; // amount of refraction distort (1.0 = like the cvar specifies; note that reflection distort is not configurable because that's what the bumpmap should do)
+       float reflectmin; // when refraction is used, minimum amount of reflection (when looking straight down)
+       float reflectmax; // when refraction is used, maximum amount of reflection (when looking parallel to water)
+       float refractfactor; // amount of refraction distort (1.0 = like the cvar specifies)
+       vec4_t refractcolor4f; // color tint of refraction (including alpha factor)
+       float reflectfactor; // amount of reflection distort (1.0 = like the cvar specifies)
+       vec4_t reflectcolor4f; // color tint of reflection (including alpha factor)
 }
 texture_t;
 
index 35e52c2..a1105ac 100644 (file)
--- a/render.h
+++ b/render.h
@@ -359,87 +359,7 @@ void R_DrawModelSurfaces(entity_render_t *ent, qboolean skysurfaces, qboolean wr
 void RSurf_PrepareVerticesForBatch(qboolean generatenormals, qboolean generatetangents, int texturenumsurfaces, msurface_t **texturesurfacelist);
 void RSurf_DrawBatch_Simple(int texturenumsurfaces, msurface_t **texturesurfacelist);
 
-#define SHADERPERMUTATION_MODE_LIGHTMAP (1<<0) // (lightmap) use directional pixel shading from fixed light direction (q3bsp)
-#define SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_MODELSPACE (1<<1) // (lightmap) use directional pixel shading from texture containing modelspace light directions (deluxemap)
-#define SHADERPERMUTATION_MODE_LIGHTDIRECTIONMAP_TANGENTSPACE (1<<2) // (lightmap) use directional pixel shading from texture containing tangentspace light directions (deluxemap)
-#define SHADERPERMUTATION_MODE_LIGHTDIRECTION (1<<3) // (lightmap) use directional pixel shading from fixed light direction (q3bsp)
-#define SHADERPERMUTATION_MODE_LIGHTSOURCE (1<<4) // (lightsource) use directional pixel shading from light source (rtlight)
-#define SHADERPERMUTATION_WATER (1<<5) // normalmap-perturbed refraction of the background, performed behind the surface (the texture or material must be transparent to see it)
-#define SHADERPERMUTATION_REFLECTION (1<<6) // normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface
-#define SHADERPERMUTATION_GLOW (1<<7) // (lightmap) blend in an additive glow texture
-#define SHADERPERMUTATION_FOG (1<<8) // tint the color by fog color or black if using additive blend mode
-#define SHADERPERMUTATION_COLORMAPPING (1<<9) // indicates this is a colormapped skin
-#define SHADERPERMUTATION_DIFFUSE (1<<10) // (lightsource) whether to use directional shading
-#define SHADERPERMUTATION_CONTRASTBOOST (1<<11) // r_glsl_contrastboost boosts the contrast at low color levels (similar to gamma)
-#define SHADERPERMUTATION_SPECULAR (1<<12) // (lightsource or deluxemapping) render specular effects
-#define SHADERPERMUTATION_CUBEFILTER (1<<13) // (lightsource) use cubemap light filter
-#define SHADERPERMUTATION_OFFSETMAPPING (1<<14) // adjust texcoords to roughly simulate a displacement mapped surface
-#define SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING (1<<15) // adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!)
-
-#define SHADERPERMUTATION_MAX (1<<16) // how many permutations are possible
-#define SHADERPERMUTATION_MASK (SHADERPERMUTATION_MAX - 1) // mask of valid indexing bits for r_glsl_permutations[] array
-
-// these are additional flags used only by R_GLSL_CompilePermutation
-#define SHADERPERMUTATION_USES_VERTEXSHADER (1<<29)
-#define SHADERPERMUTATION_USES_GEOMETRYSHADER (1<<30)
-#define SHADERPERMUTATION_USES_FRAGMENTSHADER (1<<31)
-
-typedef struct r_glsl_permutation_s
-{
-       // indicates if we have tried compiling this permutation already
-       qboolean compiled;
-       // 0 if compilation failed
-       int program;
-       int loc_Texture_Normal;
-       int loc_Texture_Color;
-       int loc_Texture_Gloss;
-       int loc_Texture_Cube;
-       int loc_Texture_Attenuation;
-       int loc_Texture_FogMask;
-       int loc_Texture_Pants;
-       int loc_Texture_Shirt;
-       int loc_Texture_Lightmap;
-       int loc_Texture_Deluxemap;
-       int loc_Texture_Glow;
-       int loc_Texture_Refraction;
-       int loc_Texture_Reflection;
-       int loc_FogColor;
-       int loc_LightPosition;
-       int loc_EyePosition;
-       int loc_LightColor;
-       int loc_Color_Pants;
-       int loc_Color_Shirt;
-       int loc_FogRangeRecip;
-       int loc_AmbientScale;
-       int loc_DiffuseScale;
-       int loc_SpecularScale;
-       int loc_SpecularPower;
-       int loc_GlowScale;
-       int loc_SceneBrightness; // or: Scenebrightness * ContrastBoost
-       int loc_OffsetMapping_Scale;
-       int loc_AmbientColor;
-       int loc_DiffuseColor;
-       int loc_SpecularColor;
-       int loc_LightDir;
-       int loc_ContrastBoostCoeff; // 1 - 1/ContrastBoost
-       int loc_DistortScaleRefractReflect;
-       int loc_ScreenScaleRefractReflect;
-       int loc_ScreenCenterRefractReflect;
-       int loc_RefractColor;
-       int loc_ReflectColor;
-       int loc_ReflectFactor;
-       int loc_ReflectOffset;
-}
-r_glsl_permutation_t;
-
-// information about each possible shader permutation
-extern r_glsl_permutation_t r_glsl_permutations[SHADERPERMUTATION_MAX];
-// currently selected permutation
-extern r_glsl_permutation_t *r_glsl_permutation;
-
-void R_GLSL_CompilePermutation(const char *shaderfilename, int permutation);
 int R_SetupSurfaceShader(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale);
-void R_SwitchSurfaceShader(int permutation);
 
 #endif