【问题标题】:Draw to HDC with user allocated memory使用用户分配的内存绘制到 HDC
【发布时间】:2011-05-02 16:11:36
【问题描述】:

我有一个无窗口的 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) 分配的内存?

如果可以从用户指定的内存创建与设备无关的位图,一种方法可能是?但是,我没有发现可以执行此操作的函数。

【问题讨论】:

    标签: c++ opengl winapi bitmap


    【解决方案1】:

    您正在尝试做的是非常合乎逻辑的恕我直言。然而不幸的是,AFAIK 没有传统的方法可以做到这一点。

    根据 WinAPI DIB 部分分配自己的内存或使用文件映射。 OTOH OpenGL 以自己的方式管理其内存。 存在从任何内存块创建 DIB 的选项,但它仅适用于视频驱动程序,用户模式应用程序无法访问。

    实际上有一个非常复杂的可能性来避免这种额外的副本。您可以创建一个虚拟视频驱动程序(不要与镜像视频驱动程序混淆),获取其HDC。然后以您的“自定义”方式告诉它应该在哪里绘制(通过Escape)。然后你可以将这个HDC 传递给你想要绘制的任何东西,你的虚拟视频驱动程序将直接在你想要的内存上绘制。

    此外,要进行实际绘图,您将能够使用操作系统功能。用 GDI 可识别的位图 (EngCreateBitmap) 包装您的内存,并使用操作系统 (EngXXXX) 在其上绘制,这样您只需在驱动程序中实现最少的功能。

    但无论如何,这都是一个驱动程序开发。我相信复制内存块足够快(与实际绘图相比),因此您可以保持代码不变。

    【讨论】:

    • 优秀的答案。而且我同意额外的副本不是瓶颈。但是,我仍然认为解决这个问题会很有趣。您对资源有什么建议可以让我开始编写这样的“驱动程序”吗?
    • 再问一个问题。这些驱动dll是不是必须放到system32目录下,还是可以放到application目录下?
    • 好吧,老实说,我不知道有什么建议。一旦我编写了一个(某种)视频驱动程序,我就从 MSDN 收集了“按件”的信息。最好从阅读随 WDK(前 DDK)提供的“镜像”视频驱动程序源代码开始。也可以尝试在网上搜索DrvEnableDriverDrvEnableSurface 等。
    • 关于视频驱动DLL。是的,它应该位于 system32 目录中。至少是“逻辑”驱动程序部分,即 DLL 文件。 (还有相应的 SYS 文件,即所谓的微型端口驱动程序)。然而,有一些“间接”技术可以解决这个问题,但这是另一个驱动程序开发和挂钩到操作系统内部
    • 我可能遗漏了一些东西,但是 OpenGL 将如何绘制到该虚拟驱动程序的 HDC 上?
    猜你喜欢
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 2010-09-25
    • 1970-01-01
    • 2020-02-17
    • 2015-01-11
    • 2011-11-29
    相关资源
    最近更新 更多