Canvas3D is redrawn even when I don't want it to be
-
--> Video showing the problem is here <--
I'm drawing to an offscreen buffer (
Canvas3D.RenderTargetOffscreenBuffer
) with Canvas3D. I want to redraw the contents of the buffer only when necessary, for performance. But it seems that thepaintGL
signal is emitted as fast as possible, with no way for me to control that. I tried returning directly frompaintGL
when I don't want to redraw, but this causes a weird looping flicker - like the view is quickly alternating between the current and the last contents of the Canvas3D. I've seen the same thing before, in a non-Qt app, when I start callingSwapBuffers
fast in a loop without callingglClear
. But here something different must be happening, as there's noSwapBuffers
involved in the Canvas3D FBO.Reproducing the flicker
I'm not going to post the entire code here as it's very long with all the low-level OpenGL code. Instead, do the following to reproduce the flicker.
Open the "
textureandlight
" Qt example from the examples bundled with the SDK, and do the following changes:Change no. 1: insert the following in main.qml, directly in the toplevel
Item
object.property bool shouldPaint: true Item { focus: true Keys.onPressed: { if(event.key === Qt.Key_Space) { shouldPaint = !shouldPaint; } } }
Change no. 2: change the onPaintGL handler in main.qml to:
onPaintGL: { if(shouldPaint) { GLCode.paintGL(canvas3d); } }
Change no. 3: (optional) Change the
duration
of each of the 6NumberAnimation
objects inmain.qml
to 1000 so it animates faster and the flicker is more visible.Change no. 4: (may not be necessary but I do it) Insert the following line right before the declaration of
QGuiApplication app
inmain.cpp
:QGuiApplication::setAttribute(Qt::AA_UseOpenGLES);
This is to make it use the ANGLE layer (on my Windows 7) because my OpenGL drivers are incompatible with Qt Quick. ANGLE translates my calls to D3D calls.
Now run the app and when the cube starts rotating, press and release space to suppress repainting. It starts flickering as described above.
-
Hi! I think you need to inform the renderer that you take control over the update process otherwise it will switch between the contents of the front buffer and the back buffer (even when no new data is available. I haven't tried this myself but I guess the way to do that is to set
renderOnDemand
to true and callrequestRender()
when needed. -
@Wieland : This does work, and so far hasn't caused problems. Thanks a lot!
-
@Wieland : Also - I forgot to ask you: what back and front buffers are there with respect to the FBO used for the Canvas3D? I don't think this FBO needs double buffering at all. I think only the main window buffer needs double buffering.
-
@Stefan-Monov76 Good to hear that it works! :-) Regarding your question: I don't know, sry.