我有一个无窗口的IViewObject对象。
我想调用它的Draw函数渲染到Opengl PBO内存中(或者OleDraw更简单)。
现在我首先使用CreateDIBSection(它分配自己的内存)创建一个HBITMAP,然后从中复制到我的PBO内存中。但是,我想避免这个额外的副本。我认为理论上这应该是可能的,因为映射的PBO存在于页面锁定的内存中。
这就是我今天所做的简化:
hdc = CreateCompatibleDC(nullptr); // Get current DC
HBITMAP bitmap = CreateDIBSection(... hdc, &bitmap_data_...); // Create Bitmap
SelectObject(hdc, bitmap);
m_spViewObject->Draw(... hdc ...); // IViewObject->Draw to bitmap
memcpy(pbo_ptr, bitmap_data_, size);
我的问题是,是否有可能让Draw函数以某种方式绘制到我指定的内存(在本例中为PBO)而不是由win32 api(CreateDIBSection)分配的内存?
如果可以从用户指定的内存创建与设备无关的位图,可能有一种方法吗?但是,我发现没有这样做的功能。
答案 0 :(得分:4)
你要做的是非常合乎逻辑的恕我直言。然而不幸的是,AFAIK没有传统的方法来做到这一点。
根据WinAPI DIB部分,要么分配自己的内存,要么使用文件映射。 OTOH OpenGL以自己的方式管理其内存。 存在从任何内存块创建DIB的选项,但它仅适用于视频驱动程序,用户模式应用程序无法访问。
实际上有一种非常复杂的可能性来避免这种额外复制。您可以创建虚拟视频驱动程序(不要与镜像视频驱动程序混淆),获取其HDC
。然后以“自定义”方式告诉它应该绘制的位置(通过Escape
)。然后您可以将此HDC
传递给您想要绘制的任何内容,您的虚拟视频驱动程序将直接绘制到您想要的内存中。
此外,要进行实际绘图,您将能够使用OS功能。通过GDI可识别的位图(EngCreateBitmap
)包裹您的记忆,并使用操作系统(EngXXXX
)绘制它,这样您就必须只实现驱动程序中的最小功能。
然而,无论如何这都是一个驱动程序开发。我相信复制一个内存块足够快(与实际绘图相比),这样你就可以保持代码原样了。