【问题标题】:Invalid OpenGL drawing context after switching between windows在窗口之间切换后无效的 OpenGL 绘图上下文
【发布时间】:2015-05-04 13:31:49
【问题描述】:

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

  • 在最小化和重新最大化窗口“A”后问题就消失了
  • 该问题仅出现在单台 Windows 7 机器上。在许多其他机器(Windows 和 Linux)上进行测试时,一切正常。将图形驱动程序更新到最新版本也没有帮助。

是否有明显的编码错误会导致这种行为?

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

【问题讨论】:

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

标签: c++ opengl


【解决方案1】:

有许多方面可能会影响 Windows 上的重绘行为。鉴于问题中的一些细节,我建议先检查基础知识:

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

  • 回复WM_ACTIVATE,您应该致电wglMakeCurrent()

  • 回复WM_SIZE,您应该致电glViewport()

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

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

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

...所有 OpenGL 渲染都被限制在 'B' 覆盖的 'A' 区域内。

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 2012-06-02
    • 2020-12-02
    • 2016-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多