From d18be15853e21906b834d0add649f300bec9fb4f Mon Sep 17 00:00:00 2001 From: divverent Date: Tue, 29 Jan 2008 16:55:43 +0000 Subject: [PATCH] v_glslgamma: make GLSL postprocessing take over the job of v_hwgamma completely, if set and glsl works. Costs here 1.6ms per frame, so I'll keep r_glsl_contrastboost. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@8045 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_draw.c | 4 ++- gl_rmain.c | 84 ++++++++++++++++++++++++++++++++++++---------------- vid_shared.c | 9 +++++- 3 files changed, 69 insertions(+), 28 deletions(-) diff --git a/gl_draw.c b/gl_draw.c index c9e03c20..fdd0d7c3 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -31,6 +31,8 @@ cvar_t r_textshadow = {CVAR_SAVE, "r_textshadow", "0", "draws a shadow on all te cvar_t r_textbrightness = {CVAR_SAVE, "r_textbrightness", "0", "additional brightness for text color codes (0 keeps colors as is, 1 makes them all white)"}; cvar_t r_textcontrast = {CVAR_SAVE, "r_textcontrast", "1", "additional contrast for text color codes (1 keeps colors as is, 1 makes them all black)"}; +extern cvar_t v_glslgamma; + //============================================================================= /* Support Routines */ @@ -1217,7 +1219,7 @@ static float blendvertex3f[9] = {-5000, -5000, 10, 10000, -5000, 10, -5000, 1000 void R_DrawGamma(void) { float c[4]; - if (!vid_usinghwgamma) + if (!vid_usinghwgamma && !(r_glsl.integer && v_glslgamma.integer)) { // all the blends ignore depth R_Mesh_VertexPointer(blendvertex3f, 0, 0); diff --git a/gl_rmain.c b/gl_rmain.c index 7ad76f49..aeba6e23 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -127,6 +127,8 @@ cvar_t r_track_sprites_flags = {CVAR_SAVE, "r_track_sprites_flags", "1", "1: Rot cvar_t r_track_sprites_scalew = {CVAR_SAVE, "r_track_sprites_scalew", "1", "width scaling of tracked sprites"}; cvar_t r_track_sprites_scaleh = {CVAR_SAVE, "r_track_sprites_scaleh", "1", "height scaling of tracked sprites"}; +extern cvar_t v_glslgamma; + extern qboolean v_flipped_state; static struct r_bloomstate_s @@ -191,6 +193,8 @@ rtexture_t *r_texture_notexture; rtexture_t *r_texture_whitecube; rtexture_t *r_texture_normalizationcube; rtexture_t *r_texture_fogattenuation; +rtexture_t *r_texture_gammaramps; +unsigned int r_texture_gammaramps_serial; //rtexture_t *r_texture_fogintensity; char r_qwskincache[MAX_SCOREBOARD][MAX_QPATH]; @@ -493,18 +497,15 @@ static const char *builtinshaderstring = "#ifdef USEGLOW\n" "uniform sampler2D Texture_Second;\n" "#endif\n" +"#ifdef USEGAMMARAMPS\n" +"uniform sampler2D Texture_Attenuation;\n" +"#endif\n" "#ifdef USEVERTEXTEXTUREBLEND\n" "uniform vec4 TintColor;\n" "#endif\n" "#ifdef USECOLORMOD\n" "uniform vec3 Gamma;\n" "#endif\n" -"#ifdef USECONTRASTBOOST\n" -"uniform float ContrastBoostCoeff;\n" -"#endif\n" -"#ifdef USEGAMMA\n" -"uniform float GammaCoeff;\n" -"#endif\n" "//uncomment these if you want to use them:\n" "// uniform vec4 UserVec1;\n" "// uniform vec4 UserVec2;\n" @@ -517,13 +518,6 @@ static const char *builtinshaderstring = "#ifdef USEGLOW\n" " gl_FragColor += texture2D(Texture_Second, gl_TexCoord[1].xy);\n" "#endif\n" -"#ifdef USECONTRASTBOOST\n" -" gl_FragColor.rgb /= (ContrastBoostCoeff * gl_FragColor.rgb + vec3(1.0, 1.0, 1.0));\n" -" gl_FragColor.rgb *= (ContrastBoostCoeff + 1.0);\n" -"#endif\n" -"#ifdef USEGAMMA\n" -" gl_FragColor.rgb = pow(gl_FragColor.rgb, GammaCoeff);\n" -"#endif\n" "#ifdef USEVERTEXTEXTUREBLEND\n" " gl_FragColor = mix(TintColor, gl_FragColor, TintColor.a);\n" "#endif\n" @@ -532,6 +526,11 @@ static const char *builtinshaderstring = "// add your own postprocessing here or make your own ifdef for it\n" "#endif\n" "\n" +"#ifdef USEGAMMARAMPS\n" +" gl_FragColor.r = texture2D(Texture_Attenuation, vec2(gl_FragColor.r, 0)).r;\n" +" gl_FragColor.g = texture2D(Texture_Attenuation, vec2(gl_FragColor.g, 0)).g;\n" +" gl_FragColor.b = texture2D(Texture_Attenuation, vec2(gl_FragColor.b, 0)).b;\n" +"#endif\n" "}\n" "# endif\n" "\n" @@ -1090,8 +1089,8 @@ typedef enum shaderpermutation_e SHADERPERMUTATION_REFLECTION = 1<<8, // normalmap-perturbed reflection of the scene infront of the surface, preformed as an overlay on the surface SHADERPERMUTATION_OFFSETMAPPING = 1<<9, // adjust texcoords to roughly simulate a displacement mapped surface SHADERPERMUTATION_OFFSETMAPPING_RELIEFMAPPING = 1<<10, // adjust texcoords to accurately simulate a displacement mapped surface (requires OFFSETMAPPING to also be set!) - SHADERPERMUTATION_GAMMA = 1<<11, // gamma (postprocessing only) - SHADERPERMUTATION_POSTPROCESSING = 1<<12, // gamma (postprocessing only) + SHADERPERMUTATION_GAMMARAMPS = 1<<11, // gamma (postprocessing only) + SHADERPERMUTATION_POSTPROCESSING = 1<<12, // user defined postprocessing SHADERPERMUTATION_LIMIT = 1<<13, // size of permutations array SHADERPERMUTATION_COUNT = 13 // size of shaderpermutationinfo array } @@ -1111,7 +1110,7 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] = {"#define USEREFLECTION\n", " reflection"}, {"#define USEOFFSETMAPPING\n", " offsetmapping"}, {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"}, - {"#define USEGAMMA\n", " gamma"}, + {"#define USEGAMMARAMPS\n", " gammaramps"}, {"#define USEPOSTPROCESSING\n", " postprocessing"}, }; @@ -2167,6 +2166,7 @@ void gl_main_start(void) R_BuildNormalizationCube(); } r_texture_fogattenuation = NULL; + r_texture_gammaramps = NULL; //r_texture_fogintensity = NULL; memset(&r_bloomstate, 0, sizeof(r_bloomstate)); memset(&r_waterstate, 0, sizeof(r_waterstate)); @@ -2196,6 +2196,7 @@ void gl_main_shutdown(void) r_texture_whitecube = NULL; r_texture_normalizationcube = NULL; r_texture_fogattenuation = NULL; + r_texture_gammaramps = NULL; //r_texture_fogintensity = NULL; memset(&r_bloomstate, 0, sizeof(r_bloomstate)); memset(&r_waterstate, 0, sizeof(r_waterstate)); @@ -3118,7 +3119,7 @@ void R_Bloom_StartFrame(void) Cvar_SetValueQuick(&r_bloom, 0); } - if (!(r_glsl.integer && (r_glsl_postprocess.integer || r_bloom.integer || r_hdr.integer)) && !r_bloom.integer) + if (!(r_glsl.integer && (r_glsl_postprocess.integer || (v_glslgamma.integer && !vid_gammatables_trivial) || r_bloom.integer || r_hdr.integer)) && !r_bloom.integer) screentexturewidth = screentextureheight = 0; if (!r_hdr.integer && !r_bloom.integer) bloomtexturewidth = bloomtextureheight = 0; @@ -3378,11 +3379,9 @@ static void R_BlendView(void) { unsigned int permutation = (r_bloomstate.texture_bloom ? SHADERPERMUTATION_GLOW : 0) - | (r_refdef.viewblend[3] > 0 ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0); - if(r_glsl_postprocess.value) - permutation |= SHADERPERMUTATION_POSTPROCESSING - | (r_glsl_postprocess_contrastboost.value != 1 ? SHADERPERMUTATION_CONTRASTBOOST : 0) - | (r_glsl_postprocess_gamma.value != 1 ? SHADERPERMUTATION_GAMMA : 0); + | (r_refdef.viewblend[3] > 0 ? SHADERPERMUTATION_VERTEXTEXTUREBLEND : 0) + | ((v_glslgamma.value && !vid_gammatables_trivial) ? SHADERPERMUTATION_GAMMARAMPS : 0) + | (r_glsl_postprocess.integer ? SHADERPERMUTATION_POSTPROCESSING : 0); if (r_bloomstate.texture_bloom && !r_bloomstate.hdr) { @@ -3403,12 +3402,10 @@ static void R_BlendView(void) R_Mesh_TexCoordPointer(0, 2, r_bloomstate.screentexcoord2f, 0, 0); R_Mesh_TexBind(1, R_GetTexture(r_bloomstate.texture_bloom)); R_Mesh_TexCoordPointer(1, 2, r_bloomstate.bloomtexcoord2f, 0, 0); + if (r_glsl_permutation->loc_Texture_Attenuation >= 0) + R_Mesh_TexBind(GL20TU_ATTENUATION, R_GetTexture(r_texture_gammaramps)); if (r_glsl_permutation->loc_TintColor >= 0) qglUniform4fARB(r_glsl_permutation->loc_TintColor, r_refdef.viewblend[0], r_refdef.viewblend[1], r_refdef.viewblend[2], r_refdef.viewblend[3]); - if (r_glsl_permutation->loc_ContrastBoostCoeff >= 0) - qglUniform1fARB(r_glsl_permutation->loc_ContrastBoostCoeff, r_glsl_postprocess_contrastboost.value - 1); - if (r_glsl_permutation->loc_GammaCoeff >= 0) - qglUniform1fARB(r_glsl_permutation->loc_GammaCoeff, 1 / r_glsl_postprocess_gamma.value); if (r_glsl_permutation->loc_ClientTime >= 0) qglUniform1fARB(r_glsl_permutation->loc_ClientTime, cl.time); if (r_glsl_permutation->loc_UserVec1 >= 0) @@ -3620,6 +3617,41 @@ void R_UpdateVariables(void) } else r_refdef.fogenabled = false; + + if(r_glsl.integer && v_glslgamma.integer && !vid_gammatables_trivial) + { + if(!r_texture_gammaramps || vid_gammatables_serial != r_texture_gammaramps_serial) + { + // build GLSL gamma texture +#define RAMPWIDTH 256 + unsigned short ramp[RAMPWIDTH * 3]; + unsigned char ramprgb[RAMPWIDTH][4]; + int i; + + r_texture_gammaramps_serial = vid_gammatables_serial; + + VID_BuildGammaTables(&ramp[0], RAMPWIDTH); + for(i = 0; i < RAMPWIDTH; ++i) + { + ramprgb[i][0] = ramp[i] >> 8; + ramprgb[i][1] = ramp[i + RAMPWIDTH] >> 8; + ramprgb[i][2] = ramp[i + 2 * RAMPWIDTH] >> 8; + ramprgb[i][3] = 0; + } + if (r_texture_gammaramps) + { + R_UpdateTexture(r_texture_gammaramps, &ramprgb[0][0], 0, 0, RAMPWIDTH, 1); + } + else + { + r_texture_gammaramps = R_LoadTexture2D(r_main_texturepool, "gammaramps", RAMPWIDTH, 1, &ramprgb[0][0], TEXTYPE_BGRA, TEXF_PRECACHE | TEXF_FORCELINEAR | TEXF_CLAMP | TEXF_PERSISTENT, NULL); + } + } + } + else + { + // remove GLSL gamma texture + } } static r_refdef_scene_type_t r_currentscenetype = RST_CLIENT; diff --git a/vid_shared.c b/vid_shared.c index a11cfc32..bf73db17 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -111,6 +111,7 @@ cvar_t v_color_white_r = {CVAR_SAVE, "v_color_white_r", "1", "desired color of w cvar_t v_color_white_g = {CVAR_SAVE, "v_color_white_g", "1", "desired color of white"}; cvar_t v_color_white_b = {CVAR_SAVE, "v_color_white_b", "1", "desired color of white"}; cvar_t v_hwgamma = {CVAR_SAVE, "v_hwgamma", "1", "enables use of hardware gamma correction ramps if available (note: does not work very well on Windows2000 and above), values are 0 = off, 1 = attempt to use hardware gamma, 2 = use hardware gamma whether it works or not"}; +cvar_t v_glslgamma = {CVAR_SAVE, "v_glslgamma", "0", "enables use of GLSL to apply gamma correction ramps if available (note: overrides v_hwgamma)"}; cvar_t v_psycho = {0, "v_psycho", "0", "easter egg (does not work on Windows2000 or above)"}; // brand of graphics chip @@ -893,7 +894,11 @@ void VID_UpdateGamma(qboolean force, int rampsize) if (cls.state == ca_dedicated) return; - wantgamma = (vid_activewindow ? v_hwgamma.integer : 0); + wantgamma = v_hwgamma.integer; + if(r_glsl.integer && v_glslgamma.integer) + wantgamma = 0; + if(!vid_activewindow) + wantgamma = 0; #define BOUNDCVAR(cvar, m1, m2) c = &(cvar);f = bound(m1, c->value, m2);if (c->value != f) Cvar_SetValueQuick(c, f); BOUNDCVAR(v_gamma, 0.1, 5); BOUNDCVAR(v_contrast, 1, 5); @@ -912,6 +917,7 @@ void VID_UpdateGamma(qboolean force, int rampsize) // set vid_gammatables_trivial to true if the current settings would generate the identity gamma table vid_gammatables_trivial = false; + if(v_psycho.integer == 0) if(v_color_enable.integer) { if(v_contrastboost.value == 1) @@ -1035,6 +1041,7 @@ void VID_Shared_Init(void) Cvar_RegisterVariable(&v_color_white_b); Cvar_RegisterVariable(&v_hwgamma); + Cvar_RegisterVariable(&v_glslgamma); Cvar_RegisterVariable(&v_psycho); -- 2.39.2