diff --git a/src/gl_glx.c b/src/gl_glx.c index 9860561..544ea08 100644 --- a/src/gl_glx.c +++ b/src/gl_glx.c @@ -111,6 +111,7 @@ static XF86VidModeModeInfo **vidmodes; //static int default_dotclock_vidmode; static int num_vidmodes; static qboolean vidmode_active = false; +static XF86VidModeGamma oldgamma; static qboolean mlooking; @@ -752,6 +753,8 @@ int GLimp_SetMode( unsigned int *pwidth, unsigned int *pheight, int mode, qboole return rserr_invalid_mode; } + gl_state.hwgamma = false; + if (vidmode_ext) { int best_fit, best_dist, dist, x, y; @@ -784,6 +787,15 @@ int GLimp_SetMode( unsigned int *pwidth, unsigned int *pheight, int mode, qboole 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 @@ -901,6 +913,13 @@ void GLimp_Shutdown( void ) XDestroyWindow(dpy, win); if (ctx) qglXDestroyContext(dpy, ctx); + 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); @@ -967,6 +986,27 @@ void GLimp_EndFrame (void) qglXSwapBuffers(dpy, win); } +/* 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; + ri.Con_Printf(PRINT_ALL, "Setting gamma to %f\n", g); + XF86VidModeSetGamma(dpy, scrnum, &gamma); +} + /* ** GLimp_AppActivate */ diff --git a/src/gl_image.c b/src/gl_image.c index 1323b9d..2c1d919 100644 --- a/src/gl_image.c +++ b/src/gl_image.c @@ -1,22 +1,23 @@ -/* -Copyright (C) 1997-2001 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ +/* $Id$ + * + * Copyright (C) 1997-2001 Id Software, Inc. + * Copyright (c) 2002 The Quakeforge Project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #include "gl_local.h" @@ -1537,8 +1538,7 @@ void GL_InitImages (void) for ( i = 0; i < 256; i++ ) { - if ( g == 1 ) - { + if (g == 1 || gl_state.hwgamma) { gammatable[i] = i; } else diff --git a/src/gl_local.h b/src/gl_local.h index 526e1af..9a66558 100644 --- a/src/gl_local.h +++ b/src/gl_local.h @@ -1,22 +1,23 @@ -/* -Copyright (C) 1997-2001 Id Software, Inc. - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -*/ +/* $Id$ + * + * Copyright (C) 1997-2001 Id Software, Inc. + * Copyright (c) 2002 The Quakeforge Project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ #ifdef _WIN32 # include @@ -428,6 +429,8 @@ typedef struct float camera_separation; qboolean stereo_enabled; + qboolean hwgamma; + unsigned char originalRedGammaTable[256]; unsigned char originalGreenGammaTable[256]; unsigned char originalBlueGammaTable[256]; diff --git a/src/gl_rmain.c b/src/gl_rmain.c index 60b174c..ca67f1c 100644 --- a/src/gl_rmain.c +++ b/src/gl_rmain.c @@ -1446,6 +1446,9 @@ void R_Shutdown (void) R_BeginFrame @@@@@@@@@@@@@@@@@@@@@ */ + +extern void UpdateHardwareGamma(); + void R_BeginFrame( float camera_separation ) { @@ -1481,8 +1484,9 @@ void R_BeginFrame( float camera_separation ) { 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; diff --git a/src/vid_menu.c b/src/vid_menu.c index 8e0856b..e1fa083 100644 --- a/src/vid_menu.c +++ b/src/vid_menu.c @@ -111,7 +111,8 @@ static void BrightnessCallback( void *s ) if ( Q_stricmp( vid_ref->string, "soft" ) == 0 || Q_stricmp( vid_ref->string, "softx" ) == 0 || - Q_stricmp( vid_ref->string, "softsdl" ) == 0 ) + Q_stricmp( vid_ref->string, "softsdl" ) == 0 || + Q_stricmp( vid_ref->string, "glx" ) == 0 ) { float gamma = ( 0.8 - ( slider->curvalue/10.0 - 0.5 ) ) + 0.5;