开发者

How can I retain render target results so they are non-volatile?

开发者 https://www.devze.com 2023-03-26 14:02 出处:网络
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 situatio

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 l开发者_运维问答ikely 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?


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);
}


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)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号