#region Using Statements using System; using ANX.Framework; using ANX.Framework.Graphics; #endregion // Using Statements namespace StencilBuffer { public class Game1 : Game { private readonly GraphicsDeviceManager graphics; private SpriteBatch spriteBatch; private Texture2D crate; private Texture2D ground; private SamplerState SamplerState; private DepthStencilState RenderGroundStencilState; private DepthStencilState RenderObjectsStencilState; private DepthStencilState StencilStateRenderShadows; //protected static SamplerState SamplerState = new SamplerState //{ // AddressU = TextureAddressMode.Wrap, // AddressV = TextureAddressMode.Wrap, // AddressW = TextureAddressMode.Wrap, // Filter = TextureFilter.Linear, //}; //private static readonly DepthStencilState RenderObjectsStencilState = new DepthStencilState() //{ // DepthBufferEnable = true, // DepthBufferWriteEnable = true, // DepthBufferFunction = CompareFunction.Always, // ReferenceStencil = 2, // StencilEnable = true, // StencilPass = StencilOperation.Increment, //}; //private static readonly DepthStencilState StencilStateRenderShadows = new DepthStencilState //{ // DepthBufferEnable = true, // DepthBufferWriteEnable = true, // DepthBufferFunction = CompareFunction.LessEqual, // ReferenceStencil = 1, // StencilEnable = true, // StencilPass = StencilOperation.Keep, //}; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "SampleContent"; } protected override void Initialize() { //graphics.PreferredDepthStencilFormat = DepthFormat.Depth24Stencil8; //graphics.ApplyChanges(); base.Initialize(); } protected override void LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); crate = Content.Load(@"Textures/chest"); ground = Content.Load(@"Textures/stone_tile"); this.SamplerState = new SamplerState() { AddressU = TextureAddressMode.Wrap, AddressV = TextureAddressMode.Wrap, AddressW = TextureAddressMode.Wrap, Filter = TextureFilter.Linear, }; this.RenderGroundStencilState = new DepthStencilState() { DepthBufferEnable = false, DepthBufferWriteEnable = false, StencilEnable = true, ReferenceStencil = 1, StencilPass = StencilOperation.Replace, StencilFunction = CompareFunction.Always, }; this.RenderObjectsStencilState = new DepthStencilState() { DepthBufferEnable = true, DepthBufferWriteEnable = true, DepthBufferFunction = CompareFunction.Always, ReferenceStencil = 1, StencilEnable = false, StencilPass = StencilOperation.Replace, }; this.StencilStateRenderShadows = new DepthStencilState { DepthBufferEnable = false, StencilEnable = true, ReferenceStencil = 1, StencilPass = StencilOperation.Increment, StencilFunction = CompareFunction.LessEqual, }; } private void RenderObjects() { spriteBatch.Begin(SpriteSortMode.Texture, null, SamplerState, RenderObjectsStencilState, null); spriteBatch.Draw(crate, new Vector2(100, 100), Color.White); spriteBatch.Draw(crate, new Vector2(-15, -15), Color.White); spriteBatch.End(); } private void RenderGround() { spriteBatch.Begin(SpriteSortMode.Texture, null, SamplerState, RenderGroundStencilState, null); for (int y = 0; y < 2; y++) { for (int x = 0; x < 4; x++) { spriteBatch.Draw(ground, new Vector2(x * 255, y * 255), Color.White); } } spriteBatch.End(); } private void RenderShadows() { spriteBatch.Begin(SpriteSortMode.Texture, null, SamplerState, StencilStateRenderShadows, null); spriteBatch.Draw(crate, new Vector2(125, 125), new Color(0, 0, 0, 0.5f)); spriteBatch.Draw(crate, new Vector2(20, 20), new Color(0, 0, 0, 0.5f)); spriteBatch.End(); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.Stencil, Color.CornflowerBlue, 1.0f, 0); RenderGround(); RenderShadows(); RenderObjects(); base.Draw(gameTime); } } }