Please nominate your Qt Champions for 2021!

Qopenglframebufferobject in any function

  • Hi,
    how can I create a qopenglframebufferobject in any function, not only the ones which automatically provide an opengl context, i.e. how do I provide an opengl context so that the creation of an qopenglframebufferobject won't lead to a crash any more. I could not find any examples; each one I saw generated the qopenglframebufferobject within initializeGL or paintGL.

  • Yes, that is perhaps a design flaw of that class which breaks from the pattern of the other OpenGL classes that have an explicit create() type function.

    With QOpenGLFramebufferObject you have no choice but ensure you have a valid OpenGL context when you create the object instance. Why can't you defer creation until you have a context? You won't be able to do anything with the FBO until then anyway.

  • Thanks for your answer. Basically, I have a class (a scenenode), which initializes in its constructor the qopenglframebufferobjects in order to save a special kind of texture in it (the sides of a CUBE_MAP, i.e. target=GL_TEXTURE_CUBE_MAP_POSITIVE_X​, ...). There is an update function which is supposed to generate and store textures in the respective qopengelframbufferobject.
    It seems to me that I haven't yet really understood the concept of opengl contexts in qt. In which functions/classes do I have a valid context? Can I create/access a previously generated context? What does it mean to be in an opengl context?

  • (This is all for Qt5)

    An OpenGL context is represented by the class QOpenGLContext. The context contains the complete set of OpenGL state. There are typically two ways of handling the OpenGL context:

    Create a QWindow and QOpenGLContext yourself and manage when the context is current. This gives you total control.

    Use QGLWidget or QQuickView and have them create a context for you. These classes also make the context current at specified times.

    The approach you use is up to you and depends on what you want to do. Of course you can combine both methods by having more than one context.

    You can only have one current OpenGL context on any thread at a time and any context can only be current on a single thread at a time.

    To see if there is a context current on your current thread you can call the QOpenGLContext::currentContext() static function which will return you either a pointer to the current QOpenGLContext object or a null pointer if there is no context current at that time.

    If you have a pointer to a QOpenGLContext object you can try to make it current by calling QOpenGLContext::makeCurrent( surface ) where surface is typically the window.

    Conceptually, QGLWidget will do something like this under the hood (pseudo code):
    void QGLWidget::init()
    m_context->makeCurrent( this );
    where you then implement the initializeGL() virtual function. So it's easy to do the same sort of thing yourself using just a QWindow and QOpenGLContext.

    Hope this helps but feel free to come back with more questions if needed.

  • Ah, now it all becomes clearer.
    I am subclassing Qt3D's QGLView class. In the contructor, a scenenode (QGLSceneNode) is added as described above. There seems to be no valid context yet. I will have a closer look at QGLView's source in order to see how context-management is handled there.
    Maybe one more question: when I have 2 contexts and created a bunch of variables (e.g. qframebufferobjects) in one of them, can they be accessed by the other? Or only from within the current context. What happens with the variables, when the context goes out of scope?

  • It depends on if the contexts have been created as part of the same context sharing group or not. If they have then some object types become shared between them e.g. textures is a common example. The objects persist until the last context in the sharing group is destroyed.

  • I do now have a valid context, but unfortunately, there is still a problem. Basically, I want to create a cube map texture. Therefore, I call
    glGenTextures(1, &cubeTexID);
    glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexID);

    and want the texture cube sides to be stored in 6 qopenglframebuffers. So I create them:

    fbo_positive_x = new QOpenGLFramebufferObject(fboSize, QOpenGLFramebufferObject::Depth, GL_TEXTURE_CUBE_MAP_POSITIVE_X);
    But there seems to be a problem with the attachment, because is says:
    "QOpenGLFramebufferObject: Framebuffer incomplete, missing attachment."
    I had a look at the glCheckFramebufferStatus function but that didn't tell me much.

    Thanks for any hints.

  • An example sequence for rendering to a cubemap is here:

    I don't have time to make an exampel and debug it right now but I would recommend stepping through the function QOpenGLFramebufferObjectPrivate::init() in a debugger to see where things are going wrong.

  • I will have a look at both the example and the debug-output. Thanks.

Log in to reply