Clipping polygons in XNA with stencil (not using spritebatch)
- by Blau
The problem... i'm drawing polygons, in this case boxes, and i want clip children polygons with its parent's client area.
// 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?