c++ - 将渲染目标数据复制到 D3DPOOL_MANAGED?

标签 c++ copy directx textures render-to-texture

我是 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_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_A8R8G8B8D3DPOOL_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/

相关文章:

c++ - 使用#ifdef 时的多个定义

c++ - DirectX11 - 几何着色器流输出流未定义

c++ - 有哪些适合初学者的 DirectX 资源?

c++ - Direct3D 11 - 绘制三角形

c++ - 指向指针或引用的迭代器 - 错误

c++ - 模板基类实现一个默认实现

java - 如何将jar内的文件复制到jar外?

Java,clone()问题?

c# - 正确复制其中包含(字节)数组的 C# 结构?

c# - 我读过 std::list 很糟糕。有人可以将它与 .Net 的 List<> 类型进行比较吗?我要从 C# 转到 C++