XNA中窗口系统的渲染策略(RenderTarget性能)

时间:2008-10-28 14:34:07

标签: 3d xna direct3d xbox360

我目前正在从头开始为XNA游戏创建一个窗口系统。我主要是为Windows开发,但谁知道我将来可能会支持哪些平台。如果您对本机Direct3D了解这一点,请随意回答,因为性能语义应该类似。如果可能的话,考虑一下如果目标平台是X-Box 360会发生什么变化。

我取得了很好的进展,但现在我不确定如何精确渲染窗户。我提出了四种方法:

  • 只需将所有控件直接渲染到屏幕上即可。这就是我现在所做的。只要控件不是半透明的,就可以通过在状态之间进行混合来控制动画。我没有找到一种在任意数量的状态之间制作动画的好方法(假设一个按钮当前是从按钮按下到按钮按下,从鼠标移出到鼠标悬停,然后它被禁用。它应该是从最后一个状态顺利地混合到新状态。通过这种方法,这只有在最后一个完成后播放一个动画时才有效,或者你将有动画跳跃。

  • 将每个顶级窗口和所有控件渲染到渲染目标中,然后使用它将半透明的顶级窗口渲染到屏幕上。这使得顶级工作的半透明性易于管理,但不会改变动画。

  • 将每个控件渲染为渲染目标,只有在控件变脏时才会更新(即必须设置动画或文本已更改)。这样,每个控件的半透明度就可以了。

  • 与之前的一样,但除了解决动画问题外,每个控件都有第二个渲染目标。每当动画开始时,交换渲染目标,因此我们在动画开始时具有状态,并将其与目标状态混合到另一个渲染目标中。这不应该增加前一种方法的开销,我们只有两倍的渲染目标,在任何给定的帧中只有一个渲染到(最大)。但问题出现了:为了实现这一点,我需要让“旧”渲染目标保留其内容。这应该在Windows上具有良好的性能,但似乎对X-Box 360有严重的性能影响。另一方面,只有在动画处于活动状态时才需要“保留”位。

这是实际的问题。任何澄清的东西都是受欢迎的。对于性能问题,请记住这只是游戏的窗口系统 - 后面的游戏可能会使用许多渲染目标并且也会吸收性能,并且可能比窗口系统更多。假设在绝对最坏的情况下,我们可能在屏幕上有五个顶级窗口,每个窗口有20-40个控件。

  • 您会推荐以下哪种方法?为什么?当然,请随意添加另一种方法。
  • 如果让200个或400个渲染目标可用,是否会产生性能影响,前提是它们中只有20个渲染到每个帧?
  • PreserveContents对X-Box 360的性能影响真的那么糟糕吗? Windows上有多糟糕?
  • 可以写入RenderTarget2D.RenderTargetUsage属性。在运行时切换它是个好主意,只在需要时启用PreserveContents吗?
  • 你(作为玩家)是否会想到控制动画是否会在某些情况下跳跃,例如将鼠标悬停在按钮上,将鼠标移出然后再移动,这样“正常 - >悬停”动画就会播放两次开始因为它比你慢?

3 个答案:

答案 0 :(得分:4)

如果您正在为Xbox 360开发,则必须小心渲染目标。 Xbox 360有一个特殊的内存(10MB)来保存渲染目标,包括用于在屏幕上渲染的目标。

只要不超过10MB,即使使用PreserveContents,从一个渲染目标切换到另一个也不会产生任何影响,因为所有渲染目标都存储在此特殊内存中。

但是,如果使用PreserveContents的渲染目标超过10MB,则必须通过不断地将渲染目标切换回正常内存来模拟此属性。

因此渲染目标的数量不如那些目标的总大小重要。您可以使用以下公式知道渲染目标的大小:

size (bits) = width  x height x color data size (bits)

Xbox 360上的颜色数据大小是32位所以,举个例子,如果您的图书馆用户正在开发他的高清游戏而没有其他渲染目标,那么他将使用:

3,515625MB = 29491200 bits = 1280 x 760 x 32 bits

此外,您应该避免动态创建渲染目标。它花了太多钱。您应该在游戏开始时创建一个静态渲染目标池,并让您的GUI组件请求它们。

答案 1 :(得分:3)

  • 如果你想要那种带有动画的控制级别(即多次同时使用同一个控件)那么你将会进行多次传递。因此,要么在着色器中启用此类操作并使用着色器执行多次传递,要么执行标准的Render-> Resolve-> Rerender循环。
  • 确实创造了许多渲染的性能。创造那么多不是一个好主意。您最好使用较小数量的渲染目标,并为该目标写入多个控件。
  • 自从我做了任何360 dev(bugger :()以来已经很久了,但是从我可以记住的事情来看,它并不是那么好。除非绝对必要,否则我会避免这个选项。希望有更多最新经验的人可以在这里帮忙。
  • 这可能在运行时工作,但可能涉及幕后的一些工作。我不希望它表现得太好。如果你不是在渲染循环中进行它,我肯定没问题。
  • 我认为跳跃的动画肯定会很糟糕。 Imho:)

答案 2 :(得分:1)

Xbox360具有10MB的特殊内存,用于当前的渲染目标。但其余人说如何运作并不准确。无论使用什么渲染目标都在10MB的空间内。否则,您可以拥有任意数量的渲染目标。如果你的渲染目标大于10MB(如1280x720并且有一些AA多重采样),那么xbox360使用一种名为Predicated Tiling的技术:http://msdn.microsoft.com/en-us/library/bb464139.aspx

我正在编写一个窗口系统。我将窗口小部件渲染到渲染目标,然后将窗口小部件目标渲染到窗口目标,窗口目标渲染到后台缓冲区。这允许我轻松添加滚动条并仅将窗口小部件渲染目标的一部分渲染到窗口渲染目标上。如果有更好的方法来处理滚动窗口内容工作让我知道。不确定这是否是性能最佳的。