added r_greyscale to control how monochromatic the final image looks

not doing the gamma pass when gamma==1 && obBits==0
no longer checking glConfig.colorBits for computing the global brightness
This commit is contained in:
myT 2017-08-18 16:02:02 +02:00
parent 1c38742c5a
commit ec042e37e1
5 changed files with 108 additions and 30 deletions

View file

@ -1,6 +1,11 @@
DD Mmm 17 - 1.49
add: r_greyscale to control how monochromatic the final image looks
r_greyscale 0 (default) = full color (nothing done)
r_greyscale 1 = monochrome
r_greyscale ]0 1[ for linear interpolations between the 2 extremes
add: com_completionStyle to select the auto-completion style
com_completionStyle 0 (default) = always print all results
com_completionStyle 1 = cycle results like Enemy Territory's console

View file

@ -570,32 +570,8 @@ static void GL2_FBO_BlitMSToSS()
}
static GLSL_Program gammaProg;
struct GLSL_GammaProgramAttribs
static void GL2_FullScreenQuad()
{
int texture;
int gammaOverbright;
};
static GLSL_GammaProgramAttribs gammaProgAttribs;
void GL2_PostProcessGamma()
{
const int obBits = Com_ClampInt( 0, (glConfig.colorBits > 16) ? 2 : 1, r_overBrightBits->integer );
const float obScale = 1 << obBits;
const float gamma = 1.0f / Com_Clamp( 0.5f, 3.0f, r_gamma->value );
GL2_FBO_Swap();
GL2_FBO_Bind();
GL_Program( gammaProg );
qglUniform1i( gammaProgAttribs.texture, 0 ); // we use texture unit 0
qglUniform4f( gammaProgAttribs.gammaOverbright, gamma, gamma, gamma, obScale );
GL_SelectTexture( 0 );
qglBindTexture( GL_TEXTURE_2D, frameBuffersPostProcess[frameBufferReadIndex ^ 1].color );
const float w = glConfig.vidWidth;
const float h = glConfig.vidHeight;
qglBegin( GL_QUADS );
@ -608,7 +584,38 @@ void GL2_PostProcessGamma()
qglTexCoord2f( 1.0f, 0.0f );
qglVertex2f( w, h );
qglEnd();
}
static GLSL_Program gammaProg;
struct GLSL_GammaProgramAttribs
{
int texture;
int gammaOverbright;
};
static GLSL_GammaProgramAttribs gammaProgAttribs;
static void GL2_PostProcessGamma()
{
const int obBits = Com_ClampInt( 0, 2, r_overBrightBits->integer );
const float obScale = (float)( 1 << obBits );
const float gamma = 1.0f / Com_Clamp( 0.5f, 3.0f, r_gamma->value );
if ( gamma == 1.0f && obBits == 0 )
return;
GL2_FBO_Swap();
GL2_FBO_Bind();
GL_Program( gammaProg );
qglUniform1i( gammaProgAttribs.texture, 0 ); // we use texture unit 0
qglUniform4f( gammaProgAttribs.gammaOverbright, gamma, gamma, gamma, obScale );
GL_SelectTexture( 0 );
qglBindTexture( GL_TEXTURE_2D, frameBuffersPostProcess[frameBufferReadIndex ^ 1].color );
GL2_FullScreenQuad();
qglBindTexture( GL_TEXTURE_2D, 0 );
GL_Program();
}
@ -634,6 +641,62 @@ static const char* gammaFS =
"";
static GLSL_Program greyscaleProg;
struct GLSL_GreyscaleProgramAttribs
{
int texture;
int greyscale;
};
static GLSL_GreyscaleProgramAttribs greyscaleProgAttribs;
static qbool greyscaleProgramValid = qfalse;
static void GL2_PostProcessGreyscale()
{
if ( !greyscaleProgramValid )
return;
const float greyscale = Com_Clamp( 0.0f, 1.0f, r_greyscale->value );
if ( greyscale == 0.0f )
return;
GL2_FBO_Swap();
GL2_FBO_Bind();
GL_Program( greyscaleProg );
qglUniform1i( greyscaleProgAttribs.texture, 0 ); // we use texture unit 0
qglUniform1f( greyscaleProgAttribs.greyscale, greyscale );
GL_SelectTexture( 0 );
qglBindTexture( GL_TEXTURE_2D, frameBuffersPostProcess[frameBufferReadIndex ^ 1].color );
GL2_FullScreenQuad();
qglBindTexture( GL_TEXTURE_2D, 0 );
GL_Program();
}
static const char* greyscaleVS =
"void main()\n"
"{\n"
" gl_Position = ftransform();\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
"}\n"
"";
static const char* greyscaleFS =
"uniform sampler2D texture;\n"
"uniform float greyscale;\n"
"\n"
"void main()\n"
"{\n"
" vec3 base = texture2D(texture, gl_TexCoord[0].xy).rgb;\n"
" vec3 grey = vec3(0.299 * base.r + 0.587 * base.g + 0.114 * base.b);\n"
" gl_FragColor = vec4(lerp(base, grey, greyscale), 1.0);\n"
"}\n"
"";
qbool QGL_InitGL2()
{
if ( !GL2_FBO_Init() ) {
@ -657,6 +720,14 @@ qbool QGL_InitGL2()
gammaProgAttribs.texture = qglGetUniformLocation( gammaProg.p, "texture" );
gammaProgAttribs.gammaOverbright = qglGetUniformLocation( gammaProg.p, "gammaOverbright" );
greyscaleProgramValid = GL2_CreateProgram( greyscaleProg, greyscaleVS, greyscaleFS );
if ( greyscaleProgramValid ) {
greyscaleProgAttribs.texture = qglGetUniformLocation( greyscaleProg.p, "texture" );
greyscaleProgAttribs.greyscale = qglGetUniformLocation( greyscaleProg.p, "greyscale" );
} else {
Com_Printf( "ERROR: failed to compile greyscale shaders\n" );
}
return qtrue;
}
@ -676,6 +747,7 @@ void GL2_EndFrame()
GL2_FBO_BlitMSToSS();
GL2_PostProcessGamma();
GL2_PostProcessGreyscale();
GL2_FBO_BlitSSToBackBuffer();
}

View file

@ -862,11 +862,9 @@ static void R_CreateBuiltinImages()
void R_SetColorMappings()
{
// allow 2 overbright bits in 24 bit, but only 1 in 16 bit
tr.overbrightBits = Com_Clamp( 0, (glConfig.colorBits > 16) ? 2 : 1, r_overBrightBits->integer );
tr.identityLight = 1.0f / (1 << tr.overbrightBits);
tr.identityLightByte = 255 * tr.identityLight;
tr.overbrightBits = Com_Clamp( 0, 2, r_overBrightBits->integer );
tr.identityLight = 1.0f / (float)( 1 << tr.overbrightBits );
tr.identityLightByte = (int)( 255.0f * tr.identityLight );
if ( r_intensity->value < 1 )
ri.Cvar_Set( "r_intensity", "1" );

View file

@ -44,6 +44,7 @@ cvar_t *r_skipBackEnd;
cvar_t *r_intensity;
cvar_t *r_gamma;
cvar_t *r_greyscale;
cvar_t *r_measureOverdraw;
@ -542,6 +543,7 @@ static void R_Register()
r_swapInterval = ri.Cvar_Get( "r_swapInterval", "0", CVAR_ARCHIVE );
#endif
r_gamma = ri.Cvar_Get( "r_gamma", "1", CVAR_ARCHIVE );
r_greyscale = ri.Cvar_Get( "r_greyscale", "0", CVAR_ARCHIVE );
r_ambientScale = ri.Cvar_Get( "r_ambientScale", "0.6", CVAR_CHEAT );
r_directedScale = ri.Cvar_Get( "r_directedScale", "1", CVAR_CHEAT );

View file

@ -959,6 +959,7 @@ extern cvar_t *r_displayRefresh; // optional display refresh option
extern cvar_t *r_intensity;
extern cvar_t *r_gamma;
extern cvar_t *r_greyscale;
extern cvar_t *r_ext_max_anisotropy;
extern cvar_t *r_msaa;