Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Canvas3D is redrawn even when I don't want it to be
QtWS25 Last Chance

Canvas3D is redrawn even when I don't want it to be

Scheduled Pinned Locked Moved Solved QML and Qt Quick
openglframebuffer
5 Posts 2 Posters 1.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Stefan Monov76
    wrote on 4 Oct 2016, 14:14 last edited by
    #1

    --> 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) {
            GLCode.paintGL(canvas3d);
        }
    }
    

    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:

    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.

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on 4 Oct 2016, 20:33 last edited by
      #2

      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.

      S 2 Replies Last reply 13 Oct 2016, 16:27
      1
      • ? A Former User
        4 Oct 2016, 20:33

        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.

        S Offline
        S Offline
        Stefan Monov76
        wrote on 13 Oct 2016, 16:27 last edited by
        #3

        @Wieland : This does work, and so far hasn't caused problems. Thanks a lot!

        1 Reply Last reply
        0
        • ? A Former User
          4 Oct 2016, 20:33

          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.

          S Offline
          S Offline
          Stefan Monov76
          wrote on 13 Oct 2016, 16:29 last edited by
          #4

          @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.

          ? 1 Reply Last reply 13 Oct 2016, 16:47
          0
          • S Stefan Monov76
            13 Oct 2016, 16:29

            @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.

            ? Offline
            ? Offline
            A Former User
            wrote on 13 Oct 2016, 16:47 last edited by
            #5

            @Stefan-Monov76 Good to hear that it works! :-) Regarding your question: I don't know, sry.

            1 Reply Last reply
            0

            • Login

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved