如何让 OpenGL 和 GDI 同时正常工作?

Posted

技术标签:

【中文标题】如何让 OpenGL 和 GDI 同时正常工作?【英文标题】:How can I make OpenGL and GDI both working properly at the same time? 【发布时间】:2016-11-28 09:14:48 【问题描述】:

我有四个窗口,一个父窗口和三个子窗口。我想制作两个子窗口来绘制东西。第一个子窗口使用 OpenGL,第二个子窗口使用 GDI。如果我只是在我的 OpenGL 窗口上绘制一些东西并且一切正常,但是当我尝试在我的 GDI 窗口上绘制(或只是尝试处理 WM_PAINT 消息)其他东西时,这些子窗口会变得很奇怪。首先,我的第三个子窗口的某些部分(如按钮、静态、标题栏)将丢失。其次,如果我尝试调整任何这些窗口的大小,则会丢失一两个子窗口。但是一旦我点击这些窗口,它们就会回来。第三,PeekMessage 不再起作用,它总是返回一个 FALSE,MessageBox 似乎不能正常工作(我看不到弹出窗口,但我能听到声音)。

我刚刚创建的第三个子窗口。

点击后。

我认为消息处理可能有问题,但我无法弄清楚实际发生了什么。有人有什么建议吗?

消息循环:

MSG msg;


DWORD dwLast;
DWORD dwCurrent;
DWORD dwInterval = 20;//50 FPS 1000 / 50
dwLast = GetTickCount();

while (1) 

    while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == FALSE)
    
        dwCurrent = GetTickCount();
        if (dwCurrent - dwLast < dwInterval)
            continue;

        SendMessage(Handle_Child_Demo, WM_PAINT, 0, 0);

        dwLast = dwCurrent;
    
    if (GetMessage(&msg, NULL, 0, 0) != TRUE) 
        break;
    
    TranslateMessage(&msg);
    DispatchMessage(&msg);

我没有使用 MDI 来创建我的子窗口,我只是使用 CreateWindow 来创建我的所有子窗口,我认为这一定是有问题,我还需要做些什么来确保这些子窗口正常工作正常吗?

【问题讨论】:

不同的窗口是不同的线程......所以你必须为每个 GL 窗口有单独的 OpenGL 上下文并使用wglMakeCurrent 在上下文之间正确切换(在激活和退出事件上)。此外,必须从目标窗口的主线程(WndProc)调用 GDI 和可视化 WinAPI 调用,否则即使在不相关的代码中也会发生奇怪的事情......就像随机异常 gfx 错误崩溃......顺便说一句,你可以在同一个窗口中组合 GDI 和 GL没有任何问题...只要确保更新不会在错误的时间强制重新绘制。 真正的问题是在您使用较旧的英特尔 gfx 卡/驱动程序时开始的,请参阅What is the proper OpenGL initialisation on Intel HD 3000? 我只有一个GL窗口,整个程序只使用一个线程。我开始绘制时使用 wglMakeCurrent(DC,GL),停止绘制时使用 wglMakeCurrent(NULL,NULL)。 @Spektre BTW 我没有使用英特尔 gfx 卡。 您有 4 个窗口,每个窗口调用其自己的 WndProc 回调,您可以将其视为单独的线程。如果您在窗口之间访问 GDI 或 winapi 调用,那么您就会遇到问题。 【参考方案1】:

必须使用 MDI 创建子窗口,请记住,使用 MDI!!!!或者会有一些非常奇怪的事情,这是因为那些消息没有被正确处理,而 MDI 会帮助我们做到这一点。

【讨论】:

以上是关于如何让 OpenGL 和 GDI 同时正常工作?的主要内容,如果未能解决你的问题,请参考以下文章

从 OpenGL 切换到 GDI

是否可以在已经使用 GDI+ 的窗口中使用 OpenGL?

使用 OpenGL 和 Gdi+ 的 GetDC、ReleaseDC、CS_OWNDC

无法让 Stencil Buffer 在 iOS 4+ 中工作(5.0 工作正常)。 [OpenGL ES 2.0]

OpenGL学习笔记之坐标变换学习

如何在遵守严格的 script-src 内容安全策略的同时让 KendoUI 正常工作