From: havoc Date: Tue, 3 Apr 2018 05:33:43 +0000 (+0000) Subject: UNMERGE! Remove v_hwgamma feature as it is not worth maintaining and has severe restr... X-Git-Tag: xonotic-v0.8.5~55 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=f13f171c10213c7320357226bb3fe361a52536ad;p=xonotic%2Fdarkplaces.git UNMERGE! Remove v_hwgamma feature as it is not worth maintaining and has severe restrictions on Windows that are unintuitive. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12359 d7cf8633-e32d-0410-b094-e92efae38249 ::stable-branch::unmerge=77af8a073b9006fbdf7aa2e7bc92dba2f22b25af --- diff --git a/cl_screen.c b/cl_screen.c index 771d27c9..68bf62da 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -56,6 +56,7 @@ cvar_t scr_screenshot_jpeg = {CVAR_SAVE, "scr_screenshot_jpeg","1", "save jpeg i cvar_t scr_screenshot_jpeg_quality = {CVAR_SAVE, "scr_screenshot_jpeg_quality","0.9", "image quality of saved jpeg"}; cvar_t scr_screenshot_png = {CVAR_SAVE, "scr_screenshot_png","0", "save png instead of targa"}; cvar_t scr_screenshot_gammaboost = {CVAR_SAVE, "scr_screenshot_gammaboost","1", "gamma correction on saved screenshots and videos, 1.0 saves unmodified images"}; +cvar_t scr_screenshot_hwgamma = {CVAR_SAVE, "scr_screenshot_hwgamma","1", "apply the video gamma ramp to saved screenshots and videos"}; cvar_t scr_screenshot_alpha = {0, "scr_screenshot_alpha","0", "try to write an alpha channel to screenshots (debugging feature)"}; cvar_t scr_screenshot_timestamp = {CVAR_SAVE, "scr_screenshot_timestamp", "1", "use a timestamp based number of the type YYYYMMDDHHMMSSsss instead of sequential numbering"}; // scr_screenshot_name is defined in fs.c @@ -115,6 +116,7 @@ cvar_t r_speeds_graph_maxdefault = {CVAR_SAVE, "r_speeds_graph_maxdefault", "100 extern cvar_t v_glslgamma; extern cvar_t sbar_info_pos; extern cvar_t r_fog_clear; +#define WANT_SCREENSHOT_HWGAMMA (scr_screenshot_hwgamma.integer && vid_usinghwgamma) int jpeg_supported = false; @@ -1362,6 +1364,7 @@ void CL_Screen_Init(void) Cvar_RegisterVariable (&scr_screenshot_jpeg_quality); Cvar_RegisterVariable (&scr_screenshot_png); Cvar_RegisterVariable (&scr_screenshot_gammaboost); + Cvar_RegisterVariable (&scr_screenshot_hwgamma); Cvar_RegisterVariable (&scr_screenshot_name_in_mapdir); Cvar_RegisterVariable (&scr_screenshot_alpha); Cvar_RegisterVariable (&scr_screenshot_timestamp); @@ -1608,10 +1611,17 @@ Cb = R * -.169 + G * -.332 + B * .500 + 128.; Cr = R * .500 + G * -.419 + B * -.0813 + 128.; */ - // identity gamma table - BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, cls.capturevideo.vidramp, 256); - BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, cls.capturevideo.vidramp + 256, 256); - BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, cls.capturevideo.vidramp + 256*2, 256); + if(WANT_SCREENSHOT_HWGAMMA) + { + VID_BuildGammaTables(&cls.capturevideo.vidramp[0], 256); + } + else + { + // identity gamma table + BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, cls.capturevideo.vidramp, 256); + BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, cls.capturevideo.vidramp + 256, 256); + BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, cls.capturevideo.vidramp + 256*2, 256); + } if(scr_screenshot_gammaboost.value != 1) { double igamma = 1 / scr_screenshot_gammaboost.value; @@ -1997,15 +2007,22 @@ qboolean SCR_ScreenShot(char *filename, unsigned char *buffer1, unsigned char *b GL_ReadPixelsBGRA(x, y, width, height, buffer1); - if(gammacorrect && (scr_screenshot_gammaboost.value != 1)) + if(gammacorrect && (scr_screenshot_gammaboost.value != 1 || WANT_SCREENSHOT_HWGAMMA)) { int i; double igamma = 1.0 / scr_screenshot_gammaboost.value; unsigned short vidramp[256 * 3]; - // identity gamma table - BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, vidramp, 256); - BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, vidramp + 256, 256); - BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, vidramp + 256*2, 256); + if(WANT_SCREENSHOT_HWGAMMA) + { + VID_BuildGammaTables(&vidramp[0], 256); + } + else + { + // identity gamma table + BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, vidramp, 256); + BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, vidramp + 256, 256); + BuildGammaTable16(1.0f, 1.0f, 1.0f, 0.0f, 1.0f, vidramp + 256*2, 256); + } if(scr_screenshot_gammaboost.value != 1) { for (i = 0;i < 256 * 3;i++) diff --git a/gl_draw.c b/gl_draw.c index 66f6de4f..eae39c74 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -2167,11 +2167,13 @@ void R_DrawGamma(void) case RENDERPATH_D3D10: case RENDERPATH_D3D11: case RENDERPATH_GLES2: - if (v_glslgamma.integer) + if (vid_usinghwgamma || v_glslgamma.integer) return; break; case RENDERPATH_GL11: case RENDERPATH_GL13: + if (vid_usinghwgamma) + return; break; case RENDERPATH_GLES1: case RENDERPATH_SOFT: diff --git a/menu.c b/menu.c index 5ad0755a..44b5f568 100644 --- a/menu.c +++ b/menu.c @@ -2124,6 +2124,8 @@ static void M_Menu_Options_ColorControl_AdjustSliders (int dir) optnum = 1; if (options_colorcontrol_cursor == optnum++) + Cvar_SetValueQuick (&v_hwgamma, !v_hwgamma.integer); + else if (options_colorcontrol_cursor == optnum++) { Cvar_SetValueQuick (&v_color_enable, 0); Cvar_SetValueQuick (&v_gamma, bound(1, v_gamma.value + dir * 0.125, 5)); @@ -2234,6 +2236,7 @@ static void M_Options_ColorControl_Draw (void) m_opty = 32 - bound(0, m_optcursor - (visible >> 1), max(0, OPTIONS_COLORCONTROL_ITEMS - visible)) * 8; M_Options_PrintCommand( " Reset to defaults", true); + M_Options_PrintCheckbox("Hardware Gamma Control", vid_hardwaregammasupported.integer, v_hwgamma.integer); M_Options_PrintSlider( " Gamma", !v_color_enable.integer, v_gamma.value, 1, 5); M_Options_PrintSlider( " Contrast", !v_color_enable.integer, v_contrast.value, 1, 5); M_Options_PrintSlider( " Brightness", !v_color_enable.integer, v_brightness.value, 0, 0.8); @@ -2267,7 +2270,8 @@ static void M_Options_ColorControl_Draw (void) c[0] = menu_options_colorcontrol_correctionvalue.value; // intensity value that should be matched up to a 50% dither to 'correct' quake c[1] = c[0]; c[2] = c[1]; - VID_ApplyGammaToColor(c, c); + if (!(vid_hardwaregammasupported.integer && v_hwgamma.integer)) + VID_ApplyGammaToColor(c, c); s = (float) 48 / 2 * vid.width / vid_conwidth.integer; t = (float) 48 / 2 * vid.height / vid_conheight.integer; u = s * 0.5; @@ -2305,6 +2309,7 @@ static void M_Options_ColorControl_Key (int k, int ascii) switch (options_colorcontrol_cursor) { case 0: + Cvar_SetValueQuick(&v_hwgamma, 1); Cvar_SetValueQuick(&v_gamma, 1); Cvar_SetValueQuick(&v_contrast, 1); Cvar_SetValueQuick(&v_brightness, 0); diff --git a/vid.h b/vid.h index 91c42f0a..73999c48 100644 --- a/vid.h +++ b/vid.h @@ -111,8 +111,8 @@ typedef struct viddef_s qboolean stencil; qboolean sRGB2D; // whether 2D rendering is sRGB corrected (based on sRGBcapable2D) qboolean sRGB3D; // whether 3D rendering is sRGB corrected (based on sRGBcapable3D) - qboolean sRGBcapable2D; // whether 2D rendering can be sRGB corrected (renderpath) - qboolean sRGBcapable3D; // whether 3D rendering can be sRGB corrected (renderpath) + qboolean sRGBcapable2D; // whether 2D rendering can be sRGB corrected (renderpath, v_hwgamma) + qboolean sRGBcapable3D; // whether 3D rendering can be sRGB corrected (renderpath, v_hwgamma) renderpath_t renderpath; qboolean forcevbo; // some renderpaths can not operate without it @@ -177,6 +177,8 @@ void VID_EnableJoystick(qboolean enable); extern qboolean vid_hidden; extern qboolean vid_activewindow; +extern cvar_t vid_hardwaregammasupported; +extern qboolean vid_usinghwgamma; extern qboolean vid_supportrefreshrate; extern cvar_t vid_soft; @@ -222,6 +224,7 @@ extern cvar_t v_color_grey_b; extern cvar_t v_color_white_r; extern cvar_t v_color_white_g; extern cvar_t v_color_white_b; +extern cvar_t v_hwgamma; // brand of graphics chip extern const char *gl_vendor; @@ -263,9 +266,20 @@ qboolean VID_InitMode(viddef_mode_t *mode); // allocates and opens an appropriate OpenGL context (and its window) -// updates cachegamma variables and bumps vid_gammatables_serial if anything changed +// sets hardware gamma correction, returns false if the device does not +// support gamma control +// (ONLY called by VID_UpdateGamma and VID_RestoreSystemGamma) +int VID_SetGamma(unsigned short *ramps, int rampsize); +// gets hardware gamma correction, returns false if the device does not +// support gamma control +// (ONLY called by VID_UpdateGamma and VID_RestoreSystemGamma) +int VID_GetGamma(unsigned short *ramps, int rampsize); +// makes sure ramp arrays are big enough and calls VID_GetGamma/VID_SetGamma // (ONLY to be called from VID_Finish!) -void VID_UpdateGamma(void); +void VID_UpdateGamma(qboolean force, int rampsize); +// turns off hardware gamma ramps immediately +// (called from various shutdown/deactivation functions) +void VID_RestoreSystemGamma(void); qboolean VID_HasScreenKeyboardSupport(void); void VID_ShowKeyboard(qboolean show); diff --git a/vid_agl.c b/vid_agl.c index 4fd603ea..bacbb5ff 100644 --- a/vid_agl.c +++ b/vid_agl.c @@ -190,6 +190,7 @@ void VID_SetMouse(qboolean fullscreengrab, qboolean relative, qboolean hidecurso } } +#define GAMMA_TABLE_SIZE 256 void VID_Finish (void) { qboolean vid_usevsync; @@ -215,7 +216,7 @@ void VID_Finish (void) GL_Finish(); qaglSwapBuffers(context); } - VID_UpdateGamma(); + VID_UpdateGamma(false, GAMMA_TABLE_SIZE); if (apple_multithreadedgl.integer) { @@ -254,9 +255,65 @@ void VID_Finish (void) } } +int VID_SetGamma(unsigned short *ramps, int rampsize) +{ + CGGammaValue table_red [GAMMA_TABLE_SIZE]; + CGGammaValue table_green [GAMMA_TABLE_SIZE]; + CGGammaValue table_blue [GAMMA_TABLE_SIZE]; + int i; + + // Convert the unsigned short table into 3 float tables + for (i = 0; i < rampsize; i++) + table_red[i] = (float)ramps[i] / 65535.0f; + for (i = 0; i < rampsize; i++) + table_green[i] = (float)ramps[i + rampsize] / 65535.0f; + for (i = 0; i < rampsize; i++) + table_blue[i] = (float)ramps[i + 2 * rampsize] / 65535.0f; + + if (CGSetDisplayTransferByTable(CGMainDisplayID(), rampsize, table_red, table_green, table_blue) != CGDisplayNoErr) + { + Con_Print("VID_SetGamma: ERROR: CGSetDisplayTransferByTable failed!\n"); + return false; + } + + return true; +} + +int VID_GetGamma(unsigned short *ramps, int rampsize) +{ + CGGammaValue table_red [GAMMA_TABLE_SIZE]; + CGGammaValue table_green [GAMMA_TABLE_SIZE]; + CGGammaValue table_blue [GAMMA_TABLE_SIZE]; + CGTableCount actualsize = 0; + int i; + + // Get the gamma ramps from the system + if (CGGetDisplayTransferByTable(CGMainDisplayID(), rampsize, table_red, table_green, table_blue, &actualsize) != CGDisplayNoErr) + { + Con_Print("VID_GetGamma: ERROR: CGGetDisplayTransferByTable failed!\n"); + return false; + } + if (actualsize != (unsigned int)rampsize) + { + Con_Printf("VID_GetGamma: ERROR: invalid gamma table size (%u != %u)\n", actualsize, rampsize); + return false; + } + + // Convert the 3 float tables into 1 unsigned short table + for (i = 0; i < rampsize; i++) + ramps[i] = table_red[i] * 65535.0f; + for (i = 0; i < rampsize; i++) + ramps[i + rampsize] = table_green[i] * 65535.0f; + for (i = 0; i < rampsize; i++) + ramps[i + 2 * rampsize] = table_blue[i] * 65535.0f; + + return true; +} + void signal_handler(int sig) { Sys_PrintfToTerminal("Received signal %d, exiting...\n", sig); + VID_RestoreSystemGamma(); Sys_Quit(1); } @@ -341,6 +398,7 @@ void VID_Shutdown(void) VID_EnableJoystick(false); VID_SetMouse(false, false, false); + VID_RestoreSystemGamma(); if (context != NULL) { @@ -398,7 +456,11 @@ static OSStatus MainWindowEventHandler (EventHandlerCallRef nextHandler, EventRe static void VID_AppFocusChanged(qboolean windowIsActive) { if (vid_activewindow != windowIsActive) + { vid_activewindow = windowIsActive; + if (!vid_activewindow) + VID_RestoreSystemGamma(); + } if (windowIsActive || !snd_mutewhenidle.integer) { diff --git a/vid_glx.c b/vid_glx.c index fc8766d8..8327b260 100644 --- a/vid_glx.c +++ b/vid_glx.c @@ -119,9 +119,11 @@ static qboolean vid_usingmouse = false; static qboolean vid_usinghidecursor = false; static qboolean vid_usingvsync = false; static qboolean vid_usevsync = false; +static qboolean vid_x11_hardwaregammasupported = false; #ifdef USEDGA static qboolean vid_x11_dgasupported = false; #endif +static int vid_x11_gammarampsize = 0; #ifdef USEDGA cvar_t vid_dgamouse = {CVAR_SAVE, "vid_dgamouse", "0", "make use of DGA mouse input"}; @@ -703,6 +705,7 @@ static void HandleEvents(void) break; // window restored vid_hidden = false; + VID_RestoreSystemGamma(); if(vid_isvidmodefullscreen) { @@ -739,6 +742,7 @@ static void HandleEvents(void) break; // window iconified/rolledup/whatever vid_hidden = true; + VID_RestoreSystemGamma(); if(vid_isvidmodefullscreen) XF86VidModeSwitchToMode(vidx11_display, vidx11_screen, &init_vidmode); @@ -775,6 +779,7 @@ static void HandleEvents(void) // window is no longer the input focus vid_activewindow = false; + VID_RestoreSystemGamma(); break; case EnterNotify: @@ -850,6 +855,7 @@ void VID_Shutdown(void) VID_EnableJoystick(false); VID_SetMouse(false, false, false); + VID_RestoreSystemGamma(); // FIXME: glXDestroyContext here? if (vid_isvidmodefullscreen) @@ -887,6 +893,7 @@ void VID_Shutdown(void) static void signal_handler(int sig) { Con_Printf("Received signal %d, exiting...\n", sig); + VID_RestoreSystemGamma(); Sys_Quit(1); } @@ -962,7 +969,17 @@ void VID_Finish (void) } if (vid_x11_hardwaregammasupported) - VID_UpdateGamma(); + VID_UpdateGamma(false, vid_x11_gammarampsize); +} + +int VID_SetGamma(unsigned short *ramps, int rampsize) +{ + return XF86VidModeSetGammaRamp(vidx11_display, vidx11_screen, rampsize, ramps, ramps + rampsize, ramps + rampsize*2); +} + +int VID_GetGamma(unsigned short *ramps, int rampsize) +{ + return XF86VidModeGetGammaRamp(vidx11_display, vidx11_screen, rampsize, ramps, ramps + rampsize, ramps + rampsize*2); } void VID_Init(void) @@ -1299,6 +1316,7 @@ static qboolean VID_InitModeSoft(viddef_mode_t *mode) vid_usingvsync = false; vid_hidden = false; vid_activewindow = true; + vid_x11_hardwaregammasupported = XF86VidModeGetGammaRampSize(vidx11_display, vidx11_screen, &vid_x11_gammarampsize) != 0; #ifdef USEDGA vid_x11_dgasupported = XF86DGAQueryVersion(vidx11_display, &MajorVersion, &MinorVersion); if (!vid_x11_dgasupported) @@ -1645,6 +1663,7 @@ static qboolean VID_InitModeGL(viddef_mode_t *mode) vid_usingvsync = false; vid_hidden = false; vid_activewindow = true; + vid_x11_hardwaregammasupported = XF86VidModeGetGammaRampSize(vidx11_display, vidx11_screen, &vid_x11_gammarampsize) != 0; #ifdef USEDGA vid_x11_dgasupported = XF86DGAQueryVersion(vidx11_display, &MajorVersion, &MinorVersion); if (!vid_x11_dgasupported) diff --git a/vid_null.c b/vid_null.c index 4a133358..a5399779 100644 --- a/vid_null.c +++ b/vid_null.c @@ -59,6 +59,16 @@ void VID_Finish (void) { } +int VID_SetGamma(unsigned short *ramps, int rampsize) +{ + return FALSE; +} + +int VID_GetGamma(unsigned short *ramps, int rampsize) +{ + return FALSE; +} + void VID_Init(void) { InitSig(); // trap evil signals diff --git a/vid_sdl.c b/vid_sdl.c index dc210ad4..98d6567e 100644 --- a/vid_sdl.c +++ b/vid_sdl.c @@ -2848,6 +2848,7 @@ void VID_Shutdown (void) { VID_EnableJoystick(false); VID_SetMouse(false, false, false); + VID_RestoreSystemGamma(); #if SDL_MAJOR_VERSION == 1 #ifndef WIN32 @@ -2880,6 +2881,24 @@ void VID_Shutdown (void) gl_platformextensions = ""; } +int VID_SetGamma (unsigned short *ramps, int rampsize) +{ +#if SDL_MAJOR_VERSION == 1 + return !SDL_SetGammaRamp (ramps, ramps + rampsize, ramps + rampsize*2); +#else + return !SDL_SetWindowGammaRamp (window, ramps, ramps + rampsize, ramps + rampsize*2); +#endif +} + +int VID_GetGamma (unsigned short *ramps, int rampsize) +{ +#if SDL_MAJOR_VERSION == 1 + return !SDL_GetGammaRamp (ramps, ramps + rampsize, ramps + rampsize*2); +#else + return !SDL_GetWindowGammaRamp (window, ramps, ramps + rampsize, ramps + rampsize*2); +#endif +} + void VID_Finish (void) { #if SDL_MAJOR_VERSION == 1 @@ -2893,7 +2912,7 @@ void VID_Finish (void) #endif vid_activewindow = !vid_hidden && vid_hasfocus; - VID_UpdateGamma(); + VID_UpdateGamma(false, 256); if (!vid_hidden) { diff --git a/vid_shared.c b/vid_shared.c index 129641cf..843707b4 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -140,6 +140,9 @@ cvar_t vid_soft = {CVAR_SAVE, "vid_soft", "0", "enables use of the DarkPlaces So cvar_t vid_soft_threads = {CVAR_SAVE, "vid_soft_threads", "8", "the number of threads the DarkPlaces Software Rasterizer should use"}; cvar_t vid_soft_interlace = {CVAR_SAVE, "vid_soft_interlace", "1", "whether the DarkPlaces Software Rasterizer should interlace the screen bands occupied by each thread"}; +// we don't know until we try it! +cvar_t vid_hardwaregammasupported = {CVAR_READONLY,"vid_hardwaregammasupported","1", "indicates whether hardware gamma is supported (updated by attempts to set hardware gamma ramps)"}; + // VorteX: more info cvars, mostly set in VID_CheckExtensions cvar_t gl_info_vendor = {CVAR_READONLY, "gl_info_vendor", "", "indicates brand of graphics chip"}; cvar_t gl_info_renderer = {CVAR_READONLY, "gl_info_renderer", "", "indicates graphics chip model and other information"}; @@ -148,6 +151,13 @@ cvar_t gl_info_extensions = {CVAR_READONLY, "gl_info_extensions", "", "indicates cvar_t gl_info_platform = {CVAR_READONLY, "gl_info_platform", "", "indicates GL platform: WGL, GLX, or AGL."}; cvar_t gl_info_driver = {CVAR_READONLY, "gl_info_driver", "", "name of driver library (opengl32.dll, libGL.so.1, or whatever)."}; +// whether hardware gamma ramps are currently in effect +qboolean vid_usinghwgamma = false; + +int vid_gammarampsize = 0; +unsigned short *vid_gammaramps = NULL; +unsigned short *vid_systemgammaramps = NULL; + cvar_t vid_fullscreen = {CVAR_SAVE, "vid_fullscreen", "1", "use fullscreen (1) or windowed (0)"}; cvar_t vid_width = {CVAR_SAVE, "vid_width", "640", "resolution"}; cvar_t vid_height = {CVAR_SAVE, "vid_height", "480", "resolution"}; @@ -195,9 +205,10 @@ cvar_t v_color_grey_b = {CVAR_SAVE, "v_color_grey_b", "0.5", "desired color of g cvar_t v_color_white_r = {CVAR_SAVE, "v_color_white_r", "1", "desired color of white"}; cvar_t v_color_white_g = {CVAR_SAVE, "v_color_white_g", "1", "desired color of white"}; cvar_t v_color_white_b = {CVAR_SAVE, "v_color_white_b", "1", "desired color of white"}; -cvar_t v_glslgamma = {CVAR_SAVE, "v_glslgamma", "1", "enables use of GLSL to apply gamma correction ramps"}; +cvar_t v_hwgamma = {CVAR_SAVE, "v_hwgamma", "0", "enables use of hardware gamma correction ramps if available (note: does not work very well on Windows2000 and above), values are 0 = off, 1 = attempt to use hardware gamma, 2 = use hardware gamma whether it works or not"}; +cvar_t v_glslgamma = {CVAR_SAVE, "v_glslgamma", "1", "enables use of GLSL to apply gamma correction ramps if available (note: overrides v_hwgamma)"}; cvar_t v_glslgamma_2d = {CVAR_SAVE, "v_glslgamma_2d", "0", "applies GLSL gamma to 2d pictures (HUD, fonts)"}; -cvar_t v_psycho = {0, "v_psycho", "0", "easter egg - R.I.P. zinx http://obits.al.com/obituaries/birmingham/obituary.aspx?n=christopher-robert-lais&pid=186080667"}; +cvar_t v_psycho = {0, "v_psycho", "0", "easter egg"}; // brand of graphics chip const char *gl_vendor; @@ -1463,7 +1474,7 @@ static void Force_CenterView_f (void) static int gamma_forcenextframe = false; static float cachegamma, cachebrightness, cachecontrast, cacheblack[3], cachegrey[3], cachewhite[3], cachecontrastboost; -static int cachecolorenable; +static int cachecolorenable, cachehwgamma; void VID_ApplyGammaToColor(const float *rgb, float *out) { @@ -1507,8 +1518,6 @@ void VID_BuildGammaTables(unsigned short *ramps, int rampsize) // LordHavoc: this code came from Ben Winslow and Zinx Verituse, I have // immensely butchered it to work with variable framerates and fit in with // the rest of darkplaces. - // - // R.I.P. zinx http://obits.al.com/obituaries/birmingham/obituary.aspx?n=christopher-robert-lais&pid=186080667 if (v_psycho.integer) { int x, y; @@ -1546,12 +1555,36 @@ void VID_BuildGammaTables(unsigned short *ramps, int rampsize) } } -void VID_UpdateGamma(void) +void VID_UpdateGamma(qboolean force, int rampsize) { cvar_t *c; float f; + int wantgamma; qboolean gamma_changed = false; + // LordHavoc: don't mess with gamma tables if running dedicated + if (cls.state == ca_dedicated) + return; + + wantgamma = v_hwgamma.integer; + switch(vid.renderpath) + { + case RENDERPATH_GL20: + case RENDERPATH_D3D9: + case RENDERPATH_D3D10: + case RENDERPATH_D3D11: + case RENDERPATH_SOFT: + case RENDERPATH_GLES2: + if (v_glslgamma.integer) + wantgamma = 0; + break; + case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GLES1: + break; + } + if(!vid_activewindow) + wantgamma = 0; #define BOUNDCVAR(cvar, m1, m2) c = &(cvar);f = bound(m1, c->value, m2);if (c->value != f) Cvar_SetValueQuick(c, f); BOUNDCVAR(v_gamma, 0.1, 5); BOUNDCVAR(v_contrast, 0.2, 5); @@ -1597,7 +1630,6 @@ void VID_UpdateGamma(void) } } - // if any gamma settings were changed, bump vid_gammatables_serial so we regenerate the gamma ramp texture #define GAMMACHECK(cache, value) if (cache != (value)) gamma_changed = true;cache = (value) if(v_psycho.integer) gamma_changed = true; @@ -1618,7 +1650,64 @@ void VID_UpdateGamma(void) if(gamma_changed) ++vid_gammatables_serial; + + GAMMACHECK(cachehwgamma , wantgamma); #undef GAMMACHECK + + if (!force && !gamma_forcenextframe && !gamma_changed) + return; + + gamma_forcenextframe = false; + + if (cachehwgamma) + { + if (!vid_usinghwgamma) + { + vid_usinghwgamma = true; + if (vid_gammarampsize != rampsize || !vid_gammaramps) + { + vid_gammarampsize = rampsize; + if (vid_gammaramps) + Z_Free(vid_gammaramps); + vid_gammaramps = (unsigned short *)Z_Malloc(6 * vid_gammarampsize * sizeof(unsigned short)); + vid_systemgammaramps = vid_gammaramps + 3 * vid_gammarampsize; + } + VID_GetGamma(vid_systemgammaramps, vid_gammarampsize); + } + + VID_BuildGammaTables(vid_gammaramps, vid_gammarampsize); + + // set vid_hardwaregammasupported to true if VID_SetGamma succeeds, OR if vid_hwgamma is >= 2 (forced gamma - ignores driver return value) + Cvar_SetValueQuick(&vid_hardwaregammasupported, VID_SetGamma(vid_gammaramps, vid_gammarampsize) || cachehwgamma >= 2); + // if custom gamma ramps failed (Windows stupidity), restore to system gamma + if(!vid_hardwaregammasupported.integer) + { + if (vid_usinghwgamma) + { + vid_usinghwgamma = false; + VID_SetGamma(vid_systemgammaramps, vid_gammarampsize); + } + } + } + else + { + if (vid_usinghwgamma) + { + vid_usinghwgamma = false; + VID_SetGamma(vid_systemgammaramps, vid_gammarampsize); + } + } +} + +void VID_RestoreSystemGamma(void) +{ + if (vid_usinghwgamma) + { + vid_usinghwgamma = false; + Cvar_SetValueQuick(&vid_hardwaregammasupported, VID_SetGamma(vid_systemgammaramps, vid_gammarampsize)); + // force gamma situation to be reexamined next frame + gamma_forcenextframe = true; + } } #ifdef WIN32 @@ -1654,6 +1743,7 @@ void VID_Shared_Init(void) Con_Printf("DPSOFTRAST not available (SSE2 not compiled in)\n"); #endif + Cvar_RegisterVariable(&vid_hardwaregammasupported); Cvar_RegisterVariable(&gl_info_vendor); Cvar_RegisterVariable(&gl_info_renderer); Cvar_RegisterVariable(&gl_info_version); @@ -1676,6 +1766,7 @@ void VID_Shared_Init(void) Cvar_RegisterVariable(&v_color_white_g); Cvar_RegisterVariable(&v_color_white_b); + Cvar_RegisterVariable(&v_hwgamma); Cvar_RegisterVariable(&v_glslgamma); Cvar_RegisterVariable(&v_glslgamma_2d); diff --git a/vid_wgl.c b/vid_wgl.c index 329e57df..fbb027c3 100644 --- a/vid_wgl.c +++ b/vid_wgl.c @@ -321,7 +321,7 @@ void VID_Finish (void) // without this help Sleep(0); - VID_UpdateGamma(); + VID_UpdateGamma(false, 256); } //========================================================================== @@ -498,6 +498,7 @@ void AppActivate(BOOL fActive, BOOL minimize) ChangeDisplaySettings (NULL, CDS_FULLSCREEN); vid_wassuspended = true; } + VID_RestoreSystemGamma(); } } @@ -710,6 +711,32 @@ LONG WINAPI MainWndProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return lRet; } +int VID_SetGamma(unsigned short *ramps, int rampsize) +{ + if (qwglMakeCurrent) + { + HDC hdc = GetDC (NULL); + int i = SetDeviceGammaRamp(hdc, ramps); + ReleaseDC (NULL, hdc); + return i; // return success or failure + } + else + return 0; +} + +int VID_GetGamma(unsigned short *ramps, int rampsize) +{ + if (qwglMakeCurrent) + { + HDC hdc = GetDC (NULL); + int i = GetDeviceGammaRamp(hdc, ramps); + ReleaseDC (NULL, hdc); + return i; // return success or failure + } + else + return 0; +} + static void GL_CloseLibrary(void) { if (gldll) @@ -1843,6 +1870,7 @@ void VID_Shutdown (void) VID_EnableJoystick(false); VID_SetMouse(false, false, false); + VID_RestoreSystemGamma(); vid_initialized = false; isgl = gldll != NULL;