Browse Source

Added stencil write mask support.

Lasse Öörni 14 years ago
parent
commit
3be676f08c

+ 11 - 5
Engine/Graphics/Direct3D9/D3D9Graphics.cpp

@@ -1633,7 +1633,7 @@ void Graphics::SetScissorTest(bool enable, const IntRect& rect)
     }
 }
 
-void Graphics::SetStencilTest(bool enable, CompareMode mode, StencilOp pass, StencilOp fail, StencilOp zFail, unsigned stencilRef, unsigned stencilMask)
+void Graphics::SetStencilTest(bool enable, CompareMode mode, StencilOp pass, StencilOp fail, StencilOp zFail, unsigned stencilRef, unsigned compareMask, unsigned writeMask)
 {
     if (enable != stencilTest_)
     {
@@ -1668,10 +1668,15 @@ void Graphics::SetStencilTest(bool enable, CompareMode mode, StencilOp pass, Ste
             impl_->device_->SetRenderState(D3DRS_STENCILREF, stencilRef);
             stencilRef_ = stencilRef;
         }
-        if (stencilMask != stencilMask_)
+        if (compareMask != stencilCompareMask_)
         {
-            impl_->device_->SetRenderState(D3DRS_STENCILMASK, stencilMask);
-            stencilMask_ = stencilMask;
+            impl_->device_->SetRenderState(D3DRS_STENCILMASK, compareMask);
+            stencilCompareMask_ = compareMask;
+        }
+        if (writeMask != stencilWriteMask_)
+        {
+            impl_->device_->SetRenderState(D3DRS_STENCILWRITEMASK, writeMask);
+            stencilWriteMask_ = writeMask;
         }
     }
 }
@@ -2221,7 +2226,8 @@ void Graphics::ResetCachedState()
     stencilFail_ = OP_KEEP;
     stencilZFail_ = OP_KEEP;
     stencilRef_ = 0;
-    stencilMask_ = M_MAX_UNSIGNED;
+    stencilCompareMask_ = M_MAX_UNSIGNED;
+    stencilWriteMask_ = M_MAX_UNSIGNED;
     impl_->blendEnable_ = FALSE;
     impl_->srcBlend_ = D3DBLEND_ONE;
     impl_->destBlend_ = D3DBLEND_ZERO;

+ 7 - 3
Engine/Graphics/Direct3D9/D3D9Graphics.h

@@ -172,7 +172,7 @@ public:
     /// %Set scissor test.
     void SetScissorTest(bool enable, const IntRect& rect);
     /// %Set stencil test.
-    void SetStencilTest(bool enable, CompareMode mode = CMP_ALWAYS, StencilOp pass = OP_KEEP, StencilOp fail = OP_KEEP, StencilOp zFail = OP_KEEP, unsigned stencilRef = 0, unsigned stencilMask = M_MAX_UNSIGNED);
+    void SetStencilTest(bool enable, CompareMode mode = CMP_ALWAYS, StencilOp pass = OP_KEEP, StencilOp fail = OP_KEEP, StencilOp zFail = OP_KEEP, unsigned stencilRef = 0, unsigned compareMask = M_MAX_UNSIGNED, unsigned writeMask = M_MAX_UNSIGNED);
     /// %Set vertex buffer stream frequency.
     void SetStreamFrequency(unsigned index, unsigned frequency);
     /// Reset stream frequencies.
@@ -297,7 +297,9 @@ public:
     /// Return stencil reference value.
     unsigned GetStencilRef() const { return stencilRef_; }
     /// Return stencil compare bitmask.
-    unsigned GetStencilMask() const { return stencilMask_; }
+    unsigned GetStencilCompareMask() const { return stencilCompareMask_; }
+    /// Return stencil write bitmask.
+    unsigned GetStencilWriteMask() const { return stencilWriteMask_; }
     /// Return stream frequency by vertex buffer index.
     unsigned GetStreamFrequency(unsigned index) const;
     /// Return rendertarget width and height.
@@ -480,7 +482,9 @@ private:
     /// Stencil test reference value.
     unsigned stencilRef_;
     /// Stencil compare bitmask.
-    unsigned stencilMask_;
+    unsigned stencilCompareMask_;
+    /// Stencil write bitmask.
+    unsigned stencilWriteMask_;
     /// Default texture filtering mode.
     TextureFilterMode defaultTextureFilterMode_;
 };

+ 16 - 6
Engine/Graphics/OpenGL/OGLGraphics.cpp

@@ -400,11 +400,13 @@ void Graphics::Clear(unsigned flags, const Color& color, float depth, unsigned s
 {
     bool oldColorWrite = colorWrite_;
     bool oldDepthWrite = depthWrite_;
-    
+
     if (flags & CLEAR_COLOR && !oldColorWrite)
         SetColorWrite(true);
     if (flags & CLEAR_DEPTH && !oldDepthWrite)
         SetDepthWrite(true);
+    if (flags & CLEAR_STENCIL && stencilWriteMask_ != M_MAX_UNSIGNED)
+        glStencilMask(M_MAX_UNSIGNED);
     
     unsigned glFlags = 0;
     if (flags & CLEAR_COLOR)
@@ -436,6 +438,8 @@ void Graphics::Clear(unsigned flags, const Color& color, float depth, unsigned s
     SetScissorTest(false);
     SetColorWrite(oldColorWrite);
     SetDepthWrite(oldDepthWrite);
+    if (flags & CLEAR_STENCIL && stencilWriteMask_ != M_MAX_UNSIGNED)
+        glStencilMask(stencilWriteMask_);
 }
 
 bool Graphics::ResolveToTexture(Texture2D* destination, const IntRect& viewport)
@@ -1623,7 +1627,7 @@ void Graphics::ResetStreamFrequencies()
 {
 }
 
-void Graphics::SetStencilTest(bool enable, CompareMode mode, StencilOp pass, StencilOp fail, StencilOp zFail, unsigned stencilRef, unsigned stencilMask)
+void Graphics::SetStencilTest(bool enable, CompareMode mode, StencilOp pass, StencilOp fail, StencilOp zFail, unsigned stencilRef, unsigned compareMask, unsigned writeMask)
 {
     if (enable != stencilTest_)
     {
@@ -1636,12 +1640,17 @@ void Graphics::SetStencilTest(bool enable, CompareMode mode, StencilOp pass, Ste
     
     if (enable)
     {
-        if (mode != stencilTestMode_ || stencilRef != stencilRef_ || stencilMask != stencilMask_)
+        if (mode != stencilTestMode_ || stencilRef != stencilRef_ || compareMask != stencilCompareMask_)
         {
-            glStencilFunc(glCmpFunc[mode], stencilRef, stencilMask);
+            glStencilFunc(glCmpFunc[mode], stencilRef, compareMask);
             stencilTestMode_ = mode;
             stencilRef_ = stencilRef;
-            stencilMask_ = stencilMask;
+            stencilCompareMask_ = compareMask;
+        }
+        if (writeMask != stencilWriteMask_)
+        {
+            glStencilMask(writeMask);
+            stencilWriteMask_ = writeMask;
         }
         if (pass != stencilPass_ || fail != stencilFail_ || zFail != stencilZFail_)
         {
@@ -1983,7 +1992,8 @@ void Graphics::ResetCachedState()
     stencilFail_ = OP_KEEP;
     stencilZFail_ = OP_KEEP;
     stencilRef_ = 0;
-    stencilMask_ = M_MAX_UNSIGNED;
+    stencilCompareMask_ = M_MAX_UNSIGNED;
+    stencilWriteMask_ = M_MAX_UNSIGNED;
     
     impl_->activeTexture_ = 0;
     impl_->drawBuffers_ = M_MAX_UNSIGNED;

+ 7 - 3
Engine/Graphics/OpenGL/OGLGraphics.h

@@ -195,7 +195,7 @@ public:
     /// Set scissor test.
     void SetScissorTest(bool enable, const IntRect& rect);
     /// Set stencil test.
-    void SetStencilTest(bool enable, CompareMode mode = CMP_ALWAYS, StencilOp pass = OP_KEEP, StencilOp fail = OP_KEEP, StencilOp zFail = OP_KEEP, unsigned stencilRef = 0, unsigned stencilMask = M_MAX_UNSIGNED);
+    void SetStencilTest(bool enable, CompareMode mode = CMP_ALWAYS, StencilOp pass = OP_KEEP, StencilOp fail = OP_KEEP, StencilOp zFail = OP_KEEP, unsigned stencilRef = 0, unsigned compareMask = M_MAX_UNSIGNED, unsigned writeMask = M_MAX_UNSIGNED);
     /// Set vertex buffer stream frequency. No-op on OpenGL.
     void SetStreamFrequency(unsigned index, unsigned frequency);
     /// Reset stream frequencies. No-op on OpenGL.
@@ -320,7 +320,9 @@ public:
     /// Return stencil reference value.
     unsigned GetStencilRef() const { return stencilRef_; }
     /// Return stencil compare bitmask.
-    unsigned GetStencilMask() const { return stencilMask_; }
+    unsigned GetStencilCompareMask() const { return stencilCompareMask_; }
+    /// Return stencil write bitmask.
+    unsigned GetStencilWriteMask() const { return stencilWriteMask_; }
     /// Return stream frequency by vertex buffer index. Always returns 0 on OpenGL.
     unsigned GetStreamFrequency(unsigned index) const { return 0; }
     /// Return rendertarget width and height.
@@ -473,7 +475,9 @@ private:
     /// Stencil test reference value.
     unsigned stencilRef_;
     /// Stencil compare bitmask.
-    unsigned stencilMask_;
+    unsigned stencilCompareMask_;
+    /// Stencil write bitmask.
+    unsigned stencilWriteMask_;
     /// Default texture filtering mode.
     TextureFilterMode defaultTextureFilterMode_;
     /// Map for additional depth textures, to emulate Direct3D9 ability to mix render texture and backbuffer rendering.