June
June

Reputation: 3307

XNA clears textures mid-render?

We're prerendering large sets of textures to RenderTexture2D and this is the issue we're having:

Render issues with XNA

It seems that randomly during the render of a chunk, the textures for each cell (the top and sides) will corrupt and disappear. The weird things is that they come back when the next chunk is rendered though, so it seems to be something that is occurring on a per-frame basis.

Does anyone know why this occurs (and randomly it seems; note the white rectangle is where a side texture corrupts and you can see from there on out the texture contains just transparent)?

EDIT: The sides of the cubes are being saved to Texture2D but they are still disappearing in the middle of a chunk render and then coming back on the next one. So I don't understand why graphics that are in Texture2D are disappearing and coming back, without reinitialization (and that's the weird part).

Upvotes: 1

Views: 249

Answers (2)

June
June

Reputation: 3307

I can't say that we ever solved this issue for sure, but it appears to have been something caused by either threading or splitting the task across multiple cycles. It wasn't an issue with the RenderTarget2D since we were already doing that at the time.

Upvotes: 0

Jeremy Mone
Jeremy Mone

Reputation: 11

RenderTexture2D is only a temporary memory construct, and gets flushed quite quickly and regularly. It is because it is reused in an effort to save memory and to a lesser extent to speed things up. As such you should only treat it as a very temporary place to store your texture. You will want to shift it to a proper Texture2D which will be stored for longer. As just doing a simple:

Texture2D YourPic = (RenderTexture2D)SomeRenderedPic;

Will not do it. This just passes the pointer to the memory space of the rendered image. When the graphics card discards it, then it will still just vanish. What you want to do is something more like:

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

Now if I have whipped up that code right then it should store the data and not the pointer into the new texture. This makes the new texture its own unique memory space that won't get flushed the same way a Render Target space would.

There is a down side to this method. It cannot be done at the full refresh rate of XNA. (Something like 60 frames a second... I think... maybe 30... I forget.) At any rate, this may not be fast enough if you need a very constant refreshing. However if you are creating a static texture that doesn't really change much if ever, then this may do the trick for you.

Hopefully this made sense as I am writing this on the fly and late at night. If this doesn't work I apologize. Feel free to write me at [email protected] if need be. If I am able to answer your questions I will be happy to.

Otherwise good luck, and be inventive. I am sure there is a solution.

x Jeremy M.

Upvotes: 1

Related Questions