1

DirectX9 を利用するエンジンを使用しています。

以下を使用してレンダー ターゲットを作成します。

D3DXCreateTexture(
    pD3DDevice, width, height, 1, 
    D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, 
    D3DPOOL_DEFAULT, &pRT
)


他のすべてのテクスチャは次のように作成されます。

D3DXCreateTexture(
    pD3DDevice, width, height,
    1, 0, D3DFMT_A8R8G8B8,
    D3DPOOL_MANAGED, &pTex
)

バックバッファも同様D3DFMT_X8R8G8B8なので、テクスチャの作成方法が異なる理由はわかりませんが、「壊れていない場合は修正しないでください」と思いますよね?すべてのテクスチャが問題なくロード/レンダリングされているように見えます。このエンジンの動作の詳細については、メイン グラフィック モジュールのコードをご覧ください。(主にandメソッド
に注意してください)...Target_CreateTexture_Create

ただし、レンダー ターゲット テクスチャを通常のテクスチャに変換しようとしているときに、これらのルールを守ろうとするのに非常に苦労しました。エンジンにはこの機能が組み込まれておらず、レンダー ターゲットはテクスチャとは別のオブジェクトとして扱われます。また、これにより、レンダー ターゲットを必要とするもの (ピクセル シェーダーなど)を実際に使用する能力が制限されます。最終的な結果として、このレンダー ターゲット データを、上記のように作成されたテクスチャにコピーする方法を見つける必要があります。これにより、エンジンは競合することなく使用できます。

私は次のようなことを試しました:

inline PVOID LockedBits(LPDIRECT3DSURFACE9 surface, UINT w, UINT h, INT* size)
{
    D3DLOCKED_RECT lr;
    RECT rc = {0, 0, w, h};
    surface->LockRect(&lr, &rc, 0);
    if(size) *size = (w*h) * 4;
    return lr.pBits;
}
inline PVOID LockedBits(LPDIRECT3DTEXTURE9 texture, UINT w, UINT h, INT* size)
{
    D3DLOCKED_RECT lr;
    RECT rc = {0, 0, w, h};
    texture->LockRect(0, &lr, &rc, 0);
    if(size) *size = (w*h) * 4;
    return lr.pBits;
}

LPDIRECT3DTEXTURE9 CloneTextureFromTarget(LPDIRECT3DDEVICE9 device, LPDIRECT3DTEXTURE9 target, UINT w, UINT h)
{
    D3DDISPLAYMODE dm;
    device->GetDisplayMode(0, &dm);

    // Create source and destination surfaces and copy rendertarget
    LPDIRECT3DSURFACE9 dstSurf = NULL, srcSurf = NULL;
    device->CreateOffscreenPlainSurface(w, h, dm.Format, D3DPOOL_SYSTEMMEM, &dstSurf, NULL);
    target->GetSurfaceLevel(0, &srcSurf);
    device->GetRenderTargetData(srcSurf, dstSurf);
    SafeRelease(&srcSurf);

    // Create destination texture
    LPDIRECT3DTEXTURE9 dstTexture = NULL;
    D3DXCreateTexture(device, w, h, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &dstTexture);

    // Get bits for destination surface and texture
    INT dwSrc, dwDst;
    PVOID pBitsSrc = LockedBits(dstSurf, w, h, &dwSrc);
    PVOID pBitsDst = LockedBits(dstTexture, w, h, &dwDst);

    // Copy bits from surface to texture
    RtlCopyMemory(pBitsSrc, pBitsDst, dwSrc);
    dstTexture->UnlockRect(0);
    dstSurf->UnlockRect();
    SafeRelease(&dstSurf);

    /* Just to double-check if it worked... */
    D3DXSaveTextureToFileA("C:\\outSrc.png", D3DXIFF_PNG, target, NULL);
    D3DXSaveTextureToFileA("C:\\outDst.png", D3DXIFF_PNG, dstTexture, NULL);

    // Return the result
    return dstTexture;
}

このコードの結果、両方のテクスチャがディスクに適切に保存され、期待どおりに出力されますが、適切にレンダリングされません...

私は何か間違ったことをしていますか?D3DFMT_A8R8G8B8と で作成された新しいテクスチャにこのデータの完全なコピーを実現する最善の方法は何D3DPOOL_MANAGEDですか?

4

1 に答える 1