Я работал не покладая рук, пытаясь заставить работать трафаретные буферы, но безуспешно в xna 4.0
private void DrawReflectionMask()
{
if (AlphaEffect == null)
{
AlphaEffect = new AlphaTestEffect(GraphicsDevice);
AlphaEffect.VertexColorEnabled = true;
AlphaEffect.DiffuseColor = Color.White.ToVector3();
AlphaEffect.AlphaFunction = CompareFunction.Equal;
AlphaEffect.ReferenceAlpha = 0;
AlphaEffect.World = Matrix.Identity;
AlphaEffect.View = Matrix.Identity;
}
if(mReflection == null)
{
mReflection = Content.Load<Texture2D>("reflection");
mMask = Content.Load<Texture2D>("ice-mask");
}
mSpriteBatch.End();
RenderTarget2D lMaskRenderTarget = new RenderTarget2D(mGraphicsDevice, mPixelViewport.Width, mPixelViewport.Height,false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, 0 ,RenderTargetUsage.DiscardContents);
GraphicsDevice.SetRenderTarget(lMaskRenderTarget);
BlendState lOldState = GraphicsDevice.BlendState;
GraphicsDevice.BlendState = ABlendState;
GraphicsDevice.Clear(ClearOptions.Stencil | ClearOptions.Target, new Color(0,0,0,1), 0, 0);
SpriteBatch.Begin(SpriteSortMode.Immediate,null,null, AlwaysStencilState,null);
for (int x = mViewPort.Viewport.Left; x < mViewPort.Viewport.Right; x++)
{
for (int y = mViewPort.Viewport.Top; y < mViewPort.Viewport.Bottom; y++)
{
int lTileIndex = mMap[x, y].TileID;
Rectangle lSourceRectangle = new Rectangle((lTileIndex % 8) * 32, (lTileIndex / 8) * 32, 32, 32);
mSpriteBatch.Draw(mMask,
new Vector2((x - mViewPort.Viewport.X) * 32, (y - mViewPort.Viewport.Y) * 32),
lSourceRectangle,
Color.White);
}
}
SpriteBatch.End();
GraphicsDevice.BlendState = lOldState;
SpriteBatch.Begin(SpriteSortMode.Immediate, null, null, EqualStencilState, null);
for (int x = 0; x < 4; x++)
{
for (int y = 0; y < 3; y++)
{
SpriteBatch.Draw(mReflection, new Vector2(x * 256, y * 256), Color.White);
}
}
SpriteBatch.End();
GraphicsDevice.SetRenderTarget(null);
//lMaskRenderTarget.SaveAsPng(new FileStream("Image.png", FileMode.Create), lMaskRenderTarget.Width, lMaskRenderTarget.Height);
SpriteBatch.Begin();
SpriteBatch.Draw(lMaskRenderTarget, Vector2.Zero, Color.White);
}
Это моя функция, которую я использую, чтобы попытаться нарисовать маску трафарета ...
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,
};
Это мои трафаретные состояния ...
Что я пытаюсь сделать, так это скрыть части текстуры на основе маски.
Вот мое отражение ...
http://www.badsheepgaming.com/Kevin/reflection.png
Вот моя маска
http://www.badsheepgaming.com/Kevin/ice-mask.png
Вот что я получаю с этим кодом
http://www.badsheepgaming.com/Kevin/outcome.png
и вот что я ожидаю
http://www.badsheepgaming.com/Kevin/cow.png