如何从DirectX中获取图像


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

posted on 2011-12-23 17:45 Daywei 阅读(2662) 评论(0)  编辑 收藏 引用 所属分类: CODEDirectX


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年4月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

导航

统计

常用链接

留言簿

随笔分类

随笔档案

文章档案

牛人博客

搜索

积分与排名

最新评论

阅读排行榜