Alright, so the API for this is totally different for beta 2. That's fine. But I can't see how you create depth textures now. I'm using them to render shadows.
Also, how do you get and restore the back buffer now Do you do something like:
RenderTarget2D backBuffer = (RenderTarget2D)device.GetRenderTarget(0);
...
device.SetRenderTarget(0, backBuffer);

Creating depth textures and getting back buffer in beta 2?
Sudheer Kandali
Also, Shawn got to this thread right before I did. But what I lose in timeliness I make up for in volume! :)
His answer about why you can't get the depth stencil buffer is much more correct than mine.
Sandyee
I'm creating a SurfaceFormat.Color render target (RenderTarget2D) and a DepthFormat.Depth24Stencil8 depth stencil surface (DepthStencilBuffer). I render - or I would if I could get this to work - into both for my shadows.
Regardless of what DepthStencilBuffer looks like, the class is more than just information - it's the buffer itself. The problem is that I don't understand how to get the texture from it, so there's no way I can set it into my shader. I didn't have this problem in beta 1 when the interface was totally different.
GS80
HumteeDumbtee
We took out that ability because it doesn't work consistently on all cards: some graphics vendors have hacked the ability into their drivers, but this isn't an official part of the DX spec and people who use it tend to get in trouble when they try to run their program on a wider range of graphics cards and realise this doesn't work any more! It also doesn't work on Xbox.
The more robust and cross platform way to do shadows is to render depth values into a floating point RenderTarget2D.
Rod Yager
To achieve colored/alpha blended shadows I use two render targets. One render target receives the shadow depth "color", which is just a single floating point value. The other render target receives the shadow color and alpha. In my main pixel shader I fetch the depth and color/alpha values and do a blend between the two.
I will post a link to the project (which of course will include the source code) I'm working on when I'm done, which should be very soon.
Thanks for the help everybody.
mlgray
Sorry for the multiple answers:
You can create your own DepthStencilBuffer with it's constructor, and set it on the device. When Draw (with the DepthBufferEnable render state turned on) or Clear (using the Color-only overload or specifying ClearOptions.DepthBuffer) are called, then the depth buffer must exist and match the resolution of the render target/back buffer set on that index. If you don't want to bother with that, then set the DepthStencilBuffer on the device to null and turn off the render state (and make sure you use the full Clear overload and specify ClearOptions.Target only).
Also, you can change the device-created depth buffer (or turn off EnableAutoDepthStencil). You would add a method to handle the GraphicsDeviceManager's PreparingDeviceSettings event, and addthat method on the event in the game template constructor. You can modify the arguments passed into that method, giving you more control while still letting the nice GraphicsDeviceManager handle everything else. :)
Finally, the big thing to wrap your head around with Resolve is that it clears the contents of GetTexture(). That means that you cannot accumulate a render target through multiple Sets. Multiple Draws between SetRenderTarget and before ResolveRenderTarget accumulate, of course, but if you do:
SetRenderTarget(0, rt1);
DrawObject1();
ResolveRenderTarget(0, rt1); // after this, rt1.GetTexture has the results of the DrawObject1 call
SetRenderTarget(0, rt2);
DrawObject2();
ResolveRenderTarget(0);
SetRenderTarget(0, rt1);
DrawObject3();
ResolveRenderTarget(0); // after this, rt1.GetTexture only has the results of the DrawObject3 call!
... then you only get the results from the last Resolve. It clears before Resolving (again, 360 platform behavior that is unified on both the PC and 360).
jsdude99
This seems very strange. It forces you to use RenderTarget2D now instead of Texture2Ds with render target usage. That doesnt seem too bad.
So you want to get the backbuffer, and copy that into a texture.
You do ResolveBackbuffer(texture, index) but how do you get the RenderTarget2D from the texture
And how do you even copy between RenderTarget2D's
bobbins
I appreciate the response, but I have to ask: if there's no way to get the depth buffer with the current API then how do you recommend shadow mapping be done I was previously rendering into a color and depth buffer so that I could get transparent shadows (it looks roughly like the shadows being cast by light shining through a stained glass window).
figuerres
I'm not sure I understand your question.
In MDX I mostly use a R32F render target as my shadow map, into which I render the depth from the light using a pixel shader. Then when rendering the final scene, you can use this shadow map as a texture in another shader/technique to render the shadows. This is also demonstrated in the ShadowMap sample in the DX SDK. The SurfaceFormat.Single seems to correspond with the R32F format, so this should work out.
The DepthStencilSurface class only seems to hold info about the depth buffer and no data (inhereting only from IDisposable and exposing no useful members), so the shader/RenderTarget approach looks like the only way to go in XNA.
And @X-tatic: I posted a suggestion to copy between render targets in your topic on them. Works for me, so I hope that helps
arcliner
Douglas Penna
You can create render targets with SurfaceFormat.Single, which still seems to work as it should. As for rendering to textures, I posted a snippet in this topic (sorry if I'm spamming about it, but I guess it's not easy to be found there).
As for retrieving the backbuffer, I guess that's simply 'not done'. Calling GetRenderTarget(0) on a virgin device will return null. Restoring the backbuffer is apperently done by calling SetRenderTarget(0, null) once you're done with your target and called ResolveRenderTarget on it. It might be possible to copy the backbuffer onto a texture using the ResolveBackBuffer method, which takes a Texture2D as a parameter, but I haven't tested this yet.
Sioln
If you create a render target as SurfaceFormat.Single, how do you get the DepthStencilBuffer that you use to set into the GraphicsDevice.DepthStencilBuffer
Gary_MN
null represents the implicit back buffer (i.e. the one created by the device). So, as previously answered, SetRenderTarget(index, null) will set the render target at that index to the implicit one.
In general - Textures (2D, 3D, Cube) are inputs to shaders, RenderTargets (2D or Cube, specifying a face) are potential outputs from shaders. First you set the render target on the device, then you "draw" to it (Clear, Draw*, etc.). When you're done using the render target, you have to call ResolveRenderTarget(index). This is a requirement of the 360 implementation, and it is pretty clean once you get used to it. It also makes generating mipmaps for mipmapped render targets a lot easier (i.e. automatic). If you want to use the contents of a RenderTarget after it has been resolved, then you can call GetTexture on that object (it returns the same object each time, filled with the results of the draw calls on Resolve).
There is no way to get the contents of the depth buffer with the current API. You could render that information into a regular color buffer, but that's definitely not ideal. This was mostly done for cross-platform compatibility. This does complicate a number of shadowing patterns, which we are aware of. If this is a major problem, then please provide feedback via the Connect tool described in the XNA F.A.Q.