Important: Please read the Qt Code of Conduct -

QQuickView to FBO to OpenGL texture

  • Hello,

    I'm trying to render a QML scene overlaid on top of an OpenGL scene.
    To achieve this, I used QQuickView::setRenderTarget() to render to an FBO.
    I know this part is working, as I can retrieve the render using QOpenGLFrameBufferObject::toImage() and display it as a QLabel pixmap.

    My issue is about the texture part: I don't want to use toImage() as it has to make a QImage on the CPU, and is relatively slow.
    I want to retrieve the contents of the FBO as a texture, that I can map to a rectangle in my scene.
    It would seem QOpenGLFrameBufferObject doesn't provide a way to get a QOpenGLTexture, so I simply want to call glBindTexture(GL_TEXTURE_2D, fbo->texture()) for the time being ([url=]in the same way James Turner does in this talk[/url], except I don't use shared contexts), which I can't get to work.

    Another issue with QQuickView, is that it must be visible in order to render (as I understand, the scene graph is disabled whenever the QQuickView is hidden); I would prefer the QQuickView to stay hidden, but still render to the FBO when needed, if possible.

    Also, a feature expected to be included in Qt 5.4 is the following:
    "QQuickRenderControl is made public. This API allows efficient rendering of Qt Quick 2 scenes into framebuffer objects. The contents can then be used in arbitrary ways in Qt-based or 3rd party OpenGL renderers."
    which should do what I want more easily.

    Is there any way to force a hidden QQuickView to render (or another QtQuick class that can render to an FBO)? And if maybe someone could also help me about the OpenGL part, the relevant code in my render function is the following:
    funcs()->glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
    m_guiProgram->setUniformValue("textureSampler", 0);@

    This code only draws a black rectangle (my shaders are correct as well, the same shader can display a texture when passed a texture via QOpenGLTexture::bind()).

  • Yes, using toImage() is not ideal at all.

    The proper way is to use QQuickRenderControl instead, but that's only available in 5.4.

    It is possible to render the a subtree of the scene into an fbo with earlier versions too, since this is what shader effects do. Accessing the texture needs internal APIs however so the resulting code is not exactly nice & clean. See

  • Thanks for the info and the links, I'll have a read.
    QQuickRenderControl has been in my sights since I first read the planned features for 5.4, so I'll be sure to use it when it's available!

    For the time being, I can live with the UI living in a separate window.

  • Would you mind sharing an example of QQuickRenderControl if you have?
    Thank a lot.

  • I were doing the same thing before, but that I don't use any RTT feature , instead I use normal rendering pipeline. I don't know if it is faster when using RTT.
    Here is my blog and code talking about this.

Log in to reply