QGLWidget 和快速离屏渲染

2024-04-03

是否可以在屏幕外完全渲染QGLWidget使用 Qt 无需将场景重新绘制到屏幕,从而完全避免缓冲区在监视器上翻转?

我需要保存帧缓冲区上生成的每一帧,但是,由于序列由 4000 帧组成,并且屏幕上的时间间隔为15ms我花费4000*15ms=60s但我需要比 60 秒快得多(这里计算不是瓶颈,只是更新问题)。

在帧缓冲区上进行离屏渲染可以更快吗?我可以避免 QGLWidget 中的显示器刷新率吗?

如何在不降低速度的情况下完全在帧缓冲区上渲染paintGL() calls?


现在我假设我们正在谈论 Qt4。

是否可以在 QGLWidget 中完全离屏渲染

离屏渲染根本不是一个真正依赖于窗口系统的任务。大多数工具包中 WGL(至少)和 GLX 的唯一问题是您无法拥有无表面的背景,即未绑定到窗口系统提供的可绘制对象的上下文。换句话说,您将始终提供窗口系统默认帧缓冲区只要当前上下文存在,就不可变。

有一些方法可以创建不需要的上下文window手动使用 X11 但通常不值得这么麻烦。例如,对于 EGL 和 OpenGL ES,这个问题不存在,因为有一个扩展专门针对这个问题,即离屏渲染。

但是,您可以在设置有效上下文后简单地隐藏 QGLWidget,并使用帧缓冲区对象来完成所有操作,而无需默认帧缓冲区干预。

我可以避免 QGLWidget 中的显示器刷新率吗?

不,据我所知,Qt4 的 OpenGL 模块无法以编程方式关闭垂直同步。您可以向 SDL 或 GLFW 寻求类似的帮助(不确定 FreeGLUT)。

但是,您始终可以在驱动程序设置中关闭某些功能。这也会影响 QGLWidget (或者更好地说,底层窗口系统的交换行为。)

在帧缓冲区上进行离屏渲染可以更快吗?

最后真的应该不重要。您需要将图像数据存放在 VRAM 之外的其他位置,因此在将当前帧渲染到 FBO 后,无论如何您都需要获取图像。您要么将结果传输到前缓冲区(如果需要双缓冲和交换,则将结果传输到后缓冲区),或者需要在进一步处理当前帧之前读回内容。

然而,与任何 OpenGL 和性能相关的事情一样,不要猜测 - 简介!

如何在帧缓冲区上完全渲染而不需要缓慢的 PaintGL() 调用?

一旦设置了上下文,您就不需要该小部件at all。您可以自己完成所有的魔法,无需 Qt 的干预。唯一的原因paintGL()存在的目的是为用户提供一个易于使用的界面,保证在需要更新小部件时调用该界面。

EDIT:关于评论中的查询,请参阅这个最小的代码示例,它应该可以跨平台工作而无需更改。

#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;

  // do whatever you want here, e.g. setup a FBO, 
  // render stuff, read the results back until you're done
  // pseudocode:
  //     
  //      setupFBO();
  //   
  //      while(!done)
  //      {
  //        renderFrame();
  //        readBackPixels();
  //        processImage();
  //      }
}

int main(int argc, char* argv[])
{
  QApplication app(argc, argv);
  QGLWidget gl;

  // after construction, you should have a valid context
  // however, it is NOT made current unless show() or
  // similar functions are called
  if(!gl.isValid ())
  {
    std::cout << "ERROR: No GL context!" << std::endl;
    return -1;
  }

  // do some off-screen rendering, the widget has never been made visible
  gl.makeCurrent (); // ABSOLUTELY CRUCIAL!
  renderOffScreen ();

  return 0;
}

在我当前的机器上,程序打印:

ATI 科技公司

AMD Radeon HD 7900 系列

1.4(2.1(4.2.12337 兼容性配置文件上下文 13.101))

请注意如何QGLWidget实际上从未变得可见,并且不会发生任何事件处理。 Qt OpenGL 库仅用于上下文创建。其他任何事情都可以在没有 Qt 干预的情况下完成。只是不要忘记根据您的需要设置视口和其他内容。

请注意:如果您需要的只是一些方便的方法来设置上下文,您可能需要切换到一些比 Qt4 更轻量的工具包,例如 FreeGLUT。就我个人而言,我发现 FreeGLUT 在设置有效上下文方面要可靠得多,这与我在某些硬件上想要的方式完全一致,例如桑迪桥 CPU。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QGLWidget 和快速离屏渲染 的相关文章

随机推荐