]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
change R_Upload error from Host_error to Sys_Error, added texture name
[xonotic/darkplaces.git] / gl_rmain.c
index 71662b10bf878f9296413202d553b0ed8d561cb3..84a2974e629f992aa8226a41f0b1d57e2d6d1530 100644 (file)
@@ -573,55 +573,6 @@ static void R_BuildFogHeightTexture(void)
 //=======================================================================================================================================================
 
 static const char *builtinshaderstring =
-"/* The engine may define the following macros:\n"
-"#define VERTEX_SHADER\n"
-"#define GEOMETRY_SHADER\n"
-"#define FRAGMENT_SHADER\n"
-"#define MODE_GENERIC\n"
-"#define MODE_POSTPROCESS\n"
-"#define MODE_DEPTH_OR_SHADOW\n"
-"#define MODE_FLATCOLOR\n"
-"#define MODE_VERTEXCOLOR\n"
-"#define MODE_LIGHTMAP\n"
-"#define MODE_LIGHTDIRECTIONMAP_MODELSPACE\n"
-"#define MODE_LIGHTDIRECTIONMAP_TANGENTSPACE\n"
-"#define MODE_LIGHTDIRECTION\n"
-"#define MODE_LIGHTSOURCE\n"
-"#define MODE_REFRACTION\n"
-"#define MODE_WATER\n"
-"#define MODE_SHOWDEPTH\n"
-"#define MODE_DEFERREDGEOMETRY\n"
-"#define MODE_DEFERREDLIGHTSOURCE\n"
-"#define USEDIFFUSE\n"
-"#define USEVERTEXTEXTUREBLEND\n"
-"#define USEVIEWTINT\n"
-"#define USECOLORMAPPING\n"
-"#define USESATURATION\n"
-"#define USEFOGINSIDE\n"
-"#define USEFOGOUTSIDE\n"
-"#define USEFOGHEIGHTTEXTURE\n"
-"#define USEGAMMARAMPS\n"
-"#define USECUBEFILTER\n"
-"#define USEGLOW\n"
-"#define USEBLOOM\n"
-"#define USESPECULAR\n"
-"#define USEPOSTPROCESSING\n"
-"#define USEEXACTSPECULARMATH\n"
-"#define USEREFLECTION\n"
-"#define USEOFFSETMAPPING\n"
-"#define USEOFFSETMAPPING_RELIEFMAPPING\n"
-"#define USESHADOWMAPRECT\n"
-"#define USESHADOWMAPCUBE\n"
-"#define USESHADOWMAP2D\n"
-"#define USESHADOWMAPPCF 1\n"
-"#define USESHADOWMAPPCF 2\n"
-"#define USESHADOWSAMPLER\n"
-"#define USESHADOWMAPVSDCT\n"
-"#define USESHADOWMAPORTHO\n"
-"#define USEDEFERREDLIGHTMAP\n"
-"#define USEALPHAKILL\n"
-"#define USEREFLECTCUBE\n"
-"*/\n"
 "// ambient+diffuse+specular+normalmap+attenuation+cubemap+fog shader\n"
 "// written by Forest 'LordHavoc' Hale\n"
 "// shadowmapping enhancements by Lee 'eihrul' Salzman\n"
@@ -4749,8 +4700,8 @@ static char *R_HLSL_GetText(const char *filename, qboolean printfromdisknotice)
 }
 
 #include <d3dx9.h>
-#include <d3dx9mesh.h>
-#pragma comment(lib, "d3dx9.lib")
+//#include <d3dx9shader.h>
+//#include <d3dx9mesh.h>
 
 static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, const char *vertstring, const char *fragstring)
 {
@@ -4776,42 +4727,79 @@ static void R_HLSL_CacheShader(r_hlsl_permutation_t *p, const char *cachename, c
        psbin = (DWORD *)FS_LoadFile(va("%s.psbin", cachename), r_main_mempool, true, &psbinsize);
        if ((!vsbin && vertstring) || (!psbin && fragstring))
        {
-               vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
-               psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
-               if (vertstring && vertstring[0])
-               {
-                       vsresult = D3DXCompileShader(vertstring, strlen(vertstring), NULL, NULL, "main", vsversion, 0, &vsbuffer, &vslog, &vsconstanttable);
-                       if (vsbuffer)
-                       {
-                               vsbinsize = vsbuffer->GetBufferSize();
-                               vsbin = (DWORD *)Mem_Alloc(tempmempool, vsbinsize);
-                               memcpy(vsbin, vsbuffer->GetBufferPointer(), vsbinsize);
-                               vsbuffer->Release();
-                       }
-                       if (vslog)
-                       {
-                               strlcpy(temp, (const char *)vslog->GetBufferPointer(), min(sizeof(temp), vslog->GetBufferSize()));
-                               Con_Printf("HLSL vertex shader compile output for %s follows:\n%s\n", cachename, temp);
-                               vslog->Release();
-                       }
-               }
-               if (fragstring && fragstring[0])
-               {
-                       psresult = D3DXCompileShader(fragstring, strlen(fragstring), NULL, NULL, "main", psversion, 0, &psbuffer, &pslog, &psconstanttable);
-                       if (psbuffer)
+               const char* dllnames_d3dx9 [] =
+               {
+                       "d3dx9_43.dll",
+                       "d3dx9_42.dll",
+                       "d3dx9_41.dll",
+                       "d3dx9_40.dll",
+                       "d3dx9_39.dll",
+                       "d3dx9_38.dll",
+                       "d3dx9_37.dll",
+                       "d3dx9_36.dll",
+                       "d3dx9_35.dll",
+                       "d3dx9_34.dll",
+                       "d3dx9_33.dll",
+                       "d3dx9_32.dll",
+                       "d3dx9_31.dll",
+                       "d3dx9_30.dll",
+                       "d3dx9_29.dll",
+                       "d3dx9_28.dll",
+                       "d3dx9_27.dll",
+                       "d3dx9_26.dll",
+                       "d3dx9_25.dll",
+                       "d3dx9_24.dll",
+                       NULL
+               };
+               dllhandle_t d3dx9_dll = NULL;
+               HRESULT WINAPI (*qD3DXCompileShader)(LPCSTR pSrcData, UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPCSTR pFunctionName, LPCSTR pProfile, DWORD Flags, LPD3DXBUFFER* ppShader, LPD3DXBUFFER* ppErrorMsgs, LPD3DXCONSTANTTABLE* ppConstantTable);
+               dllfunction_t d3dx9_dllfuncs[] =
+               {
+                       {"D3DXCompileShader",                   (void **) &qD3DXCompileShader},
+                       {NULL, NULL}
+               };
+               if (Sys_LoadLibrary(dllnames_d3dx9, &d3dx9_dll, d3dx9_dllfuncs))
+               {
+                       vsbin = (DWORD *)Mem_Realloc(tempmempool, vsbin, 0);
+                       psbin = (DWORD *)Mem_Realloc(tempmempool, psbin, 0);
+                       if (vertstring && vertstring[0])
                        {
-                               psbinsize = psbuffer->GetBufferSize();
-                               psbin = (DWORD *)Mem_Alloc(tempmempool, psbinsize);
-                               memcpy(psbin, psbuffer->GetBufferPointer(), psbinsize);
-                               psbuffer->Release();
+                               vsresult = qD3DXCompileShader(vertstring, strlen(vertstring), NULL, NULL, "main", vsversion, 0, &vsbuffer, &vslog, &vsconstanttable);
+                               if (vsbuffer)
+                               {
+                                       vsbinsize = vsbuffer->GetBufferSize();
+                                       vsbin = (DWORD *)Mem_Alloc(tempmempool, vsbinsize);
+                                       memcpy(vsbin, vsbuffer->GetBufferPointer(), vsbinsize);
+                                       vsbuffer->Release();
+                               }
+                               if (vslog)
+                               {
+                                       strlcpy(temp, (const char *)vslog->GetBufferPointer(), min(sizeof(temp), vslog->GetBufferSize()));
+                                       Con_Printf("HLSL vertex shader compile output for %s follows:\n%s\n", cachename, temp);
+                                       vslog->Release();
+                               }
                        }
-                       if (pslog)
+                       if (fragstring && fragstring[0])
                        {
-                               strlcpy(temp, (const char *)pslog->GetBufferPointer(), min(sizeof(temp), pslog->GetBufferSize()));
-                               Con_Printf("HLSL pixel shader compile output for %s follows:\n%s\n", cachename, temp);
-                               pslog->Release();
+                               psresult = qD3DXCompileShader(fragstring, strlen(fragstring), NULL, NULL, "main", psversion, 0, &psbuffer, &pslog, &psconstanttable);
+                               if (psbuffer)
+                               {
+                                       psbinsize = psbuffer->GetBufferSize();
+                                       psbin = (DWORD *)Mem_Alloc(tempmempool, psbinsize);
+                                       memcpy(psbin, psbuffer->GetBufferPointer(), psbinsize);
+                                       psbuffer->Release();
+                               }
+                               if (pslog)
+                               {
+                                       strlcpy(temp, (const char *)pslog->GetBufferPointer(), min(sizeof(temp), pslog->GetBufferSize()));
+                                       Con_Printf("HLSL pixel shader compile output for %s follows:\n%s\n", cachename, temp);
+                                       pslog->Release();
+                               }
                        }
+                       Sys_UnloadLibrary(&d3dx9_dll);
                }
+               else
+                       Con_Printf("Unable to compile shader - D3DXCompileShader function not found\n");
        }
        if (vsbin)
        {
@@ -5308,6 +5296,101 @@ extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture;
 extern rtexture_t *r_shadow_prepasslightingdiffusetexture;
 extern rtexture_t *r_shadow_prepasslightingspeculartexture;
 extern cvar_t gl_mesh_separatearrays;
+static qboolean R_BlendFuncAllowsColormod(int src, int dst)
+{
+       // a blendfunc allows colormod if:
+       // a) it can never keep the destination pixel invariant, or
+       // b) it can keep the destination pixel invariant, and still can do so if colormodded
+       // this is to prevent unintended side effects from colormod
+
+       // in formulas:
+       // IF there is a (s, sa) for which for all (d, da),
+       //   s * src(s, d, sa, da) + d * dst(s, d, sa, da) == d
+       // THEN, for this (s, sa) and all (colormod, d, da):
+       //   s*colormod * src(s*colormod, d, sa, da) + d * dst(s*colormod, d, sa, da) == d
+       // OBVIOUSLY, this means that
+       //   s*colormod * src(s*colormod, d, sa, da) = 0
+       //   dst(s*colormod, d, sa, da)              = 1
+
+       // note: not caring about GL_SRC_ALPHA_SATURATE and following here, these are unused in DP code
+
+       // main condition to leave dst color invariant:
+       //   s * src(s, d, sa, da) + d * dst(s, d, sa, da) == d
+       //   src == GL_ZERO:
+       //     s * 0 + d * dst(s, d, sa, da) == d
+       //       => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
+       //       => colormod is a problem for GL_SRC_COLOR only
+       //   src == GL_ONE:
+       //     s + d * dst(s, d, sa, da) == d
+       //       => s == 0
+       //       => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
+       //       => colormod is never problematic for these
+       //   src == GL_SRC_COLOR:
+       //     s*s + d * dst(s, d, sa, da) == d
+       //       => s == 0
+       //       => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
+       //       => colormod is never problematic for these
+       //   src == GL_ONE_MINUS_SRC_COLOR:
+       //     s*(1-s) + d * dst(s, d, sa, da) == d
+       //       => s == 0 or s == 1
+       //       => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
+       //       => colormod is a problem for GL_SRC_COLOR only
+       //   src == GL_DST_COLOR
+       //     s*d + d * dst(s, d, sa, da) == d
+       //       => s == 1
+       //       => dst == GL_ZERO/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
+       //       => colormod is always a problem
+       //     or
+       //       => s == 0
+       //       => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
+       //       => colormod is never problematic for these
+       //       => BUT, we do not know s! We must assume it is problematic
+       //       then... except in GL_ONE case, where we know all invariant
+       //       cases are fine
+       //   src == GL_ONE_MINUS_DST_COLOR
+       //     s*(1-d) + d * dst(s, d, sa, da) == d
+       //       => s == 0 (1-d is impossible to handle for our desired result)
+       //       => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
+       //       => colormod is never problematic for these
+       //   src == GL_SRC_ALPHA
+       //     s*sa + d * dst(s, d, sa, da) == d
+       //       => s == 0, or sa == 0
+       //       => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
+       //       => colormod breaks in the case GL_SRC_COLOR only
+       //   src == GL_ONE_MINUS_SRC_ALPHA
+       //     s*(1-sa) + d * dst(s, d, sa, da) == d
+       //       => s == 0, or sa == 1
+       //       => dst == GL_ONE/GL_SRC_COLOR/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
+       //       => colormod breaks in the case GL_SRC_COLOR only
+       //   src == GL_DST_ALPHA
+       //     s*da + d * dst(s, d, sa, da) == d
+       //       => s == 0
+       //       => dst == GL_ONE/GL_ONE_MINUS_SRC_COLOR/GL_SRC_ALPHA/GL_ONE_MINUS_SRC_ALPHA
+       //       => colormod is never problematic for these
+
+       switch(src)
+       {
+               case GL_ZERO:
+               case GL_ONE_MINUS_SRC_COLOR:
+               case GL_SRC_ALPHA:
+               case GL_ONE_MINUS_SRC_ALPHA:
+                       if(dst == GL_SRC_COLOR)
+                               return false;
+                       return true;
+               case GL_ONE:
+               case GL_SRC_COLOR:
+               case GL_ONE_MINUS_DST_COLOR:
+               case GL_DST_ALPHA:
+               case GL_ONE_MINUS_DST_ALPHA:
+                       return true;
+               case GL_DST_COLOR:
+                       if(dst == GL_ONE)
+                               return true;
+                       return false;
+               default:
+                       return false;
+       }
+}
 void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *surfacewaterplane)
 {
        // select a permutation of the lighting shader appropriate to this
@@ -5316,6 +5399,9 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
        // fragment shader on features that are not being used
        unsigned int permutation = 0;
        unsigned int mode = 0;
+       qboolean allow_colormod;
+       static float dummy_colormod[3] = {1, 1, 1};
+       float *colormod = rsurface.colormod;
        float m16f[16];
        r_waterstate_waterplane_t *waterplane = (r_waterstate_waterplane_t *)surfacewaterplane;
        if (rsurfacepass == RSURFPASS_BACKGROUND)
@@ -5332,6 +5418,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                }
                GL_AlphaTest(false);
                GL_BlendFunc(GL_ONE, GL_ZERO);
+               allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
        }
        else if (rsurfacepass == RSURFPASS_DEFERREDGEOMETRY)
        {
@@ -5358,6 +5445,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_VERTEXTEXTUREBLEND;
                GL_AlphaTest(false);
                GL_BlendFunc(GL_ONE, GL_ZERO);
+               allow_colormod = R_BlendFuncAllowsColormod(GL_ONE, GL_ZERO);
        }
        else if (rsurfacepass == RSURFPASS_RTLIGHT)
        {
@@ -5416,6 +5504,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_REFLECTCUBE;
                GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
                GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
+               allow_colormod = R_BlendFuncAllowsColormod(GL_SRC_ALPHA, GL_ONE);
        }
        else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
        {
@@ -5464,6 +5553,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_REFLECTCUBE;
                GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
                GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+               allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
        }
        else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT_DIRECTIONAL)
        {
@@ -5520,6 +5610,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_REFLECTCUBE;
                GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
                GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+               allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
        }
        else if (rsurface.texture->currentmaterialflags & MATERIALFLAG_MODELLIGHT)
        {
@@ -5569,6 +5660,7 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        permutation |= SHADERPERMUTATION_REFLECTCUBE;
                GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
                GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+               allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
        }
        else
        {
@@ -5654,7 +5746,10 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                }
                GL_AlphaTest((rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST) != 0);
                GL_BlendFunc(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
+               allow_colormod = R_BlendFuncAllowsColormod(rsurface.texture->currentlayers[0].blendfunc1, rsurface.texture->currentlayers[0].blendfunc2);
        }
+       if(!allow_colormod)
+               colormod = dummy_colormod;
        switch(vid.renderpath)
        {
        case RENDERPATH_D3D9:
@@ -5685,8 +5780,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                {
                        hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
                        hlslPSSetParameter3f(D3DPSREGISTER_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
-                       hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, rsurface.colormod[0] * ambientscale, rsurface.colormod[1] * ambientscale, rsurface.colormod[2] * ambientscale);
-                       hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.colormod[0] * diffusescale, rsurface.colormod[1] * diffusescale, rsurface.colormod[2] * diffusescale);
+                       hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
+                       hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
                        hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
 
                        // additive passes are only darkened by fog, not tinted
@@ -5697,24 +5792,24 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                {
                        if (mode == SHADERMODE_FLATCOLOR)
                        {
-                               hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2]);
+                               hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, colormod[0], colormod[1], colormod[2]);
                        }
                        else if (mode == SHADERMODE_LIGHTDIRECTION)
                        {
-                               hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * rsurface.colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * rsurface.colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * rsurface.colormod[2]);
-                               hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * rsurface.colormod[0], r_refdef.lightmapintensity * rsurface.colormod[1], r_refdef.lightmapintensity * rsurface.colormod[2]);
+                               hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * colormod[2]);
+                               hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
                                hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
-                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, rsurface.colormod[0] * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * r_shadow_deferred_8bitrange.value);
+                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);
                                hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
                                hlslPSSetParameter3f(D3DPSREGISTER_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
                                hlslPSSetParameter3f(D3DPSREGISTER_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
                        }
                        else
                        {
-                               hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * rsurface.colormod[0], r_refdef.scene.ambient * rsurface.colormod[1], r_refdef.scene.ambient * rsurface.colormod[2]);
+                               hlslPSSetParameter3f(D3DPSREGISTER_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
                                hlslPSSetParameter3f(D3DPSREGISTER_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
                                hlslPSSetParameter3f(D3DPSREGISTER_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
-                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, rsurface.colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
+                               hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
                                hlslPSSetParameter3f(D3DPSREGISTER_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
                        }
                        // additive passes are only darkened by fog, not tinted
@@ -5772,8 +5867,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (rsurfacepass == RSURFPASS_BACKGROUND)
                {
                        R_Mesh_TexBind(GL20TU_REFRACTION        , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
+                       if(mode == SHADERMODE_GENERIC) R_Mesh_TexBind(GL20TU_FIRST             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
                        R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
-                       R_Mesh_TexBind(GL20TU_FIRST             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
                }
                else
                {
@@ -5824,8 +5919,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                        if (r_glsl_permutation->loc_ModelToLight >= 0) {Matrix4x4_ToArrayFloatGL(&rsurface.entitytolight, m16f);qglUniformMatrix4fvARB(r_glsl_permutation->loc_ModelToLight, 1, false, m16f);}
                        if (r_glsl_permutation->loc_LightPosition >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);
                        if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);
-                       if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, rsurface.colormod[0] * ambientscale, rsurface.colormod[1] * ambientscale, rsurface.colormod[2] * ambientscale);
-                       if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, rsurface.colormod[0] * diffusescale, rsurface.colormod[1] * diffusescale, rsurface.colormod[2] * diffusescale);
+                       if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);
+                       if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);
                        if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);
        
                        // additive passes are only darkened by fog, not tinted
@@ -5837,24 +5932,24 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                {
                        if (mode == SHADERMODE_FLATCOLOR)
                        {
-                               if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2]);
+                               if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, colormod[0], colormod[1], colormod[2]);
                        }
                        else if (mode == SHADERMODE_LIGHTDIRECTION)
                        {
-                               if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * rsurface.colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * rsurface.colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * rsurface.colormod[2]);
-                               if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity * rsurface.colormod[0], r_refdef.lightmapintensity * rsurface.colormod[1], r_refdef.lightmapintensity * rsurface.colormod[2]);
+                               if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * colormod[2]);
+                               if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);
                                if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
-                               if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Diffuse, rsurface.colormod[0] * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * r_shadow_deferred_8bitrange.value);
+                               if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);
                                if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
                                if (r_glsl_permutation->loc_LightColor >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);
                                if (r_glsl_permutation->loc_LightDir >= 0) qglUniform3fARB(r_glsl_permutation->loc_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);
                        }
                        else
                        {
-                               if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * rsurface.colormod[0], r_refdef.scene.ambient * rsurface.colormod[1], r_refdef.scene.ambient * rsurface.colormod[2]);
+                               if (r_glsl_permutation->loc_Color_Ambient >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);
                                if (r_glsl_permutation->loc_Color_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);
                                if (r_glsl_permutation->loc_Color_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);
-                               if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Diffuse, rsurface.colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
+                               if (r_glsl_permutation->loc_DeferredMod_Diffuse >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);
                                if (r_glsl_permutation->loc_DeferredMod_Specular >= 0) qglUniform3fARB(r_glsl_permutation->loc_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);
                        }
                        // additive passes are only darkened by fog, not tinted
@@ -5927,9 +6022,9 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (r_glsl_permutation->loc_Texture_Attenuation     >= 0) R_Mesh_TexBind(GL20TU_ATTENUATION       , r_shadow_attenuationgradienttexture                 );
                if (rsurfacepass == RSURFPASS_BACKGROUND)
                {
-                       R_Mesh_TexBind(GL20TU_REFRACTION        , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
-                       R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
-                       R_Mesh_TexBind(GL20TU_FIRST             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
+                       if(r_glsl_permutation->loc_Texture_Refraction >= 0) R_Mesh_TexBind(GL20TU_REFRACTION        , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);
+                       else if(r_glsl_permutation->loc_Texture_First >= 0) R_Mesh_TexBind(GL20TU_FIRST             , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);
+                       if(r_glsl_permutation->loc_Texture_Reflection >= 0) R_Mesh_TexBind(GL20TU_REFLECTION        , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);
                }
                else
                {
@@ -5996,8 +6091,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                {
                        if (r_cg_permutation->fp_LightPosition) cgGLSetParameter3f(r_cg_permutation->fp_LightPosition, rsurface.entitylightorigin[0], rsurface.entitylightorigin[1], rsurface.entitylightorigin[2]);CHECKCGERROR
                        if (r_cg_permutation->fp_LightColor) cgGLSetParameter3f(r_cg_permutation->fp_LightColor, lightcolorbase[0], lightcolorbase[1], lightcolorbase[2]);CHECKCGERROR
-                       if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, rsurface.colormod[0] * ambientscale, rsurface.colormod[1] * ambientscale, rsurface.colormod[2] * ambientscale);CHECKCGERROR
-                       if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, rsurface.colormod[0] * diffusescale, rsurface.colormod[1] * diffusescale, rsurface.colormod[2] * diffusescale);CHECKCGERROR
+                       if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, colormod[0] * ambientscale, colormod[1] * ambientscale, colormod[2] * ambientscale);CHECKCGERROR
+                       if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, colormod[0] * diffusescale, colormod[1] * diffusescale, colormod[2] * diffusescale);CHECKCGERROR
                        if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale, r_refdef.view.colorscale * specularscale);CHECKCGERROR
 
                        // additive passes are only darkened by fog, not tinted
@@ -6008,24 +6103,24 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                {
                        if (mode == SHADERMODE_FLATCOLOR)
                        {
-                               if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, rsurface.colormod[0], rsurface.colormod[1], rsurface.colormod[2]);CHECKCGERROR
+                               if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, colormod[0], colormod[1], colormod[2]);CHECKCGERROR
                        }
                        else if (mode == SHADERMODE_LIGHTDIRECTION)
                        {
-                               if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * rsurface.colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * rsurface.colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * rsurface.colormod[2]);CHECKCGERROR
-                               if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, r_refdef.lightmapintensity * rsurface.colormod[0], r_refdef.lightmapintensity * rsurface.colormod[1], r_refdef.lightmapintensity * rsurface.colormod[2]);CHECKCGERROR
+                               if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, (r_refdef.scene.ambient + rsurface.modellight_ambient[0] * r_refdef.lightmapintensity) * colormod[0], (r_refdef.scene.ambient + rsurface.modellight_ambient[1] * r_refdef.lightmapintensity) * colormod[1], (r_refdef.scene.ambient + rsurface.modellight_ambient[2] * r_refdef.lightmapintensity) * colormod[2]);CHECKCGERROR
+                               if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, r_refdef.lightmapintensity * colormod[0], r_refdef.lightmapintensity * colormod[1], r_refdef.lightmapintensity * colormod[2]);CHECKCGERROR
                                if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);CHECKCGERROR
-                               if (r_cg_permutation->fp_DeferredMod_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, rsurface.colormod[0] * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * r_shadow_deferred_8bitrange.value);CHECKCGERROR
+                               if (r_cg_permutation->fp_DeferredMod_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, colormod[0] * r_shadow_deferred_8bitrange.value, colormod[1] * r_shadow_deferred_8bitrange.value, colormod[2] * r_shadow_deferred_8bitrange.value);CHECKCGERROR
                                if (r_cg_permutation->fp_DeferredMod_Specular) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);CHECKCGERROR
                                if (r_cg_permutation->fp_LightColor) cgGLSetParameter3f(r_cg_permutation->fp_LightColor, rsurface.modellight_diffuse[0], rsurface.modellight_diffuse[1], rsurface.modellight_diffuse[2]);CHECKCGERROR
                                if (r_cg_permutation->fp_LightDir) cgGLSetParameter3f(r_cg_permutation->fp_LightDir, rsurface.modellight_lightdir[0], rsurface.modellight_lightdir[1], rsurface.modellight_lightdir[2]);CHECKCGERROR
                        }
                        else
                        {
-                               if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, r_refdef.scene.ambient * rsurface.colormod[0], r_refdef.scene.ambient * rsurface.colormod[1], r_refdef.scene.ambient * rsurface.colormod[2]);CHECKCGERROR
+                               if (r_cg_permutation->fp_Color_Ambient) cgGLSetParameter3f(r_cg_permutation->fp_Color_Ambient, r_refdef.scene.ambient * colormod[0], r_refdef.scene.ambient * colormod[1], r_refdef.scene.ambient * colormod[2]);CHECKCGERROR
                                if (r_cg_permutation->fp_Color_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_Color_Diffuse, rsurface.texture->lightmapcolor[0], rsurface.texture->lightmapcolor[1], rsurface.texture->lightmapcolor[2]);CHECKCGERROR
                                if (r_cg_permutation->fp_Color_Specular) cgGLSetParameter3f(r_cg_permutation->fp_Color_Specular, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale, r_refdef.lightmapintensity * r_refdef.view.colorscale * specularscale);CHECKCGERROR
-                               if (r_cg_permutation->fp_DeferredMod_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, rsurface.colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, rsurface.colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);CHECKCGERROR
+                               if (r_cg_permutation->fp_DeferredMod_Diffuse) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Diffuse, colormod[0] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[1] * diffusescale * r_shadow_deferred_8bitrange.value, colormod[2] * diffusescale * r_shadow_deferred_8bitrange.value);CHECKCGERROR
                                if (r_cg_permutation->fp_DeferredMod_Specular) cgGLSetParameter3f(r_cg_permutation->fp_DeferredMod_Specular, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value, specularscale * r_shadow_deferred_8bitrange.value);CHECKCGERROR
                        }
                        // additive passes are only darkened by fog, not tinted
@@ -6098,8 +6193,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting,
                if (rsurfacepass == RSURFPASS_BACKGROUND)
                {
                        if (r_cg_permutation->fp_Texture_Refraction     ) CG_BindTexture(r_cg_permutation->fp_Texture_Refraction     , waterplane->texture_refraction ? waterplane->texture_refraction : r_texture_black);CHECKCGERROR
+                       else if (r_cg_permutation->fp_Texture_First     ) CG_BindTexture(r_cg_permutation->fp_Texture_First          , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);CHECKCGERROR
                        if (r_cg_permutation->fp_Texture_Reflection     ) CG_BindTexture(r_cg_permutation->fp_Texture_Reflection     , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black);CHECKCGERROR
-                       if (r_cg_permutation->fp_Texture_First          ) CG_BindTexture(r_cg_permutation->fp_Texture_First          , waterplane->texture_camera ? waterplane->texture_camera : r_texture_black);CHECKCGERROR
                }
                else
                {
@@ -6499,7 +6594,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        {
                basepixels_width = image_width;
                basepixels_height = image_height;
-               skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL);
+               skinframe->base = R_LoadTexture2D (r_main_texturepool, skinframe->basename, basepixels_width, basepixels_height, basepixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL);
                if (textureflags & TEXF_ALPHA)
                {
                        for (j = 3;j < basepixels_width * basepixels_height * 4;j += 4)
@@ -6521,23 +6616,23 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
                                        pixels[j+2] = 255;
                                        pixels[j+3] = basepixels[j+3];
                                }
-                               skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL);
+                               skinframe->fog = R_LoadTexture2D (r_main_texturepool, va("%s_mask", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), miplevel, NULL);
                                Mem_Free(pixels);
                        }
                }
                R_SKINFRAME_LOAD_AVERAGE_COLORS(basepixels_width * basepixels_height, basepixels[4 * pix + comp]);
                //Con_Printf("Texture %s has average colors %f %f %f alpha %f\n", name, skinframe->avgcolor[0], skinframe->avgcolor[1], skinframe->avgcolor[2], skinframe->avgcolor[3]);
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->base)
-                       R_SaveTextureDDSFile(skinframe->base, va("dds/%s.dds", skinframe->basename), true);
+                       R_SaveTextureDDSFile(skinframe->base, va("dds/%s.dds", skinframe->basename), true, skinframe->hasalpha);
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->fog)
-                       R_SaveTextureDDSFile(skinframe->fog, va("dds/%s_mask.dds", skinframe->basename), true);
+                       R_SaveTextureDDSFile(skinframe->fog, va("dds/%s_mask.dds", skinframe->basename), true, true);
        }
 
        if (r_loaddds)
        {
                mymiplevel = savemiplevel;
                if (r_loadnormalmap)
-                       skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_norm.dds", skinframe->basename), textureflags | TEXF_ALPHA, NULL, NULL, mymiplevel);
+                       skinframe->nmap = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_norm.dds", skinframe->basename), (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), NULL, NULL, mymiplevel);
                skinframe->glow = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_glow.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
                if (r_loadgloss)
                        skinframe->gloss = R_LoadTextureDDSFile(r_main_texturepool, va("dds/%s_gloss.dds", skinframe->basename), textureflags, NULL, NULL, mymiplevel);
@@ -6552,7 +6647,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
                mymiplevel = savemiplevel;
                if ((pixels = loadimagepixelsbgra(va("%s_norm", skinframe->basename), false, false, false, &mymiplevel)) != NULL)
                {
-                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                        Mem_Free(pixels);
                        pixels = NULL;
                }
@@ -6560,7 +6655,7 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
                {
                        pixels = (unsigned char *)Mem_Alloc(tempmempool, image_width * image_height * 4);
                        Image_HeightmapToNormalmap_BGRA(bumppixels, pixels, image_width, image_height, false, r_shadow_bumpscale_bumpmap.value);
-                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                        Mem_Free(pixels);
                        Mem_Free(bumppixels);
                }
@@ -6568,11 +6663,11 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
                {
                        pixels = (unsigned char *)Mem_Alloc(tempmempool, basepixels_width * basepixels_height * 4);
                        Image_HeightmapToNormalmap_BGRA(basepixels, pixels, basepixels_width, basepixels_height, false, r_shadow_bumpscale_basetexture.value);
-                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | skinframe->textureflags) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+                       skinframe->nmap = R_LoadTexture2D (r_main_texturepool, va("%s_nmap", skinframe->basename), basepixels_width, basepixels_height, pixels, TEXTYPE_BGRA, (TEXF_ALPHA | textureflags) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP) & (gl_texturecompression_normal.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                        Mem_Free(pixels);
                }
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->nmap)
-                       R_SaveTextureDDSFile(skinframe->nmap, va("dds/%s_norm.dds", skinframe->basename), true);
+                       R_SaveTextureDDSFile(skinframe->nmap, va("dds/%s_norm.dds", skinframe->basename), true, true);
        }
 
        // _luma is supported only for tenebrae compatibility
@@ -6580,18 +6675,18 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        mymiplevel = savemiplevel;
        if (skinframe->glow == NULL && ((pixels = loadimagepixelsbgra(va("%s_glow",  skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)) || (pixels = loadimagepixelsbgra(va("%s_luma", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel))))
        {
-               skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+               skinframe->glow = R_LoadTexture2D (r_main_texturepool, va("%s_glow", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_glow.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->glow)
-                       R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), true);
+                       R_SaveTextureDDSFile(skinframe->glow, va("dds/%s_glow.dds", skinframe->basename), true, true);
                Mem_Free(pixels);pixels = NULL;
        }
 
        mymiplevel = savemiplevel;
        if (skinframe->gloss == NULL && r_loadgloss && (pixels = loadimagepixelsbgra(va("%s_gloss", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
        {
-               skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+               skinframe->gloss = R_LoadTexture2D (r_main_texturepool, va("%s_gloss", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_gloss.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->gloss)
-                       R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), true);
+                       R_SaveTextureDDSFile(skinframe->gloss, va("dds/%s_gloss.dds", skinframe->basename), true, true);
                Mem_Free(pixels);
                pixels = NULL;
        }
@@ -6599,9 +6694,9 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        mymiplevel = savemiplevel;
        if (skinframe->pants == NULL && (pixels = loadimagepixelsbgra(va("%s_pants", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
        {
-               skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+               skinframe->pants = R_LoadTexture2D (r_main_texturepool, va("%s_pants", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->pants)
-                       R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), true);
+                       R_SaveTextureDDSFile(skinframe->pants, va("dds/%s_pants.dds", skinframe->basename), true, false);
                Mem_Free(pixels);
                pixels = NULL;
        }
@@ -6609,9 +6704,9 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        mymiplevel = savemiplevel;
        if (skinframe->shirt == NULL && (pixels = loadimagepixelsbgra(va("%s_shirt", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
        {
-               skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+               skinframe->shirt = R_LoadTexture2D (r_main_texturepool, va("%s_shirt", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_color.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->shirt)
-                       R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), true);
+                       R_SaveTextureDDSFile(skinframe->shirt, va("dds/%s_shirt.dds", skinframe->basename), true, false);
                Mem_Free(pixels);
                pixels = NULL;
        }
@@ -6619,9 +6714,9 @@ skinframe_t *R_SkinFrame_LoadExternal(const char *name, int textureflags, qboole
        mymiplevel = savemiplevel;
        if (skinframe->reflect == NULL && (pixels = loadimagepixelsbgra(va("%s_reflect", skinframe->basename), false, false, r_texture_convertsRGB_skin.integer != 0, &mymiplevel)))
        {
-               skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, skinframe->textureflags & (gl_texturecompression_reflectmask.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
+               skinframe->reflect = R_LoadTexture2D (r_main_texturepool, va("%s_reflect", skinframe->basename), image_width, image_height, pixels, TEXTYPE_BGRA, textureflags & (gl_texturecompression_reflectmask.integer ? ~0 : ~TEXF_COMPRESS), mymiplevel, NULL);
                if (r_savedds && qglGetCompressedTexImageARB && skinframe->reflect)
-                       R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), true);
+                       R_SaveTextureDDSFile(skinframe->reflect, va("dds/%s_reflect.dds", skinframe->basename), true, true);
                Mem_Free(pixels);
                pixels = NULL;
        }
@@ -6671,10 +6766,10 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co
                temp1 = (unsigned char *)Mem_Alloc(tempmempool, width * height * 8);
                temp2 = temp1 + width * height * 4;
                Image_HeightmapToNormalmap_BGRA(skindata, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
-               skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, skinframe->textureflags | TEXF_ALPHA, -1, NULL);
+               skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
                Mem_Free(temp1);
        }
-       skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_BGRA, skinframe->textureflags, -1, NULL);
+       skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_BGRA, textureflags, -1, NULL);
        if (textureflags & TEXF_ALPHA)
        {
                for (i = 3;i < width * height * 4;i += 4)
@@ -6691,7 +6786,7 @@ skinframe_t *R_SkinFrame_LoadInternalBGRA(const char *name, int textureflags, co
                        memcpy(fogpixels, skindata, width * height * 4);
                        for (i = 0;i < width * height * 4;i += 4)
                                fogpixels[i] = fogpixels[i+1] = fogpixels[i+2] = 255;
-                       skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, skinframe->textureflags, -1, NULL);
+                       skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, fogpixels, TEXTYPE_BGRA, textureflags, -1, NULL);
                        Mem_Free(fogpixels);
                }
        }
@@ -6794,7 +6889,7 @@ static void R_SkinFrame_GenerateTexturesFromQPixels(skinframe_t *skinframe, qboo
                // use either a custom palette or the quake palette
                Image_Copy8bitBGRA(skindata, temp1, width * height, palette_bgra_complete);
                Image_HeightmapToNormalmap_BGRA(temp1, temp2, width, height, false, r_shadow_bumpscale_basetexture.value);
-               skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, skinframe->textureflags | TEXF_ALPHA, -1, NULL);
+               skinframe->nmap = R_LoadTexture2D(r_main_texturepool, va("%s_nmap", skinframe->basename), width, height, temp2, TEXTYPE_BGRA, (skinframe->textureflags | TEXF_ALPHA) & (r_mipnormalmaps.integer ? ~0 : ~TEXF_MIPMAP), -1, NULL);
                Mem_Free(temp1);
        }
 
@@ -6856,7 +6951,7 @@ skinframe_t *R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, co
        if (developer_loading.integer)
                Con_Printf("loading embedded 8bit image \"%s\"\n", name);
 
-       skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, -1, palette);
+       skinframe->base = skinframe->merged = R_LoadTexture2D(r_main_texturepool, skinframe->basename, width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, palette);
        if (textureflags & TEXF_ALPHA)
        {
                for (i = 0;i < width * height;i++)
@@ -6868,7 +6963,7 @@ skinframe_t *R_SkinFrame_LoadInternal8bit(const char *name, int textureflags, co
                        }
                }
                if (r_loadfog && skinframe->hasalpha)
-                       skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, skinframe->textureflags, -1, alphapalette);
+                       skinframe->fog = R_LoadTexture2D(r_main_texturepool, va("%s_fog", skinframe->basename), width, height, skindata, TEXTYPE_PALETTE, textureflags, -1, alphapalette);
        }
 
        R_SKINFRAME_LOAD_AVERAGE_COLORS(width * height, ((unsigned char *)palette)[skindata[pix]*4 + comp]);
@@ -6908,7 +7003,7 @@ skinframe_t *R_SkinFrame_LoadMissing(void)
 //static char *suffix[6] = {"ft", "bk", "rt", "lf", "up", "dn"};
 typedef struct suffixinfo_s
 {
-       char *suffix;
+       const char *suffix;
        qboolean flipx, flipy, flipdiagonal;
 }
 suffixinfo_t;
@@ -7937,7 +8032,7 @@ static void R_View_UpdateEntityVisible (void)
                {
                        ent = r_refdef.scene.entities[i];
                        if (!(ent->flags & renderimask))
-                       if (!R_CullBox(ent->mins, ent->maxs) || (ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
+                       if (!R_CullBox(ent->mins, ent->maxs) || (ent->model && ent->model->type == mod_sprite && (ent->model->sprite.sprnum_type == SPR_LABEL || ent->model->sprite.sprnum_type == SPR_LABEL_SCALE)))
                        if ((ent->flags & (RENDER_NODEPTHTEST | RENDER_VIEWMODEL)) || r_refdef.scene.worldmodel->brush.BoxTouchingVisibleLeafs(r_refdef.scene.worldmodel, r_refdef.viewcache.world_leafvisible, ent->mins, ent->maxs))
                                r_refdef.viewcache.entityvisible[i] = true;
                }
@@ -8817,6 +8912,11 @@ void R_Bloom_StartFrame(void)
 
        switch(vid.renderpath)
        {
+       case RENDERPATH_GL11:
+       case RENDERPATH_GL13:
+       case RENDERPATH_GL20:
+       case RENDERPATH_CGGL:
+               break;
        case RENDERPATH_D3D9:
        case RENDERPATH_D3D10:
        case RENDERPATH_D3D11:
@@ -10510,6 +10610,9 @@ texture_t *R_GetCurrentTexture(texture_t *t)
                        blendfunc1 = GL_ONE;
                        blendfunc2 = GL_ZERO;
                }
+               // don't colormod evilblend textures
+               if(!R_BlendFuncAllowsColormod(blendfunc1, blendfunc2))
+                       VectorSet(t->lightmapcolor, 1, 1, 1);
                depthmask = !(t->currentmaterialflags & MATERIALFLAG_BLENDED);
                if (t->currentmaterialflags & MATERIALFLAG_FULLBRIGHT)
                {
@@ -13327,7 +13430,7 @@ static void R_DecalSystem_SplatEntity(entity_render_t *ent, const vec3_t worldor
                return;
        }
 
-       if (!model->brush.data_nodes && !cl_decals_models.integer)
+       if (!model->brush.data_leafs && !cl_decals_models.integer)
        {
                if (decalsystem->model)
                        R_DecalSystem_Reset(decalsystem);