使用用户分配的内存绘制到 HDC
我有一个无窗口的 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) 分配的内存?
一种方法可能是是否可以从用户指定的内存创建设备无关的位图?但是,我发现没有函数可以执行此操作。
I have an windowless IViewObject object.
I want to call its Draw function to render into Opengl PBO memory (alternatively OleDraw is simpler).
Right now i first create an HBITMAP using CreateDIBSection (which allocates its own memory) and then copy from this into my PBO memory. However, I'd like to avoid this extra copy. I believe this should be possible in theory as mapped PBOs live in page-locked memory.
This is what I do today simplified:
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);
My question is if its possible to have the Draw function to somehow draw to memory which i have specified (in this case the PBO) instead of memory allocated by the win32 api (CreateDIBSection)?
One way might be if it is possible to create a device independent bitmap from user specified memory? However, I have found no function that does this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
恕我直言,你想做的事情是非常合乎逻辑的。然而不幸的是,据我所知,没有传统的方法可以做到这一点。
根据 WinAPI DIB 部分,要么分配自己的内存,要么使用文件映射。 OTOH OpenGL 以自己的方式管理内存。
存在从任何内存块创建 DIB 的选项,但它仅适用于视频驱动程序,用户模式应用程序无法访问。
实际上,避免这种额外副本的可能性非常复杂。您可以创建一个虚拟视频驱动程序(不要与镜像视频驱动程序混淆),获取其
HDC
。然后以您的“自定义”方式告诉它应该在哪里绘制(通过Escape
)。然后你可以将这个 HDC 传递给你想要进行绘图的任何地方,你的虚拟视频驱动程序将直接在你想要的内存上绘图。此外,要进行实际绘图,您将能够使用操作系统功能。用 GDI 可识别的位图 (
EngCreateBitmap
) 包装您的内存,并使用操作系统 (EngXXXX
) 在其上绘图,这样您只需在您的程序中实现最少的功能。司机。然而,无论如何,这都是一个驱动程序开发。我相信复制内存块足够快(与实际绘图相比),因此您可以按原样保留代码。
What you're trying to do is very logical IMHO. However unfortunately AFAIK there's no conventional way to do this.
According to WinAPI DIB sections either allocate their own memory or work with the file mapping. OTOH OpenGL manages its memory in its own way.
There exists an option to create a DIB from any memory block, but it's for video drivers only, not accessible to the user-mode applications.
There's actually a very complex possibility to avoid this extra-copy. You may create a virtual video driver (not to be confused with mirror video driver), obtain its
HDC
. Then in you 'custom' way tell it where it should draw (viaEscape
). And then you may pass thisHDC
to whatever you want to do the drawing, your virtual video driver will draw directly on the memory you want.Moreover, to do the actual drawing you will be able to use the OS functions. Wrap your memory by GDI-recognizable bitmap (
EngCreateBitmap
), and draw on it using OS (EngXXXX
), so that you'll have to implement only the minimum functionality in your driver.However this is a driver development anyway. I believe that copying a memory block is fast enough (comparison to the actual drawing), so that you can leave your code as-is.