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_Create
Texture_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
ですか?