add back VorteX's "lightweight shader parameter" system, but have it detect cvar...
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 14 Oct 2010 06:14:59 +0000 (06:14 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Thu, 14 Oct 2010 06:14:59 +0000 (06:14 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10532 d7cf8633-e32d-0410-b094-e92efae38249

gl_rmain.c

index 44e3504..bda27f4 100644 (file)
@@ -189,6 +189,7 @@ cvar_t r_overheadsprites_perspective = {CVAR_SAVE, "r_overheadsprites_perspectiv
 cvar_t r_overheadsprites_pushback = {CVAR_SAVE, "r_overheadsprites_pushback", "16", "how far to pull the SPR_OVERHEAD sprites toward the eye (used to avoid intersections with 3D models)"};
 
 cvar_t r_glsl_saturation = {CVAR_SAVE, "r_glsl_saturation", "1", "saturation multiplier (only working in glsl!)"};
+cvar_t r_glsl_saturation_redcompensate = {CVAR_SAVE, "r_glsl_saturation_redcompensate", "0", "a 'vampire sight' addition to desaturation effect, does compensation for red color, r_glsl_restart is required"};
 
 cvar_t r_framedatasize = {CVAR_SAVE, "r_framedatasize", "1", "size of renderer data cache used during one frame (for skeletal animation caching, light processing, etc)"};
 
@@ -749,8 +750,16 @@ static const char *builtinshaderstring =
 "#ifdef USESATURATION\n"
 "      //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
 "      float y = dot(gl_FragColor.rgb, vec3(0.299, 0.587, 0.114));\n"
-"      //gl_FragColor = vec3(y) + (gl_FragColor.rgb - vec3(y)) * Saturation;\n"
-"      gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
+"      // 'vampire sight' effect, wheres red is compensated\n"
+"      #ifdef SATURATION_REDCOMPENSATE\n"
+"              float rboost = max(0.0, (gl_FragColor.r - max(gl_FragColor.g, gl_FragColor.b))*(1.0 - Saturation));\n"
+"              gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
+"              gl_FragColor.r += rboost;\n"
+"      #else\n"
+"              // normal desaturation\n"
+"              //gl_FragColor = vec3(y) + (gl_FragColor.rgb - vec3(y)) * Saturation;\n"
+"              gl_FragColor.rgb = mix(vec3(y), gl_FragColor.rgb, Saturation);\n"
+"      #endif\n"
 "#endif\n"
 "\n"
 "#ifdef USEGAMMARAMPS\n"
@@ -2003,8 +2012,16 @@ const char *builtincgshaderstring =
 "#ifdef USESATURATION\n"
 "      //apply saturation BEFORE gamma ramps, so v_glslgamma value does not matter\n"
 "      float y = dot(gl_FragColor.rgb, float3(0.299, 0.587, 0.114));\n"
-"      //gl_FragColor = float3(y,y,y) + (gl_FragColor.rgb - float3(y)) * Saturation;\n"
-"      gl_FragColor.rgb = lerp(float3(y,y,y), gl_FragColor.rgb, Saturation);\n"
+"      // 'vampire sight' effect, wheres red is compensated\n"
+"      #ifdef SATURATION_REDCOMPENSATE\n"
+"              float rboost = max(0.0, (gl_FragColor.r - max(gl_FragColor.g, gl_FragColor.b))*(1.0 - Saturation));\n"
+"              gl_FragColor.rgb = mix(float3(y,y,y), gl_FragColor.rgb, Saturation);\n"
+"              gl_FragColor.r += r;\n"
+"      #else\n"
+"              // normal desaturation\n"
+"              //gl_FragColor = float3(y,y,y) + (gl_FragColor.rgb - float3(y)) * Saturation;\n"
+"              gl_FragColor.rgb = lerp(float3(y,y,y), gl_FragColor.rgb, Saturation);\n"
+"      #endif\n"
 "#endif\n"
 "\n"
 "#ifdef USEGAMMARAMPS\n"
@@ -3567,6 +3584,47 @@ r_glsl_permutation_t;
 
 #define SHADERPERMUTATION_HASHSIZE 256
 
+
+// non-degradable "lightweight" shader parameters to keep the permutations simpler
+// these can NOT degrade! only use for simple stuff
+enum
+{
+       SHADERSTATICPARM_SATURATION_REDCOMPENSATE = 0
+};
+#define SHADERSTATICPARMS_COUNT 1
+
+static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
+static int shaderstaticparms_count = 0;
+
+static unsigned int r_compileshader_staticparms[(SHADERSTATICPARMS_COUNT + 0x1F) >> 5] = {0};
+#define R_COMPILESHADER_STATICPARM_ENABLE(p) r_compileshader_staticparms[(p) >> 5] |= (1 << ((p) & 0x1F))
+qboolean R_CompileShader_CheckStaticParms(void)
+{
+       static int r_compileshader_staticparms_save[1];
+       memcpy(r_compileshader_staticparms_save, r_compileshader_staticparms, sizeof(r_compileshader_staticparms));
+       memset(r_compileshader_staticparms, 0, sizeof(r_compileshader_staticparms));
+
+       // detect all
+       if (r_glsl_saturation_redcompensate.integer)
+               R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_SATURATION_REDCOMPENSATE);
+
+       return memcmp(r_compileshader_staticparms, r_compileshader_staticparms_save, sizeof(r_compileshader_staticparms));
+}
+
+#define R_COMPILESHADER_STATICPARM_EMIT(p, n) \
+       if(r_compileshader_staticparms[(p) >> 5] & (1 << ((p) & 0x1F))) \
+               shaderstaticparmstrings_list[shaderstaticparms_count++] = "#define " n "\n"; \
+       else \
+               shaderstaticparmstrings_list[shaderstaticparms_count++] = "\n"
+void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permutation)
+{
+       shaderstaticparms_count = 0;
+
+       // emit all
+       R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SATURATION_REDCOMPENSATE, "SATURATION_REDCOMPENSATE");
+}
+
+
 /// information about each possible shader permutation
 r_glsl_permutation_t *r_glsl_permutationhash[SHADERMODE_COUNT][SHADERPERMUTATION_HASHSIZE];
 /// currently selected permutation
@@ -3632,14 +3690,14 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
 {
        int i;
        shadermodeinfo_t *modeinfo = glslshadermodeinfo + mode;
+       char *vertexstring, *geometrystring, *fragmentstring;
+       char permutationname[256];
        int vertstrings_count = 0;
        int geomstrings_count = 0;
        int fragstrings_count = 0;
-       char *vertexstring, *geometrystring, *fragmentstring;
-       const char *vertstrings_list[32+3];
-       const char *geomstrings_list[32+3];
-       const char *fragstrings_list[32+3];
-       char permutationname[256];
+       const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+       const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+       const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
 
        if (p->compiled)
                return;
@@ -3655,9 +3713,6 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
 
        // the first pretext is which type of shader to compile as
        // (later these will all be bound together as a program object)
-       vertstrings_count = 0;
-       geomstrings_count = 0;
-       fragstrings_count = 0;
        vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
        geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
        fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
@@ -3687,6 +3742,15 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode
                }
        }
 
+       // add static parms
+       R_CompileShader_AddStaticParms(mode, permutation);
+       memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+       vertstrings_count += shaderstaticparms_count;
+       memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+       geomstrings_count += shaderstaticparms_count;
+       memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+       fragstrings_count += shaderstaticparms_count;
+
        // now append the shader text itself
        vertstrings_list[vertstrings_count++] = vertexstring;
        geomstrings_list[geomstrings_count++] = geometrystring;
@@ -4059,18 +4123,22 @@ static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, un
 {
        int i;
        shadermodeinfo_t *modeinfo = cgshadermodeinfo + mode;
-       int vertstrings_count = 0, vertstring_length = 0;
-       int geomstrings_count = 0, geomstring_length = 0;
-       int fragstrings_count = 0, fragstring_length = 0;
+       int vertstring_length = 0;
+       int geomstring_length = 0;
+       int fragstring_length = 0;
+       char *t;
        char *vertexstring, *geometrystring, *fragmentstring;
-       const char *vertstrings_list[32+3];
-       const char *geomstrings_list[32+3];
-       const char *fragstrings_list[32+3];
        char *vertstring, *geomstring, *fragstring;
        char permutationname[256];
        char cachename[256];
        CGprofile vertexProfile;
        CGprofile fragmentProfile;
+       int vertstrings_count = 0;
+       int geomstrings_count = 0;
+       int fragstrings_count = 0;
+       const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+       const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+       const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
 
        if (p->compiled)
                return;
@@ -4122,6 +4190,12 @@ static void R_CG_CompilePermutation(r_cg_permutation_t *p, unsigned int mode, un
 
        // add static parms
        R_CompileShader_AddStaticParms(mode, permutation);
+       memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+       vertstrings_count += shaderstaticparms_count;
+       memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+       geomstrings_count += shaderstaticparms_count;
+       memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+       fragstrings_count += shaderstaticparms_count;
 
        // replace spaces in the cachename with _ characters
        for (i = 0;cachename[i];i++)
@@ -4683,17 +4757,20 @@ static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode
 {
        int i;
        shadermodeinfo_t *modeinfo = hlslshadermodeinfo + mode;
-       int vertstrings_count = 0, vertstring_length = 0;
-       int geomstrings_count = 0, geomstring_length = 0;
-       int fragstrings_count = 0, fragstring_length = 0;
+       int vertstring_length = 0;
+       int geomstring_length = 0;
+       int fragstring_length = 0;
        char *t;
        char *vertexstring, *geometrystring, *fragmentstring;
-       const char *vertstrings_list[32+3];
-       const char *geomstrings_list[32+3];
-       const char *fragstrings_list[32+3];
        char *vertstring, *geomstring, *fragstring;
        char permutationname[256];
        char cachename[256];
+       int vertstrings_count = 0;
+       int geomstrings_count = 0;
+       int fragstrings_count = 0;
+       const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+       const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
+       const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1];
 
        if (p->compiled)
                return;
@@ -4711,15 +4788,15 @@ static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode
        strlcat(cachename, "hlsl/", sizeof(cachename));
 
        // define HLSL so that the shader can tell apart the HLSL compiler and the Cg compiler
+       vertstrings_count = 0;
+       geomstrings_count = 0;
+       fragstrings_count = 0;
        vertstrings_list[vertstrings_count++] = "#define HLSL\n";
        geomstrings_list[geomstrings_count++] = "#define HLSL\n";
        fragstrings_list[fragstrings_count++] = "#define HLSL\n";
 
        // the first pretext is which type of shader to compile as
        // (later these will all be bound together as a program object)
-       vertstrings_count = 0;
-       geomstrings_count = 0;
-       fragstrings_count = 0;
        vertstrings_list[vertstrings_count++] = "#define VERTEX_SHADER\n";
        geomstrings_list[geomstrings_count++] = "#define GEOMETRY_SHADER\n";
        fragstrings_list[fragstrings_count++] = "#define FRAGMENT_SHADER\n";
@@ -4751,6 +4828,15 @@ static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode
                }
        }
 
+       // add static parms
+       R_CompileShader_AddStaticParms(mode, permutation);
+       memcpy(vertstrings_list + vertstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+       vertstrings_count += shaderstaticparms_count;
+       memcpy(geomstrings_list + geomstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+       geomstrings_count += shaderstaticparms_count;
+       memcpy(fragstrings_list + fragstrings_count, shaderstaticparmstrings_list, sizeof(*vertstrings_list) * shaderstaticparms_count);
+       fragstrings_count += shaderstaticparms_count;
+
        // replace spaces in the cachename with _ characters
        for (i = 0;cachename[i];i++)
                if (cachename[i] == ' ')
@@ -7340,6 +7426,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&gl_lightmaps);
        Cvar_RegisterVariable(&r_test);
        Cvar_RegisterVariable(&r_glsl_saturation);
+       Cvar_RegisterVariable(&r_glsl_saturation_redcompensate);
        Cvar_RegisterVariable(&r_framedatasize);
        if (gamemode == GAME_NEHAHRA || gamemode == GAME_TENEBRAE)
                Cvar_SetValue("r_fullbrights", 0);
@@ -9527,6 +9614,9 @@ void R_RenderView(void)
        r_textureframe++; // used only by R_GetCurrentTexture
        rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity
 
+       if(R_CompileShader_CheckStaticParms())
+               R_GLSL_Restart_f();
+
        if (!r_drawentities.integer)
                r_refdef.scene.numentities = 0;