C++ Directx访问backbuffer
我正在尝试使用directx从backbuffer访问屏幕数据。但是,对于下面的代码,指向像素数据的指针的值都是0。 我真的不确定我是否正确地检查了数据。我正在Visual studio 2013上运行此程序,并使用断点检查指针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
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);