レンダー ターゲットを切り替える前に深度バッファーから IDirect3DSurface9 をコピーし、後で深度バッファーを復元することで、レンダー ターゲットを切り替えるときに XNA 3.1 の深度バッファーの自動クリアを回避しようとしています。
コードでは、getDepthBuffer メソッドは IDirect3DDevice9 GetDepthStencilBuffer 関数へのポインターです。そのメソッドへのポインターは正しいようですが、IDirect3DSurface9 ポインターを取得しようとすると、例外 (0x8876086C - D3DERR_INVALIDCALL) が返されます。surfacePtr ポインターは、最終的に 0x00000000 を指します。
なぜそれが機能していないのかについて何か考えはありますか? そして、それを修正する方法についてのアイデアはありますか?
コードは次のとおりです。
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;
var getDepthBuffer = (GetDepthStencilBufferDelegate)Marshal.GetDelegateForFunctionPointer(new IntPtr(getDepthPtr), typeof(GetDepthStencilBufferDelegate));
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;
}