Directx访问后台缓冲区

时间:2015-01-20 12:47:47

标签: c++ directx buffer

我正在尝试使用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;

1 个答案:

答案 0 :(得分:0)

当您在此处调用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读取的曲面。

顺便说一句,检查来电的问题,特别是CreateOffscreenPlainSurfaceLockRect

编辑:如果你要做的是创建一个与backbuffer具有相同属性的新曲面,那么你应该这样做:

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