Qt/OpenGL:绘制成非曝光windows

Qt/OpenGL: drawing into non-exposed windows

我正在使用 gitlab-ci-runner 在每次提交时自动测试桌面 Qt/OpenGL 应用程序。在Windows8上,应用程序是由安装了gitlab-ci-运行ner的系统服务执行的,因此是运行"hidden",即在no可见的桌面。所有 UI 模块都会初始化并且 运行 无论如何,除了 OpenGL 模块,它永远不会获得 "expose" 事件;如果我尝试在不暴露 window 的情况下绘制到 OpenGL 上下文中,我会收到错误消息:

QOpenGLContext::swapBuffers() called with non-exposed window, behavior is undefined

我发现在 运行ning 桌面会话上从服务执行 Windows GUI 应用程序相当困难,不建议执行(请参阅 How can a Windows service execute a GUI application?).

现在,我不需要用户查看 应用程序,我只需要 OpenGL 部分即可正常工作。有什么方法可以 "pretend" 以某种方式公开 window,或者有任何其他方法可以从系统服务将其正确地 运行 吗?

Is there a way I can "pretend" to expose a window somehow, or is there any other way to get this to run correctly from a system service?

您 运行 遇到的两个问题:

  1. 如果 window 未公开,所有渲染到的像素将无法通过像素所有权测试,并且渲染将变成所有像素的 NoOp。解决方法是使用一个 PBuffer 或(推荐)一个帧缓冲区对象。两者都不会立即在屏幕上工作 window,因此您必须更改一些代码。

  2. 在 Windows 中,作为服务启动的进程通常无法访问图形硬件,因此您只能使用 GDI OpenGL 回退软件的功能(仅限于 OpenGL -1.1,因此不支持 FBO 或 PBuffers)。

如果您需要 GPU 加速,您可以投资一些网格计算 GPU 硬件(好吧,实际上每个 GPU 都可以做到,但驱动程序不允许它用于消费级的东西)以获得工作的 OpenGL 加速上下文。或者您可以迁移到 Linux,使用 KMS/DRI/DRM 支持的 GPU 并完全绕过任何图形系统。没有关于如何做到这一点的官方指南,但它在我的(冗长的)待办事项列表中写了这样一个教程。

如果你可以在没有 GPU 加速的情况下生活,请在你的程序 .exe 旁边放置一个 Windows 带有软管道渲染器的 Mesa 版本; Windows Mesa softpipe 构建作为 opengl32.dll 完全 API 和 ABI 与标准 opengl32.dll 兼容,但独立于任何图形驱动程序。它为您提供 OpenGL-3.3 支持,包括 FBO 和 PBuffers。