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指向申請(qǐng)到的內(nèi)存區(qū)域*/ /* lock entire surface*/// no lock flags specified
if (!FAILED(hr))
{
pPixelBuffer = (DWORD*)lockedRect.pBits;
result = TRUE;
}
_surfaceback->UnlockRect();
_surfaceback->Release();
return result;
}
但是這樣存在著性能的問(wèn)題,經(jīng)測(cè)試獲取一幀需要200ms左右,為什么會(huì)存在這樣的問(wèn)題?因?yàn)檫@邊有資源鎖定操作。
現(xiàn)在關(guān)鍵的問(wèn)題就在于,資源鎖定的操作速度總是非常之慢.當(dāng)然,你會(huì)跟我提, OpenGL似乎能夠快捷地完成這項(xiàng)任務(wù).但是,在Direct3D中,資源鎖定操作確實(shí)是很慢的.這里面一個(gè)主要的原因是,API,驅(qū)動(dòng),以及硬件要處理一些不可回避的后臺(tái)操作.那就是GPU與CPU是并行運(yùn)行的,若不加任何措施,將引起類(lèi)似多線(xiàn)程程序同步時(shí)的競(jìng)態(tài)條件的問(wèn)題.
如果你試圖去修改的資源正同時(shí)被一個(gè)位于GPU處理序列中的指令使用,那么整個(gè)渲染流程就會(huì)因?yàn)槟愕馁Y源鎖定而停頓或強(qiáng)制刷新(stalls and flushes).停頓(stall)會(huì)一直持續(xù)到你完成了對(duì)資源的修改并調(diào)用Unlock().而強(qiáng)制刷新(flush)則會(huì)要求GPU在你得到這個(gè)資源的訪(fǎng)問(wèn)權(quán)之前完成目前所有的任務(wù).
如何去解決這個(gè)問(wèn)題?下面的參考資料中有一些解決方案,我沒(méi)有經(jīng)過(guò)認(rèn)真測(cè)試,我試了其中一個(gè)GetRenderTargetData 這樣的一種方法 ,感覺(jué)不太好用,why請(qǐng)看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指向申請(qǐng)到的內(nèi)存區(qū)域*/ /* 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