Jump to content
  • Advertisement
Sign in to follow this  

XNA 3.1 Preserving the Depth Buffer before it clears

This topic is 2882 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I've come up with a solution to get around XNA 3.1's automatic clearing of the depth buffer when XNA switches render targets by copying the IDirect3DSurface9 from the depth buffer before the render targets are switched, and then finally restoring the depth buffer at a later point just afterwards. However, I'm stuck on one error.

In the code below, the getDepthBuffer method is a pointer to the IDirect3DDevice9 GetDepthStencilBuffer function. The pointer to that method seems to be correct, but when I try to get the IDirect3DSurface9 pointer it returns an exception (0x8876086C - D3DERR_INVALIDCALL). The surfacePtr pointer ends up pointing to 0x00000000.

Any idea on why this is happening, or how to fix it? Any help on this would be greatly appreciated!

Heres the code:

public static unsafe Texture2D GetDepthStencilBuffer(GraphicsDevice g)
if (g.DepthStencilBuffer.Format != DepthFormat.Depth24Stencil8)
return null;

Texture2D t2d = new Texture2D(g, g.DepthStencilBuffer.Width, g.DepthStencilBuffer.Height, 1, TextureUsage.None, SurfaceFormat.Color);
FieldInfo f = typeof(GraphicsDevice).GetField("pComPtr", BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.Instance);
object o = f.GetValue(g);
void* devicePtr = Pointer.Unbox(f.GetValue(g));
void* getDepthPtr = AccessVTable(devicePtr, 160);
void* surfacePtr;

// ******** POINTER TO IDirect3DDevice9 GetDepthStencilBuffer WORKS OK ********
var getDepthBuffer = (GetDepthStencilBufferDelegate)Marshal.GetDelegateForFunctionPointer(new IntPtr(getDepthPtr), typeof(GetDepthStencilBufferDelegate));

// ******** RETURNS D3D ERROR 0x8876086C - D3DERR_INVALIDCALL ********
var rv = getDepthBuffer(&surfacePtr);

SetData(t2d, 0, surfacePtr, g.DepthStencilBuffer.Width, g.DepthStencilBuffer.Height, (uint)(g.DepthStencilBuffer.Width / 4), D3DFORMAT.D24S8);
Marshal.Release(new IntPtr(devicePtr));
Marshal.Release(new IntPtr(getDepthPtr));
Marshal.Release(new IntPtr(surfacePtr));
return t2d;

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!