Clipping polygons in XNA with stencil (not using spritebatch)

Posted by Blau on Game Development See other posts from Game Development or by Blau
Published on 2011-10-12T17:53:32Z Indexed on 2011/11/12 2:13 UTC
Read the original article Hit count: 370

Filed under:
|
|
|

The problem... i'm drawing polygons, in this case boxes, and i want clip children polygons with its parent's client area.

enter image description here

    // Class Region
    public void Render(GraphicsDevice Device, Camera Camera)
    {
        int StencilLevel = 0;
        Device.Clear( ClearOptions.Stencil, Vector4.Zero, 0, StencilLevel );
        Render( Device, Camera, StencilLevel );
    }

    private void Render(GraphicsDevice Device, Camera Camera, int StencilLevel)
    {
        Device.SamplerStates[0] = this.SamplerState;
        Device.Textures[0] = this.Texture;
        Device.RasterizerState = RasterizerState.CullNone;
        Device.BlendState = BlendState.AlphaBlend;
        Device.DepthStencilState = DepthStencilState.Default;

        Effect.Prepare(this, Camera );

        Device.DepthStencilState = GlobalContext.GraphicsStates.IncMask;
        Device.ReferenceStencil = StencilLevel;

        foreach ( EffectPass pass in Effect.Techniques[Technique].Passes )
        {
            pass.Apply( );
            Device.DrawUserIndexedPrimitives<VertexPositionColorTexture>( PrimitiveType.TriangleList, VertexData, 0, VertexData.Length, IndexData, 0, PrimitiveCount );
        }

        foreach ( Region child in ChildrenRegions )
        {
            child.Render( Device, Camera, StencilLevel + 1 );
        }

        Effect.Prepare( this, Camera );

        // This does not works
        Device.BlendState = GlobalContext.GraphicsStates.NoWriteColor;
        Device.DepthStencilState = GlobalContext.GraphicsStates.DecMask;
        Device.ReferenceStencil = StencilLevel; // This should be +1, but in that case the last drrawed is blue and overlap all

        foreach ( EffectPass pass in Effect.Techniques[Technique].Passes )
        {
            pass.Apply( );
            Device.DrawUserIndexedPrimitives<VertexPositionColorTexture>( PrimitiveType.TriangleList, VertexData, 0, VertexData.Length, IndexData, 0, PrimitiveCount );
        }
    }



    public static class GraphicsStates
    {
        public static BlendState NoWriteColor = new BlendState( )
        {
             ColorSourceBlend = Blend.One,
             AlphaSourceBlend = Blend.One,
             ColorDestinationBlend = Blend.InverseSourceAlpha,
             AlphaDestinationBlend = Blend.InverseSourceAlpha,
             ColorWriteChannels1 = ColorWriteChannels.None
        };

        public static  DepthStencilState IncMask = new DepthStencilState( )
        {
            StencilEnable = true,
            StencilFunction = CompareFunction.Equal,
            StencilPass = StencilOperation.IncrementSaturation,
        };

        public static  DepthStencilState DecMask = new DepthStencilState( )
        {
            StencilEnable = true,
            StencilFunction = CompareFunction.Equal,
            StencilPass = StencilOperation.DecrementSaturation,
        };
    }

How can achieve this?

EDIT: I've just relized that the NoWriteColors.ColorWriteChannels1 should be NoWriteColors.ColorWriteChannels. :)

Now it's clipping right.

Any other approach?

© Game Development or respective owner

Related posts about XNA

Related posts about c#