我是 using an engine它利用 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
所以我不确定为什么创建的纹理不同......但我想 “如果它没有坏,就不要修复它,” 对吗?所有纹理似乎都可以正常加载/渲染。
有关此引擎如何运行的更多详细信息,here is it's main graphics module's code .
(主要注意 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
创建的新纹理中的最佳方法是什么?
最佳答案
TBH 更改您的复制方法如下:
char* pSrc = (char*)pBitsSrc;
char* pDst = (char*)pBitsDst;
int p = 0;
int pMax = w * h;
while( p < pMax )
{
// Copy B
*pDst = *pSrc;
pDst++;
pSrc++;
// Copy G
*pDst = *pSrc;
pDst++;
pSrc++;
// Copy R
*pDst = *pSrc;
pDst++;
pSrc++;
// Set A
*pDst = 0xff;
pDst++;
pSrc++;
p++;
}
或者如果失败,只需将目标纹理创建为 D3DFMT_X8R8G8B8。
关于c++ - 将渲染目标数据复制到 D3DPOOL_MANAGED?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16313269/