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
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];
"#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"
"#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"
"// 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"
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
}
{"#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"},
};
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));
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));
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;
{
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)
{
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)
}
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;
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
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);
// 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)
Cvar_RegisterVariable(&v_color_white_b);
Cvar_RegisterVariable(&v_hwgamma);
+ Cvar_RegisterVariable(&v_glslgamma);
Cvar_RegisterVariable(&v_psycho);