Directx Direct3D:从IDirect3DSurface9(默认池)获取系统内存位图的有效方法?
我有IDirect3DSurface9,默认池,YUV格式。如何有效地从中获取位图位?此刻我:Directx Direct3D:从IDirect3DSurface9(默认池)获取系统内存位图的有效方法?,directx,direct3d,direct3d9,rendertarget,Directx,Direct3d,Direct3d9,Rendertarget,我有IDirect3DSurface9,默认池,YUV格式。如何有效地从中获取位图位?此刻我: 创建渲染目标: device->CreateRenderTarget(surf_desc.Width、surf_desc.Height、D3DFMT_A8R8G8B8、D3DMULTISAMPLE_NONE、0、TRUE和render_target、NULL) 将YUV转换为RGB32: device->StretchRect(videomem\u surf,NULL,render\u target\
- 创建渲染目标:
device->CreateRenderTarget(surf_desc.Width、surf_desc.Height、D3DFMT_A8R8G8B8、D3DMULTISAMPLE_NONE、0、TRUE和render_target、NULL)
- 将YUV转换为RGB32:
device->StretchRect(videomem\u surf,NULL,render\u target\u,NULL,D3DTEXF\u NONE)
(完整的矩形,无拉伸)
- 在系统内存中创建普通屏幕外表面
device->CreateOffscreenPlainSurface(冲浪描述宽度、冲浪描述高度、D3DFMT\U A8R8G8B8、D3DPOOL\U系统内存和系统内存屏幕外冲浪、空)
- 将数据从视频内存复制到系统内存:
device->GetRenderTargetData(渲染目标、系统内存、屏幕外表面)
- 从屏幕外表面获取DC,创建兼容DC和兼容位图,将位图从屏幕外表面复制到兼容DC,并通过GetDIBits()将位图位复制到我的缓冲区。
谢谢因为您在可锁定模式下创建了渲染目标(第6个参数为
CreateRenderTarget
),所以您可以使用LockRect
锁定渲染目标,并直接从那里复制数据
MSDN不建议使用可锁定渲染目标,并且:
如果需要对渲染目标进行读取访问,请使用GetRenderTargetData而不是lockable
渲染目标
因此,另一种方法是将
GetRenderTargetData
调用到屏幕外表面,然后锁定屏幕外表面(而不是使用DCs和位图)。正如interjay指出的那样。。。你几乎是在用“正确”的方式做事
明显的改进是调用CreateRenderTarget和CreateOffscreenPlainSurface一次,然后多次重复使用。最快的方法是直接锁定曲面,将位取出
此外,如果您需要在视频之类的东西上实时执行此操作,则最好设置一组曲面(两种类型)。然后,可以将多个YUV帧加载到CreateRenderTarget的曲面上,然后填充阵列后,将第一个帧复制到OffscreenPlainSurface并将其锁定
通过这种方式,您将允许更多命令通过管道传输,并停止调用lock和强制管道同步(即,在继续进行导致管道同步的操作之前,您要锁定的表面必须准备就绪)。LockRect提供了哪种数据格式?没有找到任何描述。与GetDIBits()相同?@robin:每行像素都根据颜色格式压缩了字节。因此,对于D3DFMT_A8R8G8B8,每个像素有4个字节。每个像素的字节顺序相反(小端),因此在本例中,它们的顺序为:B、G、R、A。提供给您的
Pitch
值告诉您每行需要多少字节。您需要这样做,因为每行末尾可能有未使用的字节。