Skip to content

Commit

Permalink
New gamma correction implementation using glsl. Enabled by default on…
Browse files Browse the repository at this point in the history
… OpenGL2. Disable with -noglslgamma.

Avoids general bugginess of hardware gamma, doesn't affect the whole screen in windowed mode like HW gamma. Should fix http://sourceforge.net/p/quakespasm/bugs/5/

git-svn-id: svn+ssh://svn.code.sf.net/p/quakespasm/code/trunk@1157 af15c1b1-3010-417e-b628-4374ebc0bcbd
  • Loading branch information
ewasylishen committed Jan 26, 2015
1 parent 85879ba commit b85b510
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 4 deletions.
134 changes: 134 additions & 0 deletions quakespasm/Quake/gl_rmain.c
Expand Up @@ -103,6 +103,140 @@ cvar_t gl_zfix = {"gl_zfix", "0", CVAR_NONE}; // QuakeSpasm z-fighting fix

qboolean r_drawflat_cheatsafe, r_fullbright_cheatsafe, r_lightmap_cheatsafe, r_drawworld_cheatsafe; //johnfitz

//==============================================================================
//
// GLSL GAMMA CORRECTION
//
//==============================================================================

static GLuint r_gamma_texture;
static GLuint r_gamma_program;

// uniforms used in gamma shader
static GLuint gammaLoc;
static GLuint textureLoc;

/*
=============
GLSLGamma_DeleteTexture
=============
*/
void GLSLGamma_DeleteTexture (void)
{
glDeleteTextures (1, &r_gamma_texture);
r_gamma_texture = 0;
r_gamma_program = 0; // deleted in R_DeleteShaders
}

/*
=============
GLSLGamma_CreateShaders
=============
*/
static void GLSLGamma_CreateShaders (void)
{
const GLchar *vertSource = \
"#version 110\n"
"\n"
"void main(void) {\n"
" gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0);\n"
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
"}\n";

const GLchar *fragSource = \
"#version 110\n"
"\n"
"uniform sampler2D GammaTexture;\n"
"uniform float GammaValue;\n"
"\n"
"void main(void) {\n"
" vec4 frag = texture2D(GammaTexture, gl_TexCoord[0].xy);\n"
" gl_FragColor = vec4(pow(frag.rgb, vec3(GammaValue)), 1.0);\n"
"}\n";

if (!gl_glsl_gamma_able)
return;

r_gamma_program = GL_CreateProgram (vertSource, fragSource, 0, NULL);

// get uniform locations
gammaLoc = GL_GetUniformLocation (&r_gamma_program, "GammaValue");
textureLoc = GL_GetUniformLocation (&r_gamma_program, "GammaTexture");
}

/*
=============
GLSLGamma_GammaCorrect
=============
*/
void GLSLGamma_GammaCorrect (void)
{
if (!gl_glsl_gamma_able)
return;

if (vid_gamma.value == 1)
return;

// create render-to-texture texture if needed
if (!r_gamma_texture)
{
glGenTextures (1, &r_gamma_texture);
glBindTexture (GL_TEXTURE_2D, r_gamma_texture);

glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, glwidth, glheight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}

// create shader if needed
if (!r_gamma_program)
{
GLSLGamma_CreateShaders ();
if (!r_gamma_program)
{
Sys_Error("GLSLGamma_CreateShaders failed");
}
}

// copy the framebuffer to the texture
GL_DisableMultitexture();
glBindTexture (GL_TEXTURE_2D, r_gamma_texture);
glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, glx, gly, glwidth, glheight);

glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);

// draw the texture back to the framebuffer with a fragment shader
GL_UseProgramFunc (r_gamma_program);
GL_Uniform1fFunc (gammaLoc, vid_gamma.value);
GL_Uniform1iFunc (textureLoc, 0); // use texture unit 0

glDisable (GL_ALPHA_TEST);
glDisable (GL_DEPTH_TEST);

glViewport (glx, gly, glwidth, glheight);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glOrtho (0, 1, 1, 0, -99999, 99999);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();

glBegin (GL_QUADS);
glTexCoord2f (0, 0);
glVertex2f (-1, -1);
glTexCoord2f (1, 0);
glVertex2f (1, -1);
glTexCoord2f (1, 1);
glVertex2f (1, 1);
glTexCoord2f (0, 1);
glVertex2f (-1, 1);
glEnd ();

GL_UseProgramFunc (0);

// clear cached binding
GL_Bind (notexture);
}

/*
=================
R_CullBox -- johnfitz -- replaced with new function from lordhavoc
Expand Down
2 changes: 2 additions & 0 deletions quakespasm/Quake/gl_screen.c
Expand Up @@ -1077,6 +1077,8 @@ void SCR_UpdateScreen (void)

V_UpdateBlend (); //johnfitz -- V_UpdatePalette cleaned up and renamed

GLSLGamma_GammaCorrect ();

GL_EndRendering ();
}

35 changes: 31 additions & 4 deletions quakespasm/Quake/gl_vidsdl.c
Expand Up @@ -102,6 +102,7 @@ qboolean gl_texture_NPOT = false; //ericw
qboolean gl_vbo_able = false; //ericw
qboolean gl_glsl_able = false; //ericw
GLint gl_max_texture_units = 0; //ericw
qboolean gl_glsl_gamma_able = false; //ericw

PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc = NULL; //johnfitz
PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc = NULL; //johnfitz
Expand Down Expand Up @@ -177,6 +178,9 @@ VID_Gamma_SetGamma -- apply gamma correction
*/
static void VID_Gamma_SetGamma (void)
{
if (gl_glsl_gamma_able)
return;

if (draw_context && gammaworks)
{
float value;
Expand Down Expand Up @@ -213,6 +217,9 @@ VID_Gamma_Restore -- restore system gamma
*/
static void VID_Gamma_Restore (void)
{
if (gl_glsl_gamma_able)
return;

if (draw_context && gammaworks)
{
#if defined(USE_SDL2)
Expand Down Expand Up @@ -252,6 +259,9 @@ VID_Gamma_f -- callback when the cvar changes
*/
static void VID_Gamma_f (cvar_t *var)
{
if (gl_glsl_gamma_able)
return;

#if USE_GAMMA_RAMPS
int i;

Expand All @@ -273,6 +283,12 @@ VID_Gamma_Init -- call on init
*/
static void VID_Gamma_Init (void)
{
Cvar_RegisterVariable (&vid_gamma);
Cvar_SetCallback (&vid_gamma, VID_Gamma_f);

if (gl_glsl_gamma_able)
return;

#if defined(USE_SDL2)
# if USE_GAMMA_RAMPS
gammaworks = (SDL_GetWindowGammaRamp(draw_context, vid_sysgamma_red, vid_sysgamma_green, vid_sysgamma_blue) == 0);
Expand All @@ -293,9 +309,6 @@ static void VID_Gamma_Init (void)

if (!gammaworks)
Con_SafePrintf("gamma adjustment not available\n");

Cvar_RegisterVariable (&vid_gamma);
Cvar_SetCallback (&vid_gamma, VID_Gamma_f);
}

/*
Expand Down Expand Up @@ -683,6 +696,8 @@ static void VID_Restart (void)
// memory leak.

TexMgr_DeleteTextureObjects ();
GLSLGamma_DeleteTexture ();
R_DeleteShaders ();

//
// set new mode
Expand Down Expand Up @@ -1096,6 +1111,19 @@ static void GL_CheckExtensions (void)
{
Con_Warning ("OpenGL version < 2, GLSL not available\n");
}

// GLSL gamma
//
if (COM_CheckParm("-noglslgamma"))
Con_Warning ("GLSL gamma disabled at command line\n");
else if (gl_glsl_able && gl_texture_NPOT)
{
gl_glsl_gamma_able = true;
}
else
{
Con_Warning ("GLSL gamma not available, using hardware gamma\n");
}
}

/*
Expand Down Expand Up @@ -1168,7 +1196,6 @@ static void GL_Init (void)
}
//johnfitz

R_DeleteShaders ();
GLAlias_CreateShaders ();
GL_ClearBufferBindings ();
}
Expand Down
5 changes: 5 additions & 0 deletions quakespasm/Quake/glquake.h
Expand Up @@ -222,6 +222,7 @@ extern QS_PFNGLUNIFORM1FPROC GL_Uniform1fFunc;
extern QS_PFNGLUNIFORM3FPROC GL_Uniform3fFunc;
extern QS_PFNGLUNIFORM4FPROC GL_Uniform4fFunc;
extern qboolean gl_glsl_able;
extern qboolean gl_glsl_gamma_able;
// ericw --

//ericw -- NPOT texture support
Expand Down Expand Up @@ -376,5 +377,9 @@ void R_DrawWorld_Water (void);

void GL_BindBuffer (GLenum target, GLuint buffer);
void GL_ClearBufferBindings ();

void GLSLGamma_DeleteTexture (void);
void GLSLGamma_GammaCorrect (void);

#endif /* __GLQUAKE_H */

0 comments on commit b85b510

Please sign in to comment.