5
\$\begingroup\$

Is there any way to enable a temporary clipping mask in XNA while using a SpriteBatch? I'm drawing a bunch of Texture2D objects and Sprites in a given rectangle, and I want to make sure that said objects aren't drawn outside of that rectangle. If it's of any help, I'm already drawing my content within a Viewport, I'm not sure if I can draw, for instance, in another Viewport within that Viewport.

Illustrative image of what I'm trying to accomplish: image of clipped region

\$\endgroup\$
10
\$\begingroup\$

The scissor rect is a bit easier to use than the stencil buffer. You need to set ScissorRect to your Rectangle and set ScissorTestEnable to true.

        // In XNA < 4.0...
        spriteBatch.GraphicsDevice.RenderState.ScissorTestEnable = true;
        spriteBatch.GraphicsDevice.ScissorRectangle = clipRect;
        spriteBatch.Begin();

        // In XNA 4.0, the ScissorTestEnable has moved, so do this instead...
        spriteBatch.GraphicsDevice.RasterizerState.ScissorTestEnable = true;
        spriteBatch.GraphicsDevice.ScissorRectangle = clipRect;
        spriteBatch.Begin();
\$\endgroup\$
  • \$\begingroup\$ Thanks a ton! I wasn't able to get it working at first, but then I realized it wasn't XNA 4.0 compatible. I modified it and it worked awesomely. \$\endgroup\$ – ThatsGobbles Oct 16 '10 at 4:35
  • \$\begingroup\$ Hmm... GraphicsDevice doesn't seem to have a render state anymore. Where did this get moved to? \$\endgroup\$ – BrainSlugs83 Aug 25 '14 at 7:28
  • 1
    \$\begingroup\$ To follow up on the other two comments, in XNA 4.0, GraphicsDevice.RenderState doesn't exist anymore. In 4.0, to access the ScissorTestEnable, use: spriteBatch.GraphicsDevice.RasterizerState.ScissorTestEnable = true; \$\endgroup\$ – Sean Colombo Mar 15 '15 at 19:42
2
\$\begingroup\$

You need to use a Stencil Buffer. This is specified by passing a DepthStencilState into your SpriteBatch.Begin method call.

For example, to remove an object from a scene, fill a stencil buffer with a cut out pattern (using zeros) for each pixel where the object is visible. This is done by setting the reference stencil value to 0, clearing the stencil buffer, and rendering the object. Then set the reference stencil value to 1, set the compare function to CompareFunction.LessEqual, and render again. The stencil data masks those pixels whose value is non zero but less than 1, resulting in drawing over (or removing) the object.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.