RenderTargets在XNA中绘制顺序

时间:2011-08-29 20:36:16

标签: c# xna xna-4.0

我认为我从根本上误解了渲染目标的工作方式。在我的理解中,RenderTargets只是spritebatch draw调用draw的纹理。

所以我尝试使用此代码来渲染GUI窗口,以确保它们只能在其客户区域中绘制并在其外部进行裁剪。

 for (int i = Controls.Count - 1; i >= 0; i--)
        {
            RenderTarget2D oldTarget;
            if (graphics.GetRenderTargets().Count() == 0) oldTarget = null;
            else oldTarget = (RenderTarget2D)graphics.GetRenderTargets()[0].RenderTarget; // Get the old target being used.
            graphics.SetRenderTarget(canvas); //set the target to a temporary RT
            graphics.Clear(Color.Black); // Clear it
            Control c = Controls[i]; // Get the current control (a form in this case)
            c.Draw(spriteBatch, gameTime); // Draw it to the temp RT
            graphics.SetRenderTarget(oldTarget); // Set the RT back to the main RT
            Vector2 dest = c.DrawCoOrds(); // Gets the draw coordinates of the control
            spriteBatch.Begin();
            spriteBatch.Draw(canvas, new Rectangle((int)dest.X, (int)dest.Y, c.Bounds.Width, c.Bounds.Height), new Rectangle((int)dest.X, (int)dest.Y, c.Bounds.Width, c.Bounds.Height), Color.White); 
// take the rect from the temp RT and draw it to the main RT.
            spriteBatch.End();
        }

然而,此代码仅绘制列表中的最后一个表单,这意味着它必须以某种方式清除主RT,但我不明白为什么。当RT设置为临时画布时,我只调用clear。

2 个答案:

答案 0 :(得分:0)

我认为绘制gui控件的最佳方法是使用ScissorRectangle,因为我们只能在该矩形内部绘制,这可以是gui控件的客户区。

MSDN: GraphicsDevice.ScissorRectangle

您需要通过RasterizerState启用此功能。

 RasterizerState ScissorState = new RasterizerState() 
 { 
     ScissorTestEnabled = true; 
 }

在绘制之前,请使用此状态调用SpriteBatch.Begin。

A video of my own gui running in a xbox360 :)

答案 1 :(得分:0)

您是如何创建渲染目标和后台缓冲区的?默认情况下,在更改为其他渲染目标后,您无法多次写入渲染目标。这就是原因:

http://blogs.msdn.com/b/shawnhar/archive/2007/11/21/rendertarget-changes-in-xna-game-studio-2-0.aspx

您可以通过使用RenderTargetUsage.PreserveContents.创建渲染目标来更改默认行为,并通过覆盖GraphicsDeviceManager.PrepareDeviceSettings.来更改后缓冲区,更改GraphicsDeviceInformation.PresentationParameters.RenderTargetUsage,如链接中所述。虽然我认为在XNA 4中以不同方式完成覆盖这些设置。

所有这一切,改变远离默认行为都有性能方面的考虑因素,不建议这样做。你应该找到一种方法来做到这一点。一种可能性是为每个窗口创建一个单独的渲染目标,绘制所有窗口,切换到后缓冲区并将渲染目标绘制到它。

更好的选择是使用@Blau提出的剪刀矩形光栅化器状态。