Stencil mask with AlphaTestEffect

Posted by Brendan Wanlass on Game Development See other posts from Game Development or by Brendan Wanlass
Published on 2012-11-13T04:19:27Z Indexed on 2012/11/13 5:17 UTC
Read the original article Hit count: 458

Filed under:
|

I am trying to pull off the following effect in XNA 4.0:

http://eng.utah.edu/~brendanw/question.jpg

The purple area has 50% opacity. I have gotten pretty close with the following code:

public static DepthStencilState AlwaysStencilState = new DepthStencilState()
        {

            StencilEnable = true,
            StencilFunction = CompareFunction.Always,
            StencilPass = StencilOperation.Replace,
            ReferenceStencil = 1,
            DepthBufferEnable = false,
        };

public static DepthStencilState EqualStencilState = new DepthStencilState()
        {
            StencilEnable = true,
            StencilFunction = CompareFunction.Equal,
            StencilPass = StencilOperation.Keep,
            ReferenceStencil = 1,
            DepthBufferEnable = false,
        };

...

if (_alphaEffect == null)
{
       _alphaEffect = new AlphaTestEffect(_spriteBatch.GraphicsDevice);
       _alphaEffect.AlphaFunction = CompareFunction.LessEqual;
       _alphaEffect.ReferenceAlpha = 129;
       Matrix projection = Matrix.CreateOrthographicOffCenter(0, _spriteBatch.GraphicsDevice.PresentationParameters.BackBufferWidth, _spriteBatch.GraphicsDevice.PresentationParameters.BackBufferHeight, 0, 0, 1); 
       _alphaEffect.Projection = world.SystemManager.GetSystem<RenderSystem>().Camera.View * projection;
}

_mask = new RenderTarget2D(_spriteBatch.GraphicsDevice, _spriteBatch.GraphicsDevice.PresentationParameters.BackBufferWidth, _spriteBatch.GraphicsDevice.PresentationParameters.BackBufferHeight, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);
_spriteBatch.GraphicsDevice.SetRenderTarget(_mask);
_spriteBatch.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.Stencil, Color.Transparent, 0, 0); 

_spriteBatch.Begin(SpriteSortMode.Immediate, null, null, AlwaysStencilState, null, _alphaEffect);
_spriteBatch.Draw(sprite.Texture, position, sprite.SourceRectangle,Color.White, 0f, sprite.Origin, 1f, SpriteEffects.None, 0);
_spriteBatch.End();

_spriteBatch.Begin(SpriteSortMode.Immediate, null, null, EqualStencilState, null, null);
_spriteBatch.Draw(_maskTex, new Vector2(x * _maskTex.Width, y * _maskTex.Height), null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0);
_spriteBatch.End();

_spriteBatch.GraphicsDevice.SetRenderTarget(null);
_spriteBatch.GraphicsDevice.Clear(Color.Black);

_spriteBatch.Begin();
_spriteBatch.Draw((Texture2D)_mask, Vector2.Zero, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, layer/max_layer);
_spriteBatch.End();

My problem is, I can't get the AlphaTestEffect to behave. I can either mask over the semi-transparent purple junk and fill it in with the green design, or I can draw over the completely opaque grassy texture. How can I specify the exact opacity that needs to be replace with the green design?

© Game Development or respective owner

Related posts about xna-4.0

Related posts about stencil