C++ 在窗口之间切换后,OpenGL图形上下文无效

C++ 在窗口之间切换后,OpenGL图形上下文无效,c++,opengl,C++,Opengl,我在OpenGL应用程序“A”(用C++编写)中遇到以下问题: 切换到不同的窗口“B”(同一应用程序的子窗口或完全不同的应用程序)然后切换回“a”后,所有OpenGL渲染都被限制在“B”所覆盖的“a”区域内 最小化和重新最大化窗口“A”后,问题消失 此问题仅在单个windows 7计算机上发生。在许多其他机器(windows和Linux)上进行测试时,一切正常。将图形驱动程序更新到最新版本也没有帮助 是否有明显的编码错误会导致这种行为 调试此类错误的好方法是什么?有许多方面可能会影响Wind

我在OpenGL应用程序“A”(用C++编写)中遇到以下问题: 切换到不同的窗口“B”(同一应用程序的子窗口或完全不同的应用程序)然后切换回“a”后,所有OpenGL渲染都被限制在“B”所覆盖的“a”区域内

  • 最小化和重新最大化窗口“A”后,问题消失
  • 此问题仅在单个windows 7计算机上发生。在许多其他机器(windows和Linux)上进行测试时,一切正常。将图形驱动程序更新到最新版本也没有帮助
是否有明显的编码错误会导致这种行为


调试此类错误的好方法是什么?

有许多方面可能会影响Windows上的重新绘制行为。考虑到问题中的几个细节,我建议先检查基本情况:

  • 首先,在Windows上,您需要使用以下标志创建OpenGL上下文窗口:
    WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN

  • 为了响应
    WM\u ACTIVATE
    ,您应该调用
    wglMakeCurrent()

  • 为了响应
    WM\u SIZE
    ,您应该调用
    glViewport()

这种行为当然会因硬件、Windows版本和驱动程序版本而异。所有的组合都有自己的怪癖

最小化和重新最大化窗口“A”后,问题消失

这将强制重新绘制和调整大小,因此不会缩小问题的范围。对于调试,您可以使用
WM_CHAR
获取键盘事件,并使用热键强制重新绘制(无需所有其他消息流)。这会告诉你这是否是激活问题

…所有OpenGL渲染仅限于“B”所覆盖的“A”区域

如果渲染缩小到重叠区域,则视口可能会变得混乱,例如在重新绘制期间将视口设置为脏矩形

如果缩放正确,但您只看到正在重新绘制的窗口的一角,则您看到的行为是遮挡窗口将窗口的备份缓冲区保存在后面,当恢复时,该缓冲区仅重新绘制保存的位。这显然不足以满足重新绘制逻辑,剪辑标志会影响此行为

另一种可能性是,在处理重绘事件之前,活动GL上下文(每个线程只有一个)没有切换到新激活的窗口。上面的激活处理可以解决这个问题


至于调试策略,我会在事件处理程序中放入一些
printf
s(或者使用MessageSpy),这样您就可以看到事件的顺序。事实上,它只是硬件和软件的特定组合,这意味着您可能依赖于不同版本之间略有不同的默认行为。您可以提供的任何更多详细信息都将有助于进一步缩小范围。

大多数情况下,这不应该是由记录引起的错误。根据您的测试,此问题只发生在一台机器上。机器的配置是什么?当应用程序A被激活时,重置
glViewport
可能会起作用我的赌注是错误的/坏的/错误的驱动程序。。。这是英特尔还是ATI?Intel在每个应用程序中都有多个Opengl上下文,并且ATI(AMD)卡驱动程序对应用程序中的内存泄漏非常敏感。对于Intel,您运气不好(可以切换到GDI),对于ATI,调试或更改某些gl调用的顺序有时会有帮助,最重要的是更新驱动程序**添加有关您的应用程序做什么/使用什么操作系统的更多信息gl/GLSL什么版本、兼容性/核心配置文件等**与类似,但我没有得到答案或评论:(还要确保您的窗口在诸如OnActivate、OnResize等事件中更改当前GL上下文,并在关闭前将其设置为NULL……好吧,我可以想象应用程序错误会导致此类行为的奇怪场景,例如,某些情况下,由于前面的另一个窗口,某些区域的像素所有权测试失败对于它,结合一些特定的每像素测试,如模板测试或深度测试的奇怪用法。但是,尽管这个问题提出得很模糊,但几乎不可能给出有用的建议。然而,有一件事:检查windows是否“Aero”桌面合成器在这台机器上是关闭的,甚至可能切换它,检查它是否有任何区别。