0

I have a problem with using render targets that I am hoping someone can explain to me. I am trying to use a render target to render some sprites, and then draw said render target onto the normal back buffer 50% opaque (null). It works great, except if I use the target more than once in a draw call, in which case only the last group of sprites will appear on the screen.

Here is some psuedo code.

// Normal Sprite Drawing.  
DrawSomeSprites();

SetRenderTarget(CompositeTarget);

// These go on the render target.  
DrawSomeMoreSprites();

SetRenderTarget(null);

// And now I draw onto the back buffer.  
DrawSprite(CompositeTarget);


// So now I want to draw another bunch of sprites via my render target using the same approach.
SetRenderTarget(CompositeTarget);

// These are the only sprites that I can see on the screen.
DrawSomeMoreSprites();             
SetRenderTarget(null);
DrawSprite(CompositeTarget);

I hope that makes sense. It seems to me that every time I change the render target, the previous render target (null) is cleared for some reason. I am ending all of my sprite batches before swapping the targets, and I am not getting any errors, so I don't know what to do here. Obviously the goal is to be able to see all of my sprite groups on the screen at the same time. What am I missing here ??

A.R.
  • 15,405
  • 19
  • 77
  • 123

1 Answers1

2

This article explains why your render targets are being cleared.

Basically it's a quirk of the way the XBox graphics system works. There's only one region of memory the XBox GPU can render into, and it's quite small. When you change render targets, that memory gets clobbered. In XNA 2.0 (as the article explains), the default behaviour of Windows was changed to match the Xbox 360 behaviour to keep things consistent and fast across platforms.

The parameter to select which behaviour you want is RenderTargetUsage. Just be aware that preserving contents on the XBox is slow.

Alternately you may be able to change the order you are doing your rendering so you don't run into this problem.

Andrew Russell
  • 26,924
  • 7
  • 58
  • 104
  • Rats! I finally got a copy of PIX working last night, and yes, I saw all of those different clears all over the place which is obviously the problem. I can't really change the order of the rendering because I have a layering system that won't jive with the current approach at all. Do you think that I could use a pixel shader instead to achieve the effect that I want? – A.R. Feb 10 '11 at 13:48
  • @A.R. Were you not able to fix it by changing RenterTargetUsage on the render target (or back buffer)? (Or are you targeting Xbox?) – Andrew Russell Feb 11 '11 at 04:18
  • Yeah, I can do the rendertarget change, but I will eventually target the XBOX with the engine eventually, so I'd rather find a more exciting way to shoot myself in the foot. =) At any rate, what do you think about the Pixel Shader idea? Some folk I know think it will work, but they aren't exactly pros. – A.R. Feb 11 '11 at 16:56
  • @A.R. I don't think a pixel shader alone will do what you want. The only way to "read" from the back-buffer (without resolving it to a texture) is through the blending stage. (You can also use the depth-stencil buffer in a similar way). Perhaps you can come up with the right combination of blend state and depth test to get your effect? (see my answer to your other question). The only other alternative is to use render targets and change the order of your rendering so you prepare all of your render-target-composed sprites before actually rendering any of your scene. – Andrew Russell Feb 12 '11 at 00:40
  • I guess that means that there is no reasonable way of doing it in a completely dynamic. If I had composite sprites taht were to live on top of each other for example, then using the render targets is not really feasible. I think I am just going to table the issue until I have more time to look into the depth-stencil stuff (since I know nothing about it). Thanks for all of your help. If I come up with something brilliant, I will let you know. – A.R. Feb 14 '11 at 19:08