diff --git a/panda/src/display/config_display.cxx b/panda/src/display/config_display.cxx index a521a53209..f336b057f8 100644 --- a/panda/src/display/config_display.cxx +++ b/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 " diff --git a/panda/src/display/config_display.h b/panda/src/display/config_display.h index 633c8e5d2f..27e6b219a1 100644 --- a/panda/src/display/config_display.h +++ b/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; diff --git a/panda/src/display/graphicsStateGuardian.I b/panda/src/display/graphicsStateGuardian.I index 732742bcbb..2489292e0e 100644 --- a/panda/src/display/graphicsStateGuardian.I +++ b/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 { diff --git a/panda/src/display/graphicsStateGuardian.cxx b/panda/src/display/graphicsStateGuardian.cxx index 466472d6d2..a3481826e9 100644 --- a/panda/src/display/graphicsStateGuardian.cxx +++ b/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; diff --git a/panda/src/display/graphicsStateGuardian.h b/panda/src/display/graphicsStateGuardian.h index 80561d1ae7..297b2016cf 100644 --- a/panda/src/display/graphicsStateGuardian.h +++ b/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; diff --git a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx b/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx index cb6aae56d8..ac541f2205 100644 --- a/panda/src/dxgsg8/dxGraphicsStateGuardian8.cxx +++ b/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())); diff --git a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx b/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx index 81ae5368b4..c04c491708 100755 --- a/panda/src/dxgsg9/dxGraphicsStateGuardian9.cxx +++ b/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())); diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index a17c7c816c..44e657043b 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/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;