From ccfffc6fdc1025385239f352851c4a69238fc0a7 Mon Sep 17 00:00:00 2001 From: aignacio_sf <> Date: Wed, 12 Sep 2007 20:56:20 +0000 Subject: [PATCH] Save and restore original gamma settings. Compute gamma relative to original gamma settings. --- panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx | 93 ++++++++++++++++- panda/src/dxgsg8/dxGraphicsStateGuardian8.h | 1 + panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx | 94 +++++++++++++++++- panda/src/dxgsg9/dxGraphicsStateGuardian9.h | 1 + .../wgldisplay/wglGraphicsStateGuardian.cxx | 99 ++++++++++++++++++- .../src/wgldisplay/wglGraphicsStateGuardian.h | 1 + 6 files changed, 280 insertions(+), 9 deletions(-) diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 558090d90d..a5541de340 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -119,6 +119,7 @@ DXGraphicsStateGuardian8(GraphicsPipe *pipe) : Geom::GR_triangle_strip | Geom::GR_triangle_fan | Geom::GR_flat_first_vertex; + get_gamma_table(); atexit (atexit_function); } @@ -4267,6 +4268,88 @@ calc_fb_properties(DWORD cformat, DWORD dformat, DWORD multisampletype) { return props; } +#define GAMMA_1 (255.0 * 256.0) + +static bool _gamma_table_initialized = false; +static unsigned short _orignial_gamma_table [256 * 3]; + +void _create_gamma_table (float gamma, unsigned short *original_red_table, unsigned short *original_green_table, unsigned short *original_blue_table, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table) { + int i; + double gamma_correction; + + if (gamma <= 0.0) { + // avoid divide by zero and negative exponents + gamma = 1.0; + } + gamma_correction = 1.0 / (double) gamma; + + for (i = 0; i < 256; i++) { + double r; + double g; + double b; + + if (original_red_table) { + r = (double) original_red_table [i] / GAMMA_1; + g = (double) original_green_table [i] / GAMMA_1; + b = (double) original_blue_table [i] / GAMMA_1; + } + else { + r = ((double) i / 255.0); + g = r; + b = r; + } + + r = pow (r, gamma_correction); + g = pow (g, gamma_correction); + b = pow (b, gamma_correction); + + if (r > 1.00) { + r = 1.0; + } + if (g > 1.00) { + g = 1.0; + } + if (b > 1.00) { + b = 1.0; + } + + r = r * GAMMA_1; + g = g * GAMMA_1; + b = b * GAMMA_1; + + red_table [i] = r; + green_table [i] = g; + blue_table [i] = b; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian8::get_gamma_table +// Access: Public, Static +// Description: Static function for getting the original gamma. +//////////////////////////////////////////////////////////////////// + +bool DXGraphicsStateGuardian8:: +get_gamma_table(void) { + bool get; + + get = false; + if (_gamma_table_initialized == false) { + HDC hdc = GetDC(NULL); + + if (hdc) { + if (GetDeviceGammaRamp (hdc, (LPVOID) _orignial_gamma_table)) { + _gamma_table_initialized = true; + get = true; + } + + ReleaseDC (NULL, hdc); + } + } + + return get; +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian8::static_set_gamma // Access: Public, Static @@ -4281,8 +4364,14 @@ static_set_gamma(float gamma) { set = false; if (hdc) { unsigned short ramp [256 * 3]; - - GraphicsStateGuardian::create_gamma_table (gamma, &ramp [0], &ramp [256], &ramp [512]); + + if (_gamma_table_initialized) { + _create_gamma_table (gamma, &_orignial_gamma_table [0], &_orignial_gamma_table [256], &_orignial_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]); + } + else { + _create_gamma_table (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]); + } + if (SetDeviceGammaRamp (hdc, ramp)) { set = true; } diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 0da75a7abc..5494d9a587 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -123,6 +123,7 @@ public: const TransformState *transform); LPDIRECT3DDEVICE8 get_d3d_device(); + static bool get_gamma_table(void); static bool static_set_gamma(float gamma); bool set_gamma(float gamma); static void atexit_function(void); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index c05114b0f4..fc1508bcbc 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -158,6 +158,7 @@ DXGraphicsStateGuardian9(GraphicsPipe *pipe) : _supports_stream_offset = false; + get_gamma_table(); atexit (atexit_function); } @@ -5639,6 +5640,89 @@ calc_fb_properties(DWORD cformat, DWORD dformat, return props; } + +#define GAMMA_1 (255.0 * 256.0) + +static bool _gamma_table_initialized = false; +static unsigned short _orignial_gamma_table [256 * 3]; + +void _create_gamma_table (float gamma, unsigned short *original_red_table, unsigned short *original_green_table, unsigned short *original_blue_table, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table) { + int i; + double gamma_correction; + + if (gamma <= 0.0) { + // avoid divide by zero and negative exponents + gamma = 1.0; + } + gamma_correction = 1.0 / (double) gamma; + + for (i = 0; i < 256; i++) { + double r; + double g; + double b; + + if (original_red_table) { + r = (double) original_red_table [i] / GAMMA_1; + g = (double) original_green_table [i] / GAMMA_1; + b = (double) original_blue_table [i] / GAMMA_1; + } + else { + r = ((double) i / 255.0); + g = r; + b = r; + } + + r = pow (r, gamma_correction); + g = pow (g, gamma_correction); + b = pow (b, gamma_correction); + + if (r > 1.00) { + r = 1.0; + } + if (g > 1.00) { + g = 1.0; + } + if (b > 1.00) { + b = 1.0; + } + + r = r * GAMMA_1; + g = g * GAMMA_1; + b = b * GAMMA_1; + + red_table [i] = r; + green_table [i] = g; + blue_table [i] = b; + } +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::get_gamma_table +// Access: Public, Static +// Description: Static function for getting the original gamma. +//////////////////////////////////////////////////////////////////// + +bool DXGraphicsStateGuardian9:: +get_gamma_table(void) { + bool get; + + get = false; + if (_gamma_table_initialized == false) { + HDC hdc = GetDC(NULL); + + if (hdc) { + if (GetDeviceGammaRamp (hdc, (LPVOID) _orignial_gamma_table)) { + _gamma_table_initialized = true; + get = true; + } + + ReleaseDC (NULL, hdc); + } + } + + return get; +} + //////////////////////////////////////////////////////////////////// // Function: DXGraphicsStateGuardian9::static_set_gamma // Access: Public, Static @@ -5653,8 +5737,14 @@ static_set_gamma(float gamma) { set = false; if (hdc) { unsigned short ramp [256 * 3]; - - GraphicsStateGuardian::create_gamma_table (gamma, &ramp [0], &ramp [256], &ramp [512]); + + if (_gamma_table_initialized) { + _create_gamma_table (gamma, &_orignial_gamma_table [0], &_orignial_gamma_table [256], &_orignial_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]); + } + else { + _create_gamma_table (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]); + } + if (SetDeviceGammaRamp (hdc, ramp)) { set = true; } diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 732922dbb1..d0f78b1658 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -169,6 +169,7 @@ public: INLINE HRESULT set_texture_stage_state (DWORD stage, D3DTEXTURESTAGESTATETYPE type, DWORD value); INLINE HRESULT set_sampler_state (DWORD sampler, D3DSAMPLERSTATETYPE type, DWORD value); + static bool get_gamma_table(void); static bool static_set_gamma(float gamma); bool set_gamma(float gamma); static void atexit_function(void); diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx index 0ddf629fc0..8fbeab5348 100755 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx @@ -50,6 +50,7 @@ wglGraphicsStateGuardian(GraphicsPipe *pipe, _supports_pixel_format = false; _supports_wgl_multisample = false; + get_gamma_table(); atexit(atexit_function); } @@ -739,8 +740,90 @@ register_twindow_class() { _twindow_class_registered = true; } +#define GAMMA_1 (255.0 * 256.0) + +static bool _gamma_table_initialized = false; +static unsigned short _orignial_gamma_table [256 * 3]; + +void _create_gamma_table (float gamma, unsigned short *original_red_table, unsigned short *original_green_table, unsigned short *original_blue_table, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table) { + int i; + double gamma_correction; + + if (gamma <= 0.0) { + // avoid divide by zero and negative exponents + gamma = 1.0; + } + gamma_correction = 1.0 / (double) gamma; + + for (i = 0; i < 256; i++) { + double r; + double g; + double b; + + if (original_red_table) { + r = (double) original_red_table [i] / GAMMA_1; + g = (double) original_green_table [i] / GAMMA_1; + b = (double) original_blue_table [i] / GAMMA_1; + } + else { + r = ((double) i / 255.0); + g = r; + b = r; + } + + r = pow (r, gamma_correction); + g = pow (g, gamma_correction); + b = pow (b, gamma_correction); + + if (r > 1.00) { + r = 1.0; + } + if (g > 1.00) { + g = 1.0; + } + if (b > 1.00) { + b = 1.0; + } + + r = r * GAMMA_1; + g = g * GAMMA_1; + b = b * GAMMA_1; + + red_table [i] = r; + green_table [i] = g; + blue_table [i] = b; + } +} + //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian9::static_set_gamma +// Function: wglGraphicsStateGuardian::get_gamma_table +// Access: Public, Static +// Description: Static function for getting the original gamma. +//////////////////////////////////////////////////////////////////// + +bool wglGraphicsStateGuardian:: +get_gamma_table(void) { + bool get; + + get = false; + if (_gamma_table_initialized == false) { + HDC hdc = GetDC(NULL); + + if (hdc) { + if (GetDeviceGammaRamp (hdc, (LPVOID) _orignial_gamma_table)) { + _gamma_table_initialized = true; + get = true; + } + + ReleaseDC (NULL, hdc); + } + } + + return get; +} + +//////////////////////////////////////////////////////////////////// +// Function: wglGraphicsStateGuardian::static_set_gamma // Access: Public, Static // Description: Static function for setting gamma which is needed // for atexit. @@ -753,8 +836,14 @@ static_set_gamma(float gamma) { set = false; if (hdc) { unsigned short ramp [256 * 3]; - - GraphicsStateGuardian::create_gamma_table (gamma, &ramp [0], &ramp [256], &ramp [512]); + + if (_gamma_table_initialized) { + _create_gamma_table (gamma, &_orignial_gamma_table [0], &_orignial_gamma_table [256], &_orignial_gamma_table [512], &ramp [0], &ramp [256], &ramp [512]); + } + else { + _create_gamma_table (gamma, 0, 0, 0, &ramp [0], &ramp [256], &ramp [512]); + } + if (SetDeviceGammaRamp (hdc, ramp)) { set = true; } @@ -766,7 +855,7 @@ static_set_gamma(float gamma) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian9::set_gamma +// Function: wglGraphicsStateGuardian::set_gamma // Access: Published // Description: Non static version of setting gamma. Returns true // on success. @@ -784,7 +873,7 @@ set_gamma(float gamma) { } //////////////////////////////////////////////////////////////////// -// Function: DXGraphicsStateGuardian9::atexit_function +// Function: wglGraphicsStateGuardian::atexit_function // Access: Public, Static // Description: This function is passed to the atexit function. //////////////////////////////////////////////////////////////////// diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.h b/panda/src/wgldisplay/wglGraphicsStateGuardian.h index 726ab90557..99f93f9b53 100755 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.h +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.h @@ -50,6 +50,7 @@ public: INLINE HDC get_twindow_dc(); + static bool get_gamma_table(void); static bool static_set_gamma(float gamma); bool set_gamma(float gamma); static void atexit_function(void);