diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index c3bd39dd46..b821d20662 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/panda/src/display/graphicsStateGuardian.cxx @@ -202,6 +202,8 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system, // The default is no shader support. _auto_detect_shader_model = SM_00; _shader_model = SM_00; + + _gamma = 1.0f; } //////////////////////////////////////////////////////////////////// @@ -2063,3 +2065,57 @@ calc_projection_mat(const Lens *lens) { return TransformState::make_identity(); } +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::set_gamma +// Access: Published, Virtual +// Description: Set gamma. Returns true on success. +//////////////////////////////////////////////////////////////////// +bool GraphicsStateGuardian:: +set_gamma(float gamma) { + _gamma = gamma; + + return false; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::create_gamma_table +// Access: Published +// Description: Get the current gamma setting. +//////////////////////////////////////////////////////////////////// +float GraphicsStateGuardian:: +get_gamma(float gamma) { + return _gamma; +} + +//////////////////////////////////////////////////////////////////// +// Function: GraphicsStateGuardian::create_gamma_table +// Access: Public, Static +// Description: Create a gamma table. +//////////////////////////////////////////////////////////////////// +void GraphicsStateGuardian:: +create_gamma_table (float gamma, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table) { + int i; + + if (gamma <= 0.0) { + // avoid divide by zero and negative exponents + gamma = 1.0; + } + + for (i = 0; i < 256; i++) { + double g; + double x; + float gamma_correction; + + x = ((double) i / 255.0); + gamma_correction = 1.0 / gamma; + x = pow (x, (double) gamma_correction); + if (x > 1.00) { + x = 1.0; + } + + g = x * 65535.0; + red_table [i] = g; + green_table [i] = g; + blue_table [i] = g; + } +} diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index ee0c96c6cf..0afd704645 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/panda/src/display/graphicsStateGuardian.h @@ -151,6 +151,9 @@ PUBLISHED: virtual PreparedGraphicsObjects *get_prepared_objects(); + virtual bool set_gamma(float gamma); + float get_gamma(float gamma); + public: bool set_scene(SceneSetup *scene_setup); virtual SceneSetup *get_scene() const; @@ -262,6 +265,8 @@ public: INLINE void set_stencil_clear_value(unsigned int stencil_clear_value); INLINE unsigned int get_stencil_clear_value(); + static void create_gamma_table (float gamma, unsigned short *red_table, unsigned short *green_table, unsigned short *blue_table); + #ifdef DO_PSTATS static void init_frame_pstats(); #endif @@ -414,6 +419,8 @@ protected: ShaderExpansion::ShaderCaps _shader_caps; + float _gamma; + public: // Statistics static PStatCollector _vertex_buffer_switch_pcollector; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index 237a9b7ed6..558090d90d 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx @@ -118,6 +118,8 @@ DXGraphicsStateGuardian8(GraphicsPipe *pipe) : Geom::GR_indexed_other | Geom::GR_triangle_strip | Geom::GR_triangle_fan | Geom::GR_flat_first_vertex; + + atexit (atexit_function); } //////////////////////////////////////////////////////////////////// @@ -4265,3 +4267,56 @@ calc_fb_properties(DWORD cformat, DWORD dformat, DWORD multisampletype) { return props; } +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian8::static_set_gamma +// Access: Public, Static +// Description: Static function for setting gamma which is needed +// for atexit. +//////////////////////////////////////////////////////////////////// +bool DXGraphicsStateGuardian8:: +static_set_gamma(float gamma) { + bool set; + HDC hdc = GetDC(NULL); + + set = false; + if (hdc) { + unsigned short ramp [256 * 3]; + + GraphicsStateGuardian::create_gamma_table (gamma, &ramp [0], &ramp [256], &ramp [512]); + if (SetDeviceGammaRamp (hdc, ramp)) { + set = true; + } + + ReleaseDC (NULL, hdc); + } + + return set; +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian8::set_gamma +// Access: Published +// Description: Non static version of setting gamma. Returns true +// on success. +//////////////////////////////////////////////////////////////////// +bool DXGraphicsStateGuardian8:: +set_gamma(float gamma) { + bool set; + + set = static_set_gamma(gamma); + if (set) { + _gamma = gamma; + } + + return set; +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian8::atexit_function +// Access: Public, Static +// Description: This function is passed to the atexit function. +//////////////////////////////////////////////////////////////////// +void DXGraphicsStateGuardian8:: +atexit_function(void) { + static_set_gamma(1.0); +} diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h index 6c373c5aa0..0da75a7abc 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.h +++ b/panda/src/dxgsg8/dxGraphicsStateGuardian8.h @@ -123,6 +123,10 @@ public: const TransformState *transform); LPDIRECT3DDEVICE8 get_d3d_device(); + static bool static_set_gamma(float gamma); + bool set_gamma(float gamma); + static void atexit_function(void); + protected: void do_issue_transform(); void do_issue_alpha_test(); @@ -270,7 +274,7 @@ public: register_type(_type_handle, "DXGraphicsStateGuardian8", GraphicsStateGuardian::get_class_type()); } - + private: static TypeHandle _type_handle; diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index e919742575..c05114b0f4 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx @@ -157,6 +157,8 @@ DXGraphicsStateGuardian9(GraphicsPipe *pipe) : _vertex_shader_maximum_constants = 0; _supports_stream_offset = false; + + atexit (atexit_function); } //////////////////////////////////////////////////////////////////// @@ -2659,6 +2661,8 @@ reset() { _supports_depth_bias = ((d3d_caps.RasterCaps & D3DPRASTERCAPS_DEPTHBIAS) != 0); + _supports_gamma_calibration = ((d3d_caps.Caps2 & D3DCAPS2_CANCALIBRATEGAMMA) != 0); + // Test for occlusion query support hr = _d3d_device->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL); _supports_occlusion_query = !FAILED(hr); @@ -2696,6 +2700,7 @@ reset() { << "\nsupports_stencil_wrap = " << _supports_stencil_wrap << "\nsupports_two_sided_stencil = " << _supports_two_sided_stencil << "\nsupports_occlusion_query = " << _supports_occlusion_query + << "\nsupports_gamma_calibration = " << _supports_gamma_calibration << "\nMaxAnisotropy = " << d3d_caps.MaxAnisotropy << "\nDirectX SDK version " DIRECTX_SDK_VERSION << "\n"; @@ -4994,8 +4999,9 @@ DBG_S dxgsg9_cat.debug ( ) << "- - - - - DXGraphicsStateGuardian9::show_frame\n" HRESULT hr; if (_swap_chain) { - DWORD flags; - flags = 0; + DWORD flags; + flags = 0; + hr = _swap_chain->Present((CONST RECT*)NULL, (CONST RECT*)NULL, (HWND)NULL, NULL, flags); } else { hr = _d3d_device->Present((CONST RECT*)NULL, (CONST RECT*)NULL, (HWND)NULL, NULL); @@ -5632,3 +5638,57 @@ calc_fb_properties(DWORD cformat, DWORD dformat, } return props; } + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::static_set_gamma +// Access: Public, Static +// Description: Static function for setting gamma which is needed +// for atexit. +//////////////////////////////////////////////////////////////////// +bool DXGraphicsStateGuardian9:: +static_set_gamma(float gamma) { + bool set; + HDC hdc = GetDC(NULL); + + set = false; + if (hdc) { + unsigned short ramp [256 * 3]; + + GraphicsStateGuardian::create_gamma_table (gamma, &ramp [0], &ramp [256], &ramp [512]); + if (SetDeviceGammaRamp (hdc, ramp)) { + set = true; + } + + ReleaseDC (NULL, hdc); + } + + return set; +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::set_gamma +// Access: Published +// Description: Non static version of setting gamma. Returns true +// on success. +//////////////////////////////////////////////////////////////////// +bool DXGraphicsStateGuardian9:: +set_gamma(float gamma) { + bool set; + + set = static_set_gamma(gamma); + if (set) { + _gamma = gamma; + } + + return set; +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::atexit_function +// Access: Public, Static +// Description: This function is passed to the atexit function. +//////////////////////////////////////////////////////////////////// +void DXGraphicsStateGuardian9:: +atexit_function(void) { + static_set_gamma(1.0); +} diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h index 22be2043f6..732922dbb1 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.h +++ b/panda/src/dxgsg9/dxGraphicsStateGuardian9.h @@ -169,6 +169,10 @@ 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 static_set_gamma(float gamma); + bool set_gamma(float gamma); + static void atexit_function(void); + protected: void do_issue_transform(); void do_issue_alpha_test(); @@ -367,6 +371,8 @@ protected: list _graphics_buffer_list; + int _supports_gamma_calibration; + public: virtual TypeHandle get_type() const { return get_class_type(); diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx index c8fff40624..0ddf629fc0 100755 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.cxx @@ -49,6 +49,8 @@ wglGraphicsStateGuardian(GraphicsPipe *pipe, _supports_pbuffer = false; _supports_pixel_format = false; _supports_wgl_multisample = false; + + atexit(atexit_function); } //////////////////////////////////////////////////////////////////// @@ -736,3 +738,57 @@ register_twindow_class() { } _twindow_class_registered = true; } + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::static_set_gamma +// Access: Public, Static +// Description: Static function for setting gamma which is needed +// for atexit. +//////////////////////////////////////////////////////////////////// +bool wglGraphicsStateGuardian:: +static_set_gamma(float gamma) { + bool set; + HDC hdc = GetDC(NULL); + + set = false; + if (hdc) { + unsigned short ramp [256 * 3]; + + GraphicsStateGuardian::create_gamma_table (gamma, &ramp [0], &ramp [256], &ramp [512]); + if (SetDeviceGammaRamp (hdc, ramp)) { + set = true; + } + + ReleaseDC (NULL, hdc); + } + + return set; +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::set_gamma +// Access: Published +// Description: Non static version of setting gamma. Returns true +// on success. +//////////////////////////////////////////////////////////////////// +bool wglGraphicsStateGuardian:: +set_gamma(float gamma) { + bool set; + + set = static_set_gamma(gamma); + if (set) { + _gamma = gamma; + } + + return set; +} + +//////////////////////////////////////////////////////////////////// +// Function: DXGraphicsStateGuardian9::atexit_function +// Access: Public, Static +// Description: This function is passed to the atexit function. +//////////////////////////////////////////////////////////////////// +void wglGraphicsStateGuardian:: +atexit_function(void) { + static_set_gamma(1.0); +} diff --git a/panda/src/wgldisplay/wglGraphicsStateGuardian.h b/panda/src/wgldisplay/wglGraphicsStateGuardian.h index 592decb5e2..726ab90557 100755 --- a/panda/src/wgldisplay/wglGraphicsStateGuardian.h +++ b/panda/src/wgldisplay/wglGraphicsStateGuardian.h @@ -50,6 +50,10 @@ public: INLINE HDC get_twindow_dc(); + static bool static_set_gamma(float gamma); + bool set_gamma(float gamma); + static void atexit_function(void); + protected: virtual void get_extra_extensions(); virtual void *get_extension_func(const char *prefix, const char *name);