C++ Directx访问backbuffer

C++ Directx访问backbuffer,c++,directx,buffer,C++,Directx,Buffer,我正在尝试使用directx从backbuffer访问屏幕数据。但是,对于下面的代码,指向像素数据的指针的值都是0。 我真的不确定我是否正确地检查了数据。我正在Visual studio 2013上运行此程序,并使用断点检查指针b。它的值始终为0。 我知道我没有使用IDirect3DDevice9::GetRenderTargetData方法。我想这会导致我尝试访问设备内存中的数据。它会阻止我获得正确的像素数据吗 d3dManager = new D3DManager(NULL, 600, 60

我正在尝试使用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
获得的backbuffer的引用

 D3DSURFACE_DESC pDesc;
 ppBackBuffer->GetDesc(&pDesc);
 HANDLE *handle = NULL;
 device->CreateOffscreenPlainSurface(pDesc.Width, pDesc.Height, pDesc.Format, D3DPOOL_SYSTEMMEM, &ppBackBuffer, handle);
您需要实际调用
GetRenderTargetData
将数据从backbuffer(可能位于CPU完全无法访问的视频内存中)复制到可以从CPU读取的曲面

顺便说一句,检查您调用的HRESULT,特别是
CreateOffscreenPlainSurface
LockRect

编辑:如果要创建一个与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);
D3D表面描述pDesc;
ppBackBuffer->GetDesc(&pDesc);
ppBackBuffer->Release();//CreateOffscreenPlainSurface(pDesc.Width、pDesc.Height、pDesc.Format、D3DPOOL_SYSTEMMEM和ppBackBuffer、handle);

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

对不起,ppBackBuffer不是应该被CreateOffscreenPlainSurface覆盖,因为该方法应该填充它吗?您调用
GetBackBuffer
,它返回一个指向后缓冲区表面的COM对象指针。然后调用
CreateOffscreenPlainSurface
,它将创建一个新的曲面并返回一个COM对象指针,该指针将原始COM对象指针撞向后缓冲区曲面。换句话说,通过调用
GetBackBuffer
完成的唯一一件事就是在获取属性后将引用计数增加1。
 D3DSURFACE_DESC pDesc;
 ppBackBuffer->GetDesc(&pDesc);
 HANDLE *handle = NULL;
 device->CreateOffscreenPlainSurface(pDesc.Width, pDesc.Height, pDesc.Format, D3DPOOL_SYSTEMMEM, &ppBackBuffer, handle);