我正在 XNA 中编写一个应用程序,它依赖于渲染目标,这些目标只渲染一次,然后无限期地使用。我遇到的问题是在某些情况下,渲染目标的内容会丢失或被丢弃,例如当计算机进入睡眠状态或应用程序进入全屏模式时。
当内容丢失时重新渲染到每个目标是一种选择,但可能不是最佳选择,因为当有很多目标时它可能会相当昂贵。
我可能可以将每个结果保存为 PNG 图像,然后将该 PNG 备份为纹理,但这会增加大量 I/O 开销。
建议?
我正在 XNA 中编写一个应用程序,它依赖于渲染目标,这些目标只渲染一次,然后无限期地使用。我遇到的问题是在某些情况下,渲染目标的内容会丢失或被丢弃,例如当计算机进入睡眠状态或应用程序进入全屏模式时。
当内容丢失时重新渲染到每个目标是一种选择,但可能不是最佳选择,因为当有很多目标时它可能会相当昂贵。
我可能可以将每个结果保存为 PNG 图像,然后将该 PNG 备份为纹理,但这会增加大量 I/O 开销。
建议?
到目前为止,我发现的最有可能的选择是使用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);
}
我相信
Presetnationparameters pp = graphics.PresentationParameters;
pp.RenderTargetUsage = RenderTargetUsage.PreserveContents;
应该做的伎俩。它与着色器模型在 PC 和 Xbox 上的工作方式以及着色器模型 2+ 如何使其相等有关。(默认情况下 Xbox 会覆盖其输出缓冲区,因此旧的渲染目标会被清除,而 PC 只使用其他一些内存)