2

I want to implement a function that saves the content displayed by the OpenGLWidget to an image file.

I'm using the following code to save the image:

ui->gl_widget->grabFramebuffer().save("/foo/bar.png");

This works fine as long as I don't use multisampling, but if I add this line to my initialization, I only get weird looking results:

QSurfaceFormat format;
...
format.setSamples(4);
...

enter image description here

additionally, rendering a static scene multiple times results in different images.

I'm using Qt5.6.0 and OpenGL 3.3 (Core Profile).

Can you help me to find the problem here? I searched quite some time now and I don't have a clue what's causing this issue.

Thanks in advance!

Felix
  • 6,131
  • 4
  • 24
  • 44

1 Answers1

1

Grabbing the framebuffer of a widget is not really reliable. Even without multisampling, on some OSes it can occur that you will not get the current, but previous frame, etc. What you are seeing is basically uninitialized memory.

My workaround to this was to draw into a framebuffer object instead:

QGLFramebufferObject b(width, height);
QPainter p(&b);
bool success = drawScene(&p);

if (!success)
    return;

QImage img = b.toImage();

You might have to refactor your code a bit, but it comes with other advantages (e.g. choosing a custom resolution, different quality settings on the painter, etc.).

You can find my old question with exactly this issue here: How to take reliable QGLWidget snapshot

Community
  • 1
  • 1
ypnos
  • 50,202
  • 14
  • 95
  • 141
  • 1
    The other question was for `QGLWidget`: there, the framebuffer grab was indeed unreliable. This is for `QOpenGLWidget`. It *already draws into a framebuffer object!* The `defaultFramebufferObject()` gives you its handle in the `context()` while the painting is active (and only then IIRC). – Kuba hasn't forgotten Monica Aug 02 '16 at 21:44
  • Thanks, good to know. Maybe you also have an answer to this? http://stackoverflow.com/questions/32030389/draw-content-of-qopenglframebufferobject-onto-qopenglwidget It is holding me back from migrating to `QOpenGLWidget`. – ypnos Aug 02 '16 at 21:52
  • You really want someone to show you how to draw a textured quad?? If so, then that question is a duplicate, pretty much. – Kuba hasn't forgotten Monica Aug 02 '16 at 22:14
  • No worries, I know how to draw a textured quad. My question is "Is there any **elegant/Qt way** of getting my fbo contents onto the screen?" If you believe that going back to OpenGL for this, while for everything else I use Qt methods, is an elegant/QT way, fine. If you don't maybe my question is not so redundant after all. I just kindly asked you if you know an answer to that question, that's all. – ypnos Aug 02 '16 at 23:16