Direct3D:从IDirect3DSurface9(默认池)获取系统内存位图的有效方法?

And*_*hko 5 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_surf, NULL, render_target_, NULL, D3DTEXF_NONE)
    完整的矩形,无拉伸)
    在系统内存中创建普通的屏幕外表面
    device->CreateOffscreenPlainSurface(surf_desc.Width, surf_desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &sysmem_offscreen_surf, NULL)
    将数据从视频mem复制到sysmem:
    device->GetRenderTargetData(render_target, sysmem_offscreen_surface)
    来自屏幕外表面的GetDC,创建兼容的DC和兼容位图,BitBlt从屏幕外的sufrace DC到兼容的DC,并通过GetDIBits()将位图位复制到我的缓冲区

这看起来有点开销,因为有很多复制:从原始表面到渲染目标,然后到屏幕外表面,再到兼容位图,最后到我的缓冲区.如何改进?

谢谢

int*_*jay 3

由于您以可锁定模式创建渲染目标(第 6 个参数CreateRenderTarget),因此您可以使用锁定渲染目标LockRect并直接从那里复制数据。

MSDN 不建议使用可锁定渲染目标,并表示

如果您需要对渲染目标进行读取访问,请使用 GetRenderTargetData 而不是可锁定渲染目标。

因此,另一种方法是调用GetRenderTargetData屏幕外表面,然后锁定屏幕外表面(而不是使用 DC 和位图)。