【问题标题】:XNA clears textures mid-render?XNA 在渲染中清除纹理?
【发布时间】:2012-08-14 06:15:35
【问题描述】:

我们正在将大量纹理预渲染到 RenderTexture2D,这就是我们遇到的问题:

似乎在渲染块期间随机地,每个单元格(顶部和侧面)的纹理会损坏并消失。奇怪的是,当渲染下一个块时它们会回来,所以它似乎是每帧发生的事情。

有谁知道为什么会发生这种情况(而且似乎是随机的;注意白色矩形是侧面纹理损坏的地方,您可以从那里看到纹理只包含透明)?

编辑:立方体的侧面被保存到 Texture2D,但它们仍然在块渲染的中间消失,然后在下一个渲染时又回来了。所以我不明白为什么 Texture2D 中的图形在没有重新初始化的情况下消失并返回(这是奇怪的部分)。

【问题讨论】:

标签: c# xna textures


【解决方案1】:

RenderTexture2D 只是一个临时内存结构,并且会很快且定期地刷新。这是因为它被重用以节省内存并在较小程度上加快速度。因此,您应该只将其视为存储纹理的非常临时的地方。您需要将其转换为合适的 Texture2D,以便存储更长时间。就像做一个简单的:

Texture2D YourPic = (RenderTexture2D)SomeRenderedPic;

不会这样做。这只是将指针传递给渲染图像的内存空间。当显卡丢弃它时,它仍然会消失。你想做的更像是:

Color[] MyColorArray = new Color[SomeRenderedPic.Width * SomeRenderedPic.Height];
SomeRendeerPic.GetData<Color>(MyColorArray);
Texture2D YourPic = new Texture2D(
        GraphicsDevice,
        SomeRenderedPic.Width,
        SomeRenderedPic.Height);
YourPic.SetData<Color>(MyColorArray);

现在,如果我正确地编写了该代码,那么它应该将数据而不是指针存储到新纹理中。这使得新纹理拥有自己独特的内存空间,不会像渲染目标空间那样被刷新。

这种方法有一个缺点。它不能在 XNA 的全刷新率下完成。 (大约每秒 60 帧……我想……也许是 30 帧……我忘了。)无论如何,如果您需要非常持续的刷新,这可能还不够快。但是,如果您正在创建一个不会真正改变太多的静态纹理,那么这可能会为您解决问题。

希望这是有道理的,因为我是在飞行中和深夜写这篇文章的。如果这不起作用,我道歉。如果需要,请随时通过 jareth_gk@hotmail.com 给我写信。如果我能够回答您的问题,我将很高兴。

否则祝你好运,并发挥创造力。我相信有一个解决方案。

x 杰里米 M.

【讨论】:

  • 发布代码时,突出显示它并点击{} 代码按钮 - 它将其设置为语法突出显示,这往往使答案更具可读性(它也不会折叠代码块中的换行符)
  • +1。但是,我很确定“定期和快速”并不完全准确。只有当GraphicsDevice 以某种方式重置时它们才会消失(您可以使用RenderTarget2D.IsContentLostContentLost 检测到)。如果使用SetRenderTarget 将它们放回GraphicsDevice 并将它们的RenderTargetUsage 设置为DiscardContents(默认值,或Xbox 上的PlatformContents),它们就会被清除。我从来没有听说过他们因为任何其他原因离开?
  • 有趣的是,我们实际上是将等距边渲染到 RenderTarget2D,然后按照您所说的转换为 Texture2D。有趣的是,立方体的边在渲染一个块时会消失,然后在渲染下一个时又回来,即使我们只在游戏开始时初始化等距立方体纹理。
【解决方案2】:

我不能说我们确实解决了这个问题,但它似乎是由线程化或将任务拆分到多个周期引起的。这不是 RenderTarget2D 的问题,因为我们当时已经这样做了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-27
    相关资源
    最近更新 更多