2

我正在尝试理解模板。我可以使用一个很好的教程来解释它们是如何工作的,但与此同时,这是我正在使用的:

DepthStencilState _StencilAlways;
DepthStencilState _StencilKeepIfZero;

SpriteBatch _StencilBatch;
SpriteBatch _MaskBatch;

_StencilAlways = new DepthStencilState();
_StencilAlways.StencilEnable = true;
_StencilAlways.StencilFunction = CompareFunction.Always;
_StencilAlways.StencilPass = StencilOperation.Replace;
_StencilAlways.ReferenceStencil = 1;
_StencilAlways.DepthBufferEnable = false; 

_StencilKeepIfZero = new DepthStencilState();
_StencilKeepIfZero.StencilEnable = true;
_StencilKeepIfZero.StencilFunction = CompareFunction.Equal;
_StencilKeepIfZero.StencilPass = StencilOperation.Keep;
_StencilKeepIfZero.ReferenceStencil = 0;
_StencilKeepIfZero.DepthBufferEnable = false;

RenderTarget2D MaskRenderTarget = new RenderTarget2D(device, Width, Height, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.DiscardContents);

GraphicsDevice.SetRenderTarget(MaskRenderTarget);
GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.Stencil, new Color(0, 0, 0, 1), 0, 0);

_MaskBatch.Begin(SpriteSortMode.Immediate, null, null, _StencilAlways, null);
_MaskBatch.Draw(
    Texture,
    Position,
    null,
    Shade,
    0,
    Vector2.Zero,
    Scale,
    SpriteEffects.None,
    0);
_MaskBatch.End();

_StencilBatch.Begin(SpriteSortMode.Immediate, null, null, _StencilKeepIfZero, null);
_StencilBatch.DrawString(
    _Font, 
    Line, 
    Position2, 
    Shade);
_StencilBatch.End();

_RenderedTexture = MaskRenderTarget;

GraphicsDevice.SetRenderTargets(null);

可能存在一些换位/卫生错误,但有什么想法我做错了吗?

4

2 回答 2

1

我建议搜索与 XNA / Windows Phone 无关的模板缓冲区的使用。最后,价值或用法是完全一样的。

它的基本功能是所有显卡都支持的,DirectX 和 OpenGL 都有绑定。

http://en.wikipedia.org/wiki/Stencil_bufferhttp://www.google.cz/search?q=stencil+buffer

于 2011-04-25T19:20:09.713 回答
1

有关代码,请参阅我在 App Hub 论坛上的回答:http ://forums.create.msdn.com/forums/p/81189/499989.aspx#499989

您希望 ReferenceStencil 值两次都为 1。

您还需要使用 AlphaFunction = CompareGreater、ReferenceAlpha = 0 创建一个 AlphaTestEffect 实例,并使用 Matrix.OrthographicOffCenter(0, width, height, 0, 0, 1); 创建一个适当的投影矩阵;.

然后你必须将它传递给 SpriteBatch。在绘制模板时开始,然后在绘制你想要模板的东西时再次开始。

此外,您应该首先绘制模板,然后绘制您想要模板的内容。在上述情况下,将 DrawString 移动到 Draw 所在的位置,并将 Draw 移动到 DrawString 所在的位置。它首先绘制模板(文本)。然后它会绘制项目(您的纹理),并且只保留模板要求的项目部分。

您可能希望使用 Color.Transparent 而不是 new Color(0,0,0,1) 作为清除颜色。

于 2011-05-17T21:10:09.220 回答