QGLWidget和快速离屏渲染 [英] QGLWidget and fast offscreen rendering

查看:1914
本文介绍了QGLWidget和快速离屏渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以使用Qt在 QGLWidget 中完全隐藏屏幕,而不需要重新绘制场景到屏幕上,从而避免显示器上的缓冲区翻转?

Is it possible to render totally offscreen in a QGLWidget with Qt without the need to repaint the scene to screen thus avoiding totally the buffers flip on monitor?

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

I need to save every frame generated on the framebuffer but, since the sequence is made of 4000 frames and the time interval on the screen is 15ms I spend 4000*15ms=60s but I need to be much much faster than 60s (computations are not a bottleneck here, is just the update the problem).

可以在帧缓冲上渲染屏幕更快吗?

Can rendering offscreen on a framebuffer be faster? Can I avoid the monitor refresh rate in my QGLWidget?

如何在framebuffer上完全渲染没有缓慢 paintGL() call?

How do I render completely on framebuffer without the slow paintGL() calls?

推荐答案

现在我假设我们在说Qt4。

For now I'll assume we're talking Qt4.


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

Is it possible to render totally offscreen in a QGLWidget

不是真的是一个依赖于窗口系统的任务。在大多数工具包中,至少有WGL(至少)和GLX的唯一问题是,你不能有一个无表面的上下文,即没有绑定到窗口系统提供的drawable的上下文。换句话说,只要当前上下文存在,你总是有window-system提供的不可变的 default framebuffer

Off-screen rendering isn't really a window-system-dependent task at all. The only problem with WGL (at least) and GLX in most toolkits is that you cannot have a surfaceless context, i.e. a context that's not bound to a drawable provided by the window-system. In other words, you'll always have window-system provided default framebuffer that immutable as long as the current context exists.

有些方法可以使用X11手动创建不需要窗口的上下文,但它通常不值得麻烦。例如,对于EGL和OpenGL ES,这个问题不存在,因为有一个扩展倾向正是这个问题,即离屏呈现。

There are means to create a context that doesn't require a window manually with X11 but it's usually not worth the trouble. For EGL and OpenGL ES, for instance, this problem doesn't exist because there is an extension tending exactly to this problem, i.e. off-screen rendering.

但是,在有效的上下文设置完成后,只需隐藏QGLWidget,并使用framebuffer对象做所有没有默认framebuffer干预。

You can, however, simply hide the QGLWidget after a valid context has been set up and use framebuffer objects to do everything without default framebuffer intervention.


避免监视器刷新率在我的QGLWidget?

Can I avoid the monitor refresh rate in my QGLWidget?

不,据我所知,Qt4的OpenGL模块没有办法打开vsync程序化。你可以转到SDL或GLFW的类似的东西(不确定FreeGLUT)。

No, to my knowledge, the OpenGL module of Qt4 has no means to turn of vsync programmatically. You can turn to SDL or GLFW for something like that (not sure about FreeGLUT).

但是,你总是可以在驱动程序设置关闭东西。这也会影响QGLWidget(或更好的,底层窗口系统的交换行为。)

However, you can always turn stuff off in your driver settings. This will also affect QGLWidget (or better put, the swapping behavior of the underlying window-system.)


可以在framebuffer上渲染屏幕更快?

Can rendering offscreen on a framebuffer be faster?

这真的不重要。你想要的图像数据的一些地方,而不是VRAM,所以在将当前帧渲染到FBO后,你需要得到图像。如果你需要双缓冲和交换,你可以将结果转换为前缓冲区(或者后缓冲区),或者在进一步处理当前帧之前需要回读一些东西。

It really shouldn't matter in the end. You're gonna want the image data some place else than VRAM, so after having rendered the current frame to a FBO, you need to get the image anyway. You either blit the results to the front buffer (or back buffer if you need double buffering and swap), or you need to read-back stuff prior to further processing your current frame.

但是,与任何OpenGL和性能相关,不要猜测 - 个人资料

However, as with anything OpenGL and performance related, don't guess - profile!


我是否完全在framebuffer上渲染,而没有缓慢的paintGL()调用?

How do I render completely on framebuffer without the slow paintGL() calls?

一旦设置了上下文,窗口小部件 。你可以做所有的魔法自己没有Qt的干预。存在的 paintGL()的唯一原因是为用户提供一个易于使用的界面,当该窗口小部件需要更新时保证被调用。

Once a context is set up, you don't need the widget at all. You can do all the magic yourself without Qt's intervention. The only reason paintGL() exists is to provide the user with an easy to use interface that's guaranteed to be called when the widget needs to be updated.

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

EDIT: As to your query in the comments, see this minimal code example which should work cross-platform without change.

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

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

On my current machine the programs prints:


ATI科技公司。

ATI Technologies Inc.

AMD Radeon HD 7900系列

AMD Radeon HD 7900 Series

1.4(2.1(4.2.12337 Compatibility Profile Context 13.101))

1.4 (2.1 (4.2.12337 Compatibility Profile Context 13.101))

请注意 QGLWidget 永远不会显示,并且不会发生事件处理。 Qt OpenGL库只用于上下文创建。任何其他都没有Qt干预。

Please note how the QGLWidget is never actually made visible and no event processing takes place. The Qt OpenGL library is merely used for the context creation. Anything else is done without Qt intervention. Just don't forget to set the viewport and stuff according to your needs.

请注意:如果您需要的只是一些方便的方法,设置一个上下文,你可能想切换到比Qt4更轻量级的工具包,如FreeGLUT。个人而言,我发现FreeGLUT是更可靠的,当涉及到设置一个有效的上下文完全一样的方式,我想在一些硬件,例如。 Sandy Bridge CPU。

Please note: If all you need is some convenient way to setup a context, you might want to switch to some toolkit which is more lightweight than Qt4, like FreeGLUT. Personally I found FreeGLUT to be much more reliable when it comes to setting up a valid context exactly the way I want it on some hardware, e.g. Sandy Bridge CPUs.

这篇关于QGLWidget和快速离屏渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆