Browse Source

get_supports_stencil

David Rose 17 years ago
parent
commit
7a3d75d331

+ 12 - 1
panda/src/display/config_display.cxx

@@ -152,13 +152,24 @@ ConfigVariableBool support_render_texture
 
 ConfigVariableBool support_rescale_normal
 ("support-rescale-normal", true,
- PRC_DESC("Set this true allow use of the rescale-normal feature, if it "
+ PRC_DESC("Set this true to allow use of the rescale-normal feature, if it "
           "is supported by your graphics card.  This allows lighting normals "
           "to be uniformly counter-scaled, instead of re-normalized, "
           "in the presence of a uniform scale, which should in principle be "
           "a bit faster.  This feature is only supported "
           "by the OpenGL API."));
 
+ConfigVariableBool support_stencil
+("support-stencil", true,
+ PRC_DESC("Set this true to allow use of the stencil buffer, if it "
+          "is supported by your graphics card.  If this is false, stencil "
+          "buffer support will not be enabled, even if it is supported.  "
+          "Generally, only very old cards do not support some kind of "
+          "stencil buffer operations; but it is also not supported by "
+          "our tinydisplay renderer.  "
+          "The main reason to set this false is to test your code in "
+          "the absence of stencil buffer support."));
+
 ConfigVariableBool copy_texture_inverted
 ("copy-texture-inverted", false,
  PRC_DESC("Set this true to indicate that the GSG in use will invert textures when "

+ 1 - 0
panda/src/display/config_display.h

@@ -52,6 +52,7 @@ extern EXPCL_PANDA_DISPLAY ConfigVariableBool prefer_single_buffer;
 extern EXPCL_PANDA_DISPLAY ConfigVariableInt max_texture_stages;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool support_render_texture;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool support_rescale_normal;
+extern EXPCL_PANDA_DISPLAY ConfigVariableBool support_stencil;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool copy_texture_inverted;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool window_inverted;
 extern EXPCL_PANDA_DISPLAY ConfigVariableBool red_blue_stereo;

+ 13 - 1
panda/src/display/graphicsStateGuardian.I

@@ -602,11 +602,23 @@ get_supports_basic_shaders() const {
   return _supports_basic_shaders;
 }
 
+////////////////////////////////////////////////////////////////////
+//     Function: GraphicsStateGuardian::get_supports_stencil
+//       Access: Published
+//  Description: Returns true if this particular GSG supports
+//               stencil buffers at all.
+////////////////////////////////////////////////////////////////////
+INLINE bool GraphicsStateGuardian::
+get_supports_stencil() const {
+  return _supports_stencil;
+}
+
 ////////////////////////////////////////////////////////////////////
 //     Function: GraphicsStateGuardian::get_supports_two_sided_stencil
 //       Access: Published
 //  Description: Returns true if this particular GSG supports
-//               two sided stencil.
+//               two sided stencil: different stencil settings for the
+//               front and back side of the same polygon.
 ////////////////////////////////////////////////////////////////////
 INLINE bool GraphicsStateGuardian::
 get_supports_two_sided_stencil() const {

+ 1 - 0
panda/src/display/graphicsStateGuardian.cxx

@@ -192,6 +192,7 @@ GraphicsStateGuardian(CoordinateSystem internal_coordinate_system,
   _supports_shadow_filter = false;
   _supports_basic_shaders = false;
 
+  _supports_stencil = false;
   _supports_stencil_wrap = false;
   _supports_two_sided_stencil = false;
 

+ 3 - 1
panda/src/display/graphicsStateGuardian.h

@@ -138,6 +138,7 @@ PUBLISHED:
   INLINE bool get_supports_depth_stencil() const;
   INLINE bool get_supports_shadow_filter() const;
   INLINE bool get_supports_basic_shaders() const;
+  INLINE bool get_supports_stencil() const;
   INLINE bool get_supports_two_sided_stencil() const;
 
   INLINE int get_maximum_simultaneous_render_targets() const;
@@ -428,7 +429,8 @@ protected:
   bool _supports_depth_stencil;
   bool _supports_shadow_filter;
   bool _supports_basic_shaders;
-
+  
+  bool _supports_stencil;
   bool _supports_stencil_wrap;
   bool _supports_two_sided_stencil;
 

+ 3 - 0
panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx

@@ -4334,6 +4334,9 @@ void dx_set_stencil_functions (StencilRenderStates *stencil_render_states) {
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian8::
 do_issue_stencil() {
+  if (!_supports_stencil) {
+    return;
+  }
 
   StencilRenderStates *stencil_render_states;
   const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib_def(StencilAttrib::get_class_slot()));

+ 10 - 0
panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx

@@ -2477,6 +2477,13 @@ reset() {
   _screen->_supports_dynamic_textures = ((d3d_caps.Caps2 & D3DCAPS2_DYNAMICTEXTURES) != 0);
   _screen->_supports_automatic_mipmap_generation = ((d3d_caps.Caps2 & D3DCAPS2_CANAUTOGENMIPMAP) != 0);
 
+  if (support_stencil) {
+    int min_stencil = D3DSTENCILCAPS_ZERO | D3DSTENCILCAPS_REPLACE | D3DSTENCILCAPS_INCR | D3DSTENCILCAPS_DECR;
+    if ((d3d_caps.StencilCaps & min_stencil) == min_stencil) {
+      _supports_stencil = true;
+    }
+  }
+
   _supports_stencil_wrap = (d3d_caps.StencilCaps & D3DSTENCILCAPS_INCR) && (d3d_caps.StencilCaps & D3DSTENCILCAPS_DECR);
   _supports_two_sided_stencil = ((d3d_caps.StencilCaps & D3DSTENCILCAPS_TWOSIDED) != 0);
 
@@ -5342,6 +5349,9 @@ void dx_set_stencil_functions (StencilRenderStates *stencil_render_states) {
 ////////////////////////////////////////////////////////////////////
 void DXGraphicsStateGuardian9::
 do_issue_stencil() {
+  if (!_supports_stencil) {
+    return;
+  }
 
   StencilRenderStates *stencil_render_states;
   const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib_def(StencilAttrib::get_class_slot()));

+ 10 - 0
panda/src/glstuff/glGraphicsStateGuardian_src.cxx

@@ -1173,6 +1173,12 @@ reset() {
 
   report_my_gl_errors();
 
+  if (support_stencil) {
+    GLint num_stencil_bits;
+    GLP(GetIntegerv)(GL_STENCIL_BITS, &num_stencil_bits);
+    _supports_stencil = (num_stencil_bits != 0);
+  }
+
   _supports_stencil_wrap = has_extension("GL_EXT_stencil_wrap");
   _supports_two_sided_stencil = has_extension("GL_EXT_stencil_two_side");
   if (_supports_two_sided_stencil) {
@@ -8244,6 +8250,10 @@ void gl_set_stencil_functions (StencilRenderStates *stencil_render_states) {
 ////////////////////////////////////////////////////////////////////
 void CLP(GraphicsStateGuardian)::
 do_issue_stencil() {
+  if (!_supports_stencil) {
+    return;
+  }
+
   const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib_def(StencilAttrib::get_class_slot()));
 
   StencilRenderStates *stencil_render_states;