+ // We keep track of the last clipping Id and depth so we can determine when we are
+ // moving back up the scene graph and require some of the stencil bit-planes to be deleted.
+ lastClippingDepth = clippingDepth;
+ lastClippingId = clippingId;
+
+ // We only ever write to bit-planes up to the current depth as we may need
+ // to erase individual bit-planes and revert to a previous clipping area.
+ // Our reference value for testing (in StencilFunc) is written to to the buffer, but we actually
+ // want to test a different value. IE. All the bit-planes up to but not including the current depth.
+ // So we use the Mask parameter of StencilFunc to mask off the top bit-plane when testing.
+ // Here we create our test mask to innore the top bit of the reference test value.
+ // As the mask is made up of contiguous "1" values, we can do this quickly with a bit-shift.
+ const uint32_t testMask = currentDepthMask >> 1u;
+
+ context.StencilFunc( GL_EQUAL, currentDepthMask, testMask ); // Test against existing stencil bit-planes. All must match up to (but not including) this depth.
+ context.StencilMask( currentDepthMask ); // Write to the new stencil bit-plane (the other previous bit-planes are also written to).
+ context.StencilOp( GL_KEEP, GL_REPLACE, GL_REPLACE );
+ }
+ else
+ {
+ // We are reading from the stencil buffer. Set up the stencil accordingly
+ // This calculation sets all the bits up to the current depth bit.
+ // This has the effect of testing that the pixel being written to exists in every bit-plane up to the current depth.
+ context.StencilFunc( GL_EQUAL, currentDepthMask, 0xff );
+ context.StencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
+ }
+}