隐藏 GLUT 窗口

Posted

技术标签:

【中文标题】隐藏 GLUT 窗口【英文标题】:Hide GLUT window 【发布时间】:2013-05-06 17:19:27 【问题描述】:

是否可以隐藏 OpenGL 窗口并且渲染仍在运行?我使用 glutHideWindow,它永远不会触发显示功能。

如果不能,是否可以在程序中改变当前窗口的焦点?我想运行 opengl 程序,但我不需要那个窗口。事实上,我想在另一个程序中使用 opengl 在每一帧更新的帧缓冲区。但是在两个程序之间切换总是很烦人。 (他们都有窗口)

【问题讨论】:

@BЈовић:与显示回调无关。并且没有任何 OP 要求以天真的方式是不可能的。 @datenwolf 好的,它确实取决于窗口系统。我的经验是,如果你发出窗口渲染,它可能会被重新渲染——不管窗口是否被覆盖。 @BЈовић:我们说的是不可见的,即这里的隐藏窗口,而不是重新映射到可见屏幕的窗口。如果渲染到隐藏/不可见窗口,图形将丢弃所有绘图命令,因为它们无论如何都不会到达屏幕。 @BЈовић:OP 的问题与 GLUT 或使用的任何框架无关。您的标签添加不会添加任何有用的信息,因为如果使用原生 Win32 GDI、X11/GLX 或 Qt 或 GTK+,问题将是相同的。 【参考方案1】:

是否可以隐藏OpenGL窗口并且渲染仍在运行?

对问题的两个部分都回答“是”和“否”。

如果您隐藏一个窗口,则该窗口视口的所有像素在渲染时将无法通过像素所有权测试。所以你不能使用隐藏窗口作为 OpenGL 操作的可绘制对象。

您需要的是一个可绘制到的屏幕外可绘制对象。

现代变体是 Framebuffer Objects (FBO),您可以在常规 OpenGL 上下文中创建它,甚至可以在隐藏窗口上工作。 FBO 采用一些可绘制的附件(渲染缓冲区、纹理)并允许 OpenGL 绘制这些附件而不是窗口。

PBuffers 是一种较旧的方法,也得到广泛支持,但不如 FBO 易于使用。

请注意,如果您想在 Linux/X11 上执行离屏渲染,X 服务器必须处于活动状态,即拥有 VT,以便 GPU 实际处理命令。因此,您不能只“在后台”启动 X 服务器,而是让另一个 X 服务器使用显示设备。

【讨论】:

@BЈовић: 两位来自你的坏建议的 cmets。请停止提出适得其反的建议。 OP 需要一个 FBO 或一个 PBuffer。根本不需要共享内存(共享内存是一种进程间技术,但这不是 OP 所需要的)。 像素所有权测试失败是最好的情况。我还可以想象使上下文变为当前失败,并且当窗口恢复可见性时,可能必须将所有 OpenGL 资源重新加载到新上下文中。 @BenVoigt:这种情况是不允许发生的。 GLX 和 Win32 GDI 都允许将上下文绑定到不可见(隐藏/未映射/非活动)可绘制对象。可绘制对象上的绘图操作是未定义的,但所有不在可绘制对象上发生的 OpenGL 操作都将起作用。对于 PBuffers,GLX 指定了“损坏”条件,这与常规窗口的损坏状态非常相似,即由于内容未定义,需要完全重绘。此外,由于单个 OpenGL 上下文未绑定到单个可绘制对象,因此破坏可绘制对象不会损害上下文本身。 我在使用FBO并将渲染设置为显示函数,但是如果窗口被隐藏则永远不会调用显示函数! @YanLi:当然,如果 GLUT 认为它无论如何都不会产生可见的东西,则 GLUT 不会调用 display 函数。您必须改用空闲功能。【参考方案2】:

创建窗口后,您可以使用glutHideWindow() 离开屏幕。然后你仍然渲染为正常并使用glReadPixels 读取并获取缓冲区以供以后使用。

【讨论】:

谢谢@Ast Derek。我的英语不好:) 下次我会更小心的

以上是关于隐藏 GLUT 窗口的主要内容,如果未能解决你的问题,请参考以下文章

窗口重叠后GLUT窗口不刷新

C++\GLUT 窗口菜单栏

如何通过openGL或Glut检查窗口是不是打开

GLUT Tutorials 17:子窗口

在 Linux 中使用 glut 调整窗口大小时显示错误

GLUT Tutorials 17:子窗口的reshape