Skip to content
This repository was archived by the owner on Jul 7, 2024. It is now read-only.

Commit b85b510

Browse files
author
ewasylishen
committed
New gamma correction implementation using glsl. Enabled by default on 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
1 parent 85879ba commit b85b510

File tree

4 files changed

+172
-4
lines changed

4 files changed

+172
-4
lines changed

quakespasm/Quake/gl_rmain.c

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,140 @@ cvar_t gl_zfix = {"gl_zfix", "0", CVAR_NONE}; // QuakeSpasm z-fighting fix
103103

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

106+
//==============================================================================
107+
//
108+
// GLSL GAMMA CORRECTION
109+
//
110+
//==============================================================================
111+
112+
static GLuint r_gamma_texture;
113+
static GLuint r_gamma_program;
114+
115+
// uniforms used in gamma shader
116+
static GLuint gammaLoc;
117+
static GLuint textureLoc;
118+
119+
/*
120+
=============
121+
GLSLGamma_DeleteTexture
122+
=============
123+
*/
124+
void GLSLGamma_DeleteTexture (void)
125+
{
126+
glDeleteTextures (1, &r_gamma_texture);
127+
r_gamma_texture = 0;
128+
r_gamma_program = 0; // deleted in R_DeleteShaders
129+
}
130+
131+
/*
132+
=============
133+
GLSLGamma_CreateShaders
134+
=============
135+
*/
136+
static void GLSLGamma_CreateShaders (void)
137+
{
138+
const GLchar *vertSource = \
139+
"#version 110\n"
140+
"\n"
141+
"void main(void) {\n"
142+
" gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0);\n"
143+
" gl_TexCoord[0] = gl_MultiTexCoord0;\n"
144+
"}\n";
145+
146+
const GLchar *fragSource = \
147+
"#version 110\n"
148+
"\n"
149+
"uniform sampler2D GammaTexture;\n"
150+
"uniform float GammaValue;\n"
151+
"\n"
152+
"void main(void) {\n"
153+
" vec4 frag = texture2D(GammaTexture, gl_TexCoord[0].xy);\n"
154+
" gl_FragColor = vec4(pow(frag.rgb, vec3(GammaValue)), 1.0);\n"
155+
"}\n";
156+
157+
if (!gl_glsl_gamma_able)
158+
return;
159+
160+
r_gamma_program = GL_CreateProgram (vertSource, fragSource, 0, NULL);
161+
162+
// get uniform locations
163+
gammaLoc = GL_GetUniformLocation (&r_gamma_program, "GammaValue");
164+
textureLoc = GL_GetUniformLocation (&r_gamma_program, "GammaTexture");
165+
}
166+
167+
/*
168+
=============
169+
GLSLGamma_GammaCorrect
170+
=============
171+
*/
172+
void GLSLGamma_GammaCorrect (void)
173+
{
174+
if (!gl_glsl_gamma_able)
175+
return;
176+
177+
if (vid_gamma.value == 1)
178+
return;
179+
180+
// create render-to-texture texture if needed
181+
if (!r_gamma_texture)
182+
{
183+
glGenTextures (1, &r_gamma_texture);
184+
glBindTexture (GL_TEXTURE_2D, r_gamma_texture);
185+
186+
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA8, glwidth, glheight, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
187+
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
188+
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
189+
}
190+
191+
// create shader if needed
192+
if (!r_gamma_program)
193+
{
194+
GLSLGamma_CreateShaders ();
195+
if (!r_gamma_program)
196+
{
197+
Sys_Error("GLSLGamma_CreateShaders failed");
198+
}
199+
}
200+
201+
// copy the framebuffer to the texture
202+
GL_DisableMultitexture();
203+
glBindTexture (GL_TEXTURE_2D, r_gamma_texture);
204+
glCopyTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, glx, gly, glwidth, glheight);
205+
206+
glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
207+
208+
// draw the texture back to the framebuffer with a fragment shader
209+
GL_UseProgramFunc (r_gamma_program);
210+
GL_Uniform1fFunc (gammaLoc, vid_gamma.value);
211+
GL_Uniform1iFunc (textureLoc, 0); // use texture unit 0
212+
213+
glDisable (GL_ALPHA_TEST);
214+
glDisable (GL_DEPTH_TEST);
215+
216+
glViewport (glx, gly, glwidth, glheight);
217+
glMatrixMode (GL_PROJECTION);
218+
glLoadIdentity ();
219+
glOrtho (0, 1, 1, 0, -99999, 99999);
220+
glMatrixMode (GL_MODELVIEW);
221+
glLoadIdentity ();
222+
223+
glBegin (GL_QUADS);
224+
glTexCoord2f (0, 0);
225+
glVertex2f (-1, -1);
226+
glTexCoord2f (1, 0);
227+
glVertex2f (1, -1);
228+
glTexCoord2f (1, 1);
229+
glVertex2f (1, 1);
230+
glTexCoord2f (0, 1);
231+
glVertex2f (-1, 1);
232+
glEnd ();
233+
234+
GL_UseProgramFunc (0);
235+
236+
// clear cached binding
237+
GL_Bind (notexture);
238+
}
239+
106240
/*
107241
=================
108242
R_CullBox -- johnfitz -- replaced with new function from lordhavoc

quakespasm/Quake/gl_screen.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,6 +1077,8 @@ void SCR_UpdateScreen (void)
10771077

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

1080+
GLSLGamma_GammaCorrect ();
1081+
10801082
GL_EndRendering ();
10811083
}
10821084

quakespasm/Quake/gl_vidsdl.c

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ qboolean gl_texture_NPOT = false; //ericw
102102
qboolean gl_vbo_able = false; //ericw
103103
qboolean gl_glsl_able = false; //ericw
104104
GLint gl_max_texture_units = 0; //ericw
105+
qboolean gl_glsl_gamma_able = false; //ericw
105106

106107
PFNGLMULTITEXCOORD2FARBPROC GL_MTexCoord2fFunc = NULL; //johnfitz
107108
PFNGLACTIVETEXTUREARBPROC GL_SelectTextureFunc = NULL; //johnfitz
@@ -177,6 +178,9 @@ VID_Gamma_SetGamma -- apply gamma correction
177178
*/
178179
static void VID_Gamma_SetGamma (void)
179180
{
181+
if (gl_glsl_gamma_able)
182+
return;
183+
180184
if (draw_context && gammaworks)
181185
{
182186
float value;
@@ -213,6 +217,9 @@ VID_Gamma_Restore -- restore system gamma
213217
*/
214218
static void VID_Gamma_Restore (void)
215219
{
220+
if (gl_glsl_gamma_able)
221+
return;
222+
216223
if (draw_context && gammaworks)
217224
{
218225
#if defined(USE_SDL2)
@@ -252,6 +259,9 @@ VID_Gamma_f -- callback when the cvar changes
252259
*/
253260
static void VID_Gamma_f (cvar_t *var)
254261
{
262+
if (gl_glsl_gamma_able)
263+
return;
264+
255265
#if USE_GAMMA_RAMPS
256266
int i;
257267

@@ -273,6 +283,12 @@ VID_Gamma_Init -- call on init
273283
*/
274284
static void VID_Gamma_Init (void)
275285
{
286+
Cvar_RegisterVariable (&vid_gamma);
287+
Cvar_SetCallback (&vid_gamma, VID_Gamma_f);
288+
289+
if (gl_glsl_gamma_able)
290+
return;
291+
276292
#if defined(USE_SDL2)
277293
# if USE_GAMMA_RAMPS
278294
gammaworks = (SDL_GetWindowGammaRamp(draw_context, vid_sysgamma_red, vid_sysgamma_green, vid_sysgamma_blue) == 0);
@@ -293,9 +309,6 @@ static void VID_Gamma_Init (void)
293309

294310
if (!gammaworks)
295311
Con_SafePrintf("gamma adjustment not available\n");
296-
297-
Cvar_RegisterVariable (&vid_gamma);
298-
Cvar_SetCallback (&vid_gamma, VID_Gamma_f);
299312
}
300313

301314
/*
@@ -683,6 +696,8 @@ static void VID_Restart (void)
683696
// memory leak.
684697

685698
TexMgr_DeleteTextureObjects ();
699+
GLSLGamma_DeleteTexture ();
700+
R_DeleteShaders ();
686701

687702
//
688703
// set new mode
@@ -1096,6 +1111,19 @@ static void GL_CheckExtensions (void)
10961111
{
10971112
Con_Warning ("OpenGL version < 2, GLSL not available\n");
10981113
}
1114+
1115+
// GLSL gamma
1116+
//
1117+
if (COM_CheckParm("-noglslgamma"))
1118+
Con_Warning ("GLSL gamma disabled at command line\n");
1119+
else if (gl_glsl_able && gl_texture_NPOT)
1120+
{
1121+
gl_glsl_gamma_able = true;
1122+
}
1123+
else
1124+
{
1125+
Con_Warning ("GLSL gamma not available, using hardware gamma\n");
1126+
}
10991127
}
11001128

11011129
/*
@@ -1168,7 +1196,6 @@ static void GL_Init (void)
11681196
}
11691197
//johnfitz
11701198

1171-
R_DeleteShaders ();
11721199
GLAlias_CreateShaders ();
11731200
GL_ClearBufferBindings ();
11741201
}

quakespasm/Quake/glquake.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ extern QS_PFNGLUNIFORM1FPROC GL_Uniform1fFunc;
222222
extern QS_PFNGLUNIFORM3FPROC GL_Uniform3fFunc;
223223
extern QS_PFNGLUNIFORM4FPROC GL_Uniform4fFunc;
224224
extern qboolean gl_glsl_able;
225+
extern qboolean gl_glsl_gamma_able;
225226
// ericw --
226227

227228
//ericw -- NPOT texture support
@@ -376,5 +377,9 @@ void R_DrawWorld_Water (void);
376377

377378
void GL_BindBuffer (GLenum target, GLuint buffer);
378379
void GL_ClearBufferBindings ();
380+
381+
void GLSLGamma_DeleteTexture (void);
382+
void GLSLGamma_GammaCorrect (void);
383+
379384
#endif /* __GLQUAKE_H */
380385

0 commit comments

Comments
 (0)