0

レンダー ターゲットを切り替える前に深度バッファーから 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;
    }
4

1 に答える 1

1

XNA3.1 は、レンダー ターゲットの変更時に深度ステンシル バッファーをクリアしませんが、レンダー ターゲットの変更に注意しないと解決されます (深度テストには使用できません)。

例えば:

SetRenderTarget(someRenderTarget)
DrawStuff()
SetRenderTarget(null)
SetRenderTarget(someOtherRenderTarget)

深度ステンシル バッファーが解決されますが、次の場合は解決されません。

SetRenderTarget(someRenderTarget)
DrawStuff()
SetRenderTarget(someOtherRenderTarget)

なぜこれが XNA3.1 (およびそれ以前のバージョン) で発生するのかはわかりませんが、それを理解して以来、多くのレンダー ターゲットの変更を通じて同じ深度ステンシル バッファーを維持することができました。指定された ClearOptions.Target のみをクリアします。

于 2012-01-11T20:08:08.630 に答える