目前我假设我们在谈论Qt4。
完全离屏渲染在QGLWidget中是否可能?
离屏渲染实际上并不是依赖于窗口系统的任务。至少在WGL和大多数工具包中的GLX中唯一的问题是,您无法拥有一个无表面的上下文,即一个没有绑定到窗口系统提供的可绘制项的上下文。换句话说,只要当前上下文存在,您将始终拥有由窗口系统提供的默认帧缓冲区,该帧缓冲区是不可变的。
有一些方法可以创建不需要手动创建窗口的上下文,但通常不值得麻烦。例如,对于EGL和OpenGL ES,这个问题不存在,因为有一个扩展专门解决这个问题,即离屏渲染。
但是,您可以在设置了有效上下文后简单地隐藏QGLWidget,并使用帧缓冲对象完成所有操作,而不涉及默认帧缓冲区的干预。
我的QGLWidget中是否可以避免监视器刷新率?
据我所知,Qt4的OpenGL模块没有手动关闭垂直同步的方法。您可以转向SDL或GLFW等工具包来实现这样的功能(不确定FreeGLUT)。
但是,您始终可以在驱动程序设置中关闭一些东西。这也会影响QGLWidget(或更好地说,底层窗口系统的交换行为)。
在帧缓冲区上进行离屏渲染是否会更快?
最终它真的不应该有所不同。您将想要将图像数据放在VRAM之外的某个地方,因此,在将当前帧渲染到FBO后,您需要获取图像。您可以将结果复制到前缓冲区(如果需要双缓冲区并交换到后缓冲区),或者在进一步处理当前帧之前需要先读取内容。
但是,就OpenGL和性能相关的任何事情而言,请勿猜测-请进行性能分析!
如何完全在帧缓冲区上进行渲染而无需慢速的paintGL()调用?
一旦设置了上下文,您根本不需要小部件。您可以在没有Qt干预的情况下自己完成所有操作。 paintGL()存在的唯一原因是提供易于使用的界面,保证在需要更新小部件时调用用户。
编辑:至于您在评论中的查询,请参见此最小代码示例,它应该跨平台工作,无需更改。
#include <iostream>
#include <QtOpenGL/QGLWidget>
#include <QtGui/QApplication>
void renderOffScreen ()
{
std::cout << glGetString(GL_VENDOR) << std::endl;
std::cout << glGetString(GL_RENDERER) << std::endl;
std::cout << glGetString(GL_VERSION) << std::endl;
}
int main(int argc, char* argv[])
{
QApplication app(argc, argv);
QGLWidget gl;
if(!gl.isValid ())
{
std::cout << "ERROR: No GL context!" << std::endl;
return -1;
}
gl.makeCurrent ();
renderOffScreen ();
return 0;
}
在我的当前机器上,程序打印出:
ATI Technologies Inc.
AMD Radeon HD 7900系列
1.4(2.1(4.2.12337兼容性配置文件上下文13.101))
请注意,QGLWidget从未实际可见,也没有进行任何事件处理。Qt OpenGL库仅用于上下文创建。其他所有操作都不需要Qt的干预。只要根据您的需求设置视口和相关内容即可。
请注意:如果您只需要方便地设置上下文,您可能需要切换到比Qt4更轻量级的工具包,如FreeGLUT。就我个人而言,我发现在某些硬件上,例如Sandy Bridge CPU上,FreeGLUT在按照我想要的方式设置有效上下文方面要可靠得多。
swapBuffers()
不会帮助OP解决问题,因为交换间隔取决于VSync。此外,根据您要渲染的内容,实际上并不需要双缓冲。OP需要澄清他们正在渲染什么。 - thokraQGL::IndirectRendering
的QGL格式,它是用来做什么的? - linello