BOOL CD3DCameraViewWnd::GetImageInfo(DWORD* pPixelBuffer, int& width,int& height)
{
BOOL result = FALSE;
IDirect3DSurface9 *_surfaceback = NULL;
if (FAILED(m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &_surfaceback)))
{
result = FALSE;
}
D3DSURFACE_DESC surfaceDesc;
if (!FAILED(_surfaceback->GetDesc(&surfaceDesc)))
{
width = surfaceDesc.Width;
height = surfaceDesc.Height;
}
D3DLOCKED_RECT lockedRect;
HRESULT hr = _surfaceback->LockRect( &lockedRect,0, 0); /* pointer to receive locked data指向申请到的内存区域*/ /* lock entire surface*/// no lock flags specified
if (!FAILED(hr))
{
pPixelBuffer = (DWORD*)lockedRect.pBits;
result = TRUE;
}
_surfaceback->UnlockRect();
_surfaceback->Release();
return result;
}
但是这样存在着性能的问题,经测试获取一帧需要200ms左右,为什么会存在这样的问题?因为这边有资源锁定操作。
现在关键的问题就在于,资源锁定的操作速度总是非常之慢.当然,你会跟我提, OpenGL似乎能够快捷地完成这项任务.但是,在Direct3D中,资源锁定操作确实是很慢的.这里面一个主要的原因是,API,驱动,以及硬件要处理一些不可回避的后台操作.那就是GPU与CPU是并行运行的,若不加任何措施,将引起类似多线程程序同步时的竞态条件的问题.
如果你试图去修改的资源正同时被一个位于GPU处理序列中的指令使用,那么整个渲染流程就会因为你的资源锁定而停顿或强制刷新(stalls and flushes).停顿(stall)会一直持续到你完成了对资源的修改并调用Unlock().而强制刷新(flush)则会要求GPU在你得到这个资源的访问权之前完成目前所有的任务.
如何去解决这个问题?下面的参考资料中有一些解决方案,我没有经过认真测试,我试了其中一个GetRenderTargetData 这样的一种方法 ,感觉不太好用,why请看Reference3
下面给出我的解决方案
BOOL CD3DCameraViewWnd::GetImageInfo(DWORD* pPixelBuffer, int& width,int& height)
{
BOOL result = FALSE;
IDirect3DSurface9 *_surfaceback = NULL;
if (FAILED(m_pDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &_surfaceback)))
{
result = FALSE;
}
D3DSURFACE_DESC surfaceDesc;
if (!FAILED(_surfaceback->GetDesc(&surfaceDesc)))
{
width = surfaceDesc.Width;
height = surfaceDesc.Height;
}
LPDIREC3DSURFACE9 surf;
if(FAILED(m_pDevice->CreateOffscreenPlainSurface(width, height,D3DFMT_A8R8G8B8,D3DPOOL_SYSTEMMEM, &surf,NULL)))
{
result = FALSE;
}
D3DXLoadSurfaceFromSurface(surf, NULL,NULL,_surfaceback,NULL,NULL,D3DX_FILTER_NONE,0);
D3DLOCKED_RECT lockedRect;
HRESULT hr = surf->LockRect( &lockedRect,0, 0); /* pointer to receive locked data指向申请到的内存区域*/ /* lock entire surface*/// no lock flags specified
if (!FAILED(hr))
{
pPixelBuffer = (DWORD*)lockedRect.pBits;
result = TRUE;
}
surf->UnlockRect();
surf->Release();
_surfaceback->Release();
return result;
}
参考资料:Reference1.http://www.cnblogs.com/mixiyou/archive/2010/02/25/1673060.html
Reference 2.http://www.cnblogs.com/mixiyou/archive/2010/02/25/1673425.html
Reference 3.http://blog.csdn.net/Nightmare/article/details/1707362
Reference 4.http://www.cnblogs.com/lancidie/archive/2011/3/14.html