Gamma under OpenGL acceleration
Victor Shkamerda
vvs at auto.bnm.org
Thu Apr 18 01:58:03 EDT 2002
>>>Chris Venter <chris at dsp.sun.ac.za> wrote:
>I compiled the r0.0.8 version on my Redhat 7.2 system (which has a 3dfx
>voodoo banshee). Everything works as advertised, except the screen is
>_very_ low contrast and dark. Does anybody have an idea of how to up the
>gamma or some such thing?
Here's the patch that allows to change hardware gamma on the fly a la Quake 3. It's self documented, tested on Red Hat Linux 7.2. Sorry, I'm not sure if this list accepts attachments or not.
=============== 8< CUT HERE >8=============
* this Linux Quake 2 patch allows to change OpenGL gamma on the fly without
vid_restart. It uses hardware gamma where available (tested on
XFree86 4.2.0 with DRI)
* this is for GLX only, SDL should have its own implementation, based on
its own gamma manipulation functions
* this is implemented for fullscreen only. I'm not sure if it should be
implemented for windowed mode
* I've got the idea from MrG's BeefQuake for Windows, but the implementation
is completely mine
diff -ur quake2.orig/src/linux/gl_glx.c quake2/src/linux/gl_glx.c
--- quake2.orig/src/linux/gl_glx.c Wed Feb 13 11:58:08 2002
+++ quake2/src/linux/gl_glx.c Sun Apr 7 17:32:54 2002
@@ -98,6 +98,7 @@
static XF86VidModeModeInfo **vidmodes;
static int num_vidmodes;
static qboolean vidmode_active = false;
+static XF86VidModeGamma oldgamma;
static qboolean mlooking;
@@ -738,6 +739,8 @@
return rserr_invalid_mode;
}
+ gl_state.hwgamma = false;
+
if (vidmode_ext) {
int best_fit, best_dist, dist, x, y;
@@ -770,6 +773,15 @@
XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]);
vidmode_active = true;
+ if (XF86VidModeGetGamma(dpy, scrnum, &oldgamma)) {
+ gl_state.hwgamma = true;
+ /* We can not reliably detect hardware gamma
+ changes across software gamma calls, which
+ can reset the flag, so change it anyway */
+ vid_gamma->modified = true;
+ ri.Con_Printf( PRINT_ALL, "Using hardware gamma\n");
+ }
+
// Move the viewport to top left
XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
} else
@@ -887,6 +899,12 @@
qglXDestroyContext(dpy, ctx);
if (win)
XDestroyWindow(dpy, win);
+ if (gl_state.hwgamma) {
+ XF86VidModeSetGamma(dpy, scrnum, &oldgamma);
+ /* The gamma has changed, but SetMode will change it
+ anyway, so why bother?
+ vid_gamma->modified = true; */
+ }
if (vidmode_active)
XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[0]);
XUngrabKeyboard(dpy, CurrentTime);
@@ -953,6 +971,28 @@
}
/*
+** UpdateHardwareGamma
+**
+** We are using gamma relative to the desktop, so that we can share it
+** with software renderer and don't require to change desktop gamma
+** to match hardware gamma image brightness. It seems that Quake 3 is
+** using the opposite approach, but it has no software renderer after
+** all.
+*/
+void UpdateHardwareGamma()
+{
+ XF86VidModeGamma gamma;
+ float g;
+
+ g = (1.3 - vid_gamma->value + 1);
+ g = (g>1 ? g : 1);
+ gamma.red = oldgamma.red * g;
+ gamma.green = oldgamma.green * g;
+ gamma.blue = oldgamma.blue * g;
+ XF86VidModeSetGamma(dpy, scrnum, &gamma);
+}
+
+/*
** GLimp_AppActivate
*/
void GLimp_AppActivate( qboolean active )
diff -ur quake2.orig/src/linux/vid_menu.c quake2/src/linux/vid_menu.c
--- quake2.orig/src/linux/vid_menu.c Mon Jan 14 15:20:18 2002
+++ quake2/src/linux/vid_menu.c Sun Apr 7 17:35:23 2002
@@ -89,7 +89,8 @@
if ( stricmp( vid_ref->string, "soft" ) == 0 ||
stricmp( vid_ref->string, "softx" ) == 0 ||
- stricmp( vid_ref->string, "softsdl" ) == 0 )
+ stricmp( vid_ref->string, "softsdl" ) == 0 ||
+ stricmp( vid_ref->string, "glx" ) == 0 )
{
float gamma = ( 0.8 - ( slider->curvalue/10.0 - 0.5 ) ) + 0.5;
diff -ur quake2.orig/src/ref_gl/gl_image.c quake2/src/ref_gl/gl_image.c
--- quake2.orig/src/ref_gl/gl_image.c Fri Jan 4 14:46:15 2002
+++ quake2/src/ref_gl/gl_image.c Sun Apr 7 16:16:43 2002
@@ -1542,7 +1542,7 @@
for ( i = 0; i < 256; i++ )
{
- if ( g == 1 )
+ if ( g == 1 || gl_state.hwgamma )
{
gammatable[i] = i;
}
diff -ur quake2.orig/src/ref_gl/gl_local.h quake2/src/ref_gl/gl_local.h
--- quake2.orig/src/ref_gl/gl_local.h Mon Apr 1 15:14:53 2002
+++ quake2/src/ref_gl/gl_local.h Sun Apr 7 16:18:11 2002
@@ -426,6 +426,8 @@
float camera_separation;
qboolean stereo_enabled;
+ qboolean hwgamma;
+
unsigned char originalRedGammaTable[256];
unsigned char originalGreenGammaTable[256];
unsigned char originalBlueGammaTable[256];
diff -ur quake2.orig/src/ref_gl/gl_rmain.c quake2/src/ref_gl/gl_rmain.c
--- quake2.orig/src/ref_gl/gl_rmain.c Fri Jan 4 14:46:17 2002
+++ quake2/src/ref_gl/gl_rmain.c Sun Apr 7 16:17:48 2002
@@ -1439,6 +1439,8 @@
R_BeginFrame
@@@@@@@@@@@@@@@@@@@@@
*/
+extern void UpdateHardwareGamma();
+
void R_BeginFrame( float camera_separation )
{
@@ -1474,7 +1476,9 @@
{
vid_gamma->modified = false;
- if ( gl_config.renderer & ( GL_RENDERER_VOODOO ) )
+ if ( gl_state.hwgamma ) {
+ UpdateHardwareGamma();
+ } else if ( gl_config.renderer & ( GL_RENDERER_VOODOO ) )
{
char envbuffer[1024];
float g;
=============== 8< CUT HERE >8=============
More information about the quake2
mailing list