XNA 中的 RenderTargets 绘制顺序
我认为我从根本上误解了渲染目标的工作方式。根据我的理解,RenderTargets 只是 spritebatch 绘制调用绘制到的纹理。
因此,我尝试使用这段代码来渲染 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 设置为临时画布时调用清除。
I think I am fundamentally misunderstanding the way render targets work. In my understanding RenderTargets are just Textures that the spritebatch draw calls draw to.
So I tried this code to render GUI windows in order to make sure they can only draw in their client area and its cropped outside that.
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();
}
However this code only draws the last form in the list which means it must be clearing the main RT somehow but i dont understand why. I only call clear when the RT is set to the temp canvas.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(2)
您是如何创建渲染目标和后台缓冲区的?默认情况下,在更改为不同的渲染目标后,您无法多次写入渲染目标。这就是为什么:
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 提出的剪刀矩形光栅化器状态。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我认为绘制 gui 控件的最佳方法是使用 ScissorRectangle,因为我们只能在该矩形内绘制,这可以是 gui 控件的客户区域。
MSDN:GraphicsDevice.ScissorRectangle
您需要通过 RasterizerState 启用此功能。
在绘制之前,请使用此状态调用 SpriteBatch.Begin。
我自己的 gui 在 xbox360 中运行的视频:)
i think the best method to draw gui controls is with ScissorRectangle, because lets draw only inside that rectangle, that can be the client area of the gui control.
MSDN: GraphicsDevice.ScissorRectangle
You need to enable this funcionality through a RasterizerState.
Before you draw, call SpriteBatch.Begin with this state.
A video of my own gui running in a xbox360 :)