如何保留渲染目标结果,使其保持非易失性?

发布于 2024-11-28 06:06:28 字数 241 浏览 1 评论 0原文

我正在 XNA 中编写一个应用程序,该应用程序依赖于仅渲染一次,然后无限期使用的渲染目标。我遇到的问题是,在某些情况下,渲染目标的内容会丢失或被丢弃,例如当计算机进入睡眠状态或应用程序进入全屏模式时。

当内容丢失时重新渲染到每个目标是一种选择,但可能不是最好的选择,因为当有很多目标时,成本可能相当高。

我可能可以将每个结果保存为 PNG 图像,然后将该 PNG 作为纹理加载备份,但这会增加大量 I/O 开销。

建议?

I am writing an application in XNA that relies on render targets that are rendered to just once, and then used indefinitely afterwards. The problem I've encountered is that there are certain situations where the render targets' contents are lost or disposed, such when the computer goes to sleep or the application enters full-screen mode.

Re-rendering to each target when content is lost is an option, but likely not the best option, as it could be fairly costly when there are many targets.

I could probably save each result as a PNG image and then load that PNG back up as a texture, but that adds a lot of I/O overhead.

Suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

来日方长 2024-12-05 06:06:28

到目前为止,我发现最有可能的选择是使用 GetData()SetData()RenderTarget2D 复制到新的 Texture2D。

由于我想要一个 mip 映射纹理,我发现我必须将每个 mip 级别单独复制到新纹理,如下所示。如果您不这样做,当您远离该对象时,该对象将变黑,因为 mip 贴图中没有数据。请注意,渲染目标也必须进行 mip 映射。

Texture2D copy = new Texture2D(graphicsDevice,
    renderTarget.Width, renderTarget.Height, true,
    renderTarget.Format);

// Set data for each mip map level
for (int i = 0; i < renderTarget.LevelCount; i++)
{
    // calculate the dimensions of the mip level.
    // Math.Max because dimensions always non-zero
    int width = (int)Math.Max((renderTarget.Width / Math.Pow(2, i)), 1);
    int height = (int)Math.Max((renderTarget.Height / Math.Pow(2, i)), 1);

    Color[] data = new Color[width * height];

    renderTarget.GetData<Color>(i, null, data, 0, data.Length);
    copy.SetData<Color>(i, null, data, 0, data.Length);
}

Most likely option I've found so far is to use GetData() and SetData() to copy from the RenderTarget2D to a new Texture2D.

Since I want a mip mapped texture, I found that I had to copy each mip level individually to the new texture, like so. If you don't do this, the object will turn black as you move away from it since there's no data in the mip maps. Note that the render target must also be mip mapped.

Texture2D copy = new Texture2D(graphicsDevice,
    renderTarget.Width, renderTarget.Height, true,
    renderTarget.Format);

// Set data for each mip map level
for (int i = 0; i < renderTarget.LevelCount; i++)
{
    // calculate the dimensions of the mip level.
    // Math.Max because dimensions always non-zero
    int width = (int)Math.Max((renderTarget.Width / Math.Pow(2, i)), 1);
    int height = (int)Math.Max((renderTarget.Height / Math.Pow(2, i)), 1);

    Color[] data = new Color[width * height];

    renderTarget.GetData<Color>(i, null, data, 0, data.Length);
    copy.SetData<Color>(i, null, data, 0, data.Length);
}
自演自醉 2024-12-05 06:06:28

我相信

Presetnationparameters pp = graphics.PresentationParameters;
pp.RenderTargetUsage = RenderTargetUsage.PreserveContents;

应该能成功。它与着色器模型在 PC 和 Xbox 上的工作方式以及着色器模型 2+ 如何使其平等有关。 (Xbox 默认情况下会覆盖其输出缓冲区,因此旧的渲染目标会被清除,而 PC 仅使用一些其他内存)

I believe

Presetnationparameters pp = graphics.PresentationParameters;
pp.RenderTargetUsage = RenderTargetUsage.PreserveContents;

Should do the trick. It has to do with how shadermodels work on PC and Xbox, and how shadermodel 2+ made it equal. (Something about Xbox overwriting its output buffer by default, hence old rendertargets clear, whilst PC just uses some other memory)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文