我正在尝试使用DirectX从BackBuffer访问屏幕数据。但是,使用下面的代码,像素数据的指针全为0。
我真的不确定我是否正确检查数据。我在Visual Studio 2013上运行此程序,并使用断点检查指针b。它的值一直都是0。
我知道我没有使用IDirect3DDevice9::GetRenderTargetData方法。这使我尝试访问我认为是设备内存中的数据。这会阻止我获取正确的像素数据吗?

d3dManager = new D3DManager(NULL, 600, 600);
    IDirect3DDevice9 *device = d3dManager->getDevice();
    IDirect3DSurface9 *ppBackBuffer = NULL;
    HRESULT result = device->GetBackBuffer(
        0,
        0,
        D3DBACKBUFFER_TYPE_MONO,
        &ppBackBuffer
    );

    if (FAILED(result))
    {
        printf("vuhu");
        return 1;
    }

    D3DSURFACE_DESC pDesc;
    ppBackBuffer->GetDesc(&pDesc);
    HANDLE *handle = NULL;
    device->CreateOffscreenPlainSurface(pDesc.Width, pDesc.Height, pDesc.Format, D3DPOOL_SYSTEMMEM, &ppBackBuffer, handle);


    D3DLOCKED_RECT lockedRectangle;
    ppBackBuffer->LockRect(&lockedRectangle, NULL, D3DLOCK_DONOTWAIT);
    void* bits = lockedRectangle.pBits;
    int *a = (int*)(bits);
    int *b = a + 120;

最佳答案

当您在此处调用CreateOffscreenPlainSurface并传入ppBackBuffer时,它会被覆盖,因为它正在创建默认情况下为空的新表面。实际上,您只是泄漏了对从GetBackBuffer获得的后缓冲区的引用。

 D3DSURFACE_DESC pDesc;
 ppBackBuffer->GetDesc(&pDesc);
 HANDLE *handle = NULL;
 device->CreateOffscreenPlainSurface(pDesc.Width, pDesc.Height, pDesc.Format, D3DPOOL_SYSTEMMEM, &ppBackBuffer, handle);


您实际上需要调用GetRenderTargetData来将数据从后缓冲区(可能在视频存储器中完全无法访问CPU)复制到可以从CPU读取的表面上。

顺便说一句,检查您的呼叫的HRESULT,特别是CreateOffscreenPlainSurfaceLockRect

编辑:如果您的意思是创建一个具有与后缓冲相同属性的新表面,那么您应该这样做:

D3DSURFACE_DESC pDesc;
ppBackBuffer->GetDesc(&pDesc);
ppBackBuffer->Release(); // <--- Let go of our reference to the back buffer surface
HANDLE *handle = NULL;
device->CreateOffscreenPlainSurface(pDesc.Width, pDesc.Height, pDesc.Format, D3DPOOL_SYSTEMMEM, &ppBackBuffer, handle);


您的代码中根本没有任何内容实际上是将后缓冲区的内容移到新的表面。您只是在重用变量IDirect3DSurface9 *ppBackBuffer

关于c++ - Directx访问后缓冲,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28045773/

10-09 13:08