Important: Please read the Qt Code of Conduct -

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 the paintGL signal is emitted as fast as possible, with no way for me to control that. I tried returning directly from paintGL 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 calling SwapBuffers fast in a loop without calling glClear. But here something different must be happening, as there's no SwapBuffers 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) {

    Change no. 3: (optional) Change the duration of each of the 6 NumberAnimation objects in main.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 in main.cpp:


    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 call requestRender() 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.

Log in to reply