From fe0ac517fba262e817ecc5f06e077ad34b634057 Mon Sep 17 00:00:00 2001 From: divverent Date: Thu, 14 Oct 2010 06:14:59 +0000 Subject: [PATCH] add back VorteX's "lightweight shader parameter" system, but have it detect cvar changes and recompile all glsl shaders if any changed so these can be changed at runtime still git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10532 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rmain.c | 144 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 117 insertions(+), 27 deletions(-) diff --git a/gl_rmain.c b/gl_rmain.c index 44e3504e..bda27f4b 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -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; -- 2.39.2