Bladeren bron

Add gamma.

aignacio_sf 18 jaren geleden
bovenliggende
commit
1d6233aae5

+ 56 - 0
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;
+  }    
+}

+ 7 - 0
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;

+ 55 - 0
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);
+}

+ 5 - 1
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;
 

+ 62 - 2
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);
+}

+ 6 - 0
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 <wdxGraphicsBuffer9 *> _graphics_buffer_list;
 
+  int _supports_gamma_calibration;  
+
 public:
   virtual TypeHandle get_type() const {
     return get_class_type();

+ 56 - 0
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);
+}

+ 4 - 0
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);