Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Frame Buffer Object not being updated when QOpenGLWidget update is called.



  • I'm trying to do a off screen rendering using a native framebuffer object but the QOpenGLWidget paintGL method is interfering somehow on fbo writing. Basically, i have a main class MainGL( QOpenGLWidget), which instantiate a QMediaplayer, setting a custom surface called MyVideoWidgetSurface(QAbstractVideoSurface) as output surface.

    The basic flow is: whenever a new video frame is available at QAbstractVideoSurface::present, the related video frame texture is rendered to a off screen frame buffer and later grabbed as a new QImage by glReadPixels. Later, this QImage is passed to MainGL using a signal/slot. The slot calls QOpenglWidget update method witch renders the QImage on the screen. The issue takes place exactly after QOpenglWidget::update is called for the first time, because the first framebuffer object is grabbed correctly. If i comment the 'emitting a signal' part then all offscreen rendering succeed without problem.
    What can QOpenGLWidget::paintGL is doing to has this side effect ? I have already commented out all my code in the overwritten paintGL method to ensure that is not the render to screen code sake.

    Bellow is the offscreen rendering part.

    MyVideoWidgetSurface::present(QVideoFrame frame){
    	// extract m_fbotex here
    	...
            QOpenGLContext* ctx = QOpenGLContext::currentContext();
            QOpenGLFunctions* f = ctx->functions();
    
            GLCHK(f->glGetIntegerv( GL_FRAMEBUFFER_BINDING, &prevFbo ));
            GLCHK(f->glBindFramebuffer(GL_FRAMEBUFFER, m_fbo));
            GLCHK(f->glUseProgram(programObject));
            GLCHK(f->glViewport(0, 0, texWidth, texHeight));
            GLCHK(f->glClearColor(0.0f, 0.0f, 0.0f, 0.0f));
            GLCHK(f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
    
            GLCHK(f->glVertexAttribPointer ( positionLoc, VTX_POS_SIZE, GL_FLOAT,GL_FALSE, VTX_STRIDE, (GLvoid*) offset ));
            offset += VTX_POS_SIZE * sizeof(GLfloat);
            GLCHK(f->glVertexAttribPointer ( texCoordLoc, VTX_TEX_SIZE, GL_FLOAT,GL_FALSE, VTX_STRIDE, (GLvoid*) offset ));
    
            GLCHK(f->glEnableVertexAttribArray ( positionLoc ));
            GLCHK(f->glEnableVertexAttribArray ( texCoordLoc ));
    
            GLCHK(f->glActiveTexture ( GL_TEXTURE0 ));
            GLCHK(f->glBindTexture(GL_TEXTURE_2D, m_fbotex));
    
    	// fill m_fbotex texture with dummy data, test purpose only.
            QImage dummy( currentFrame.width(), currentFrame.height(), QImage::Format_ARGB32);
            unsigned int randcolor = QRandomGenerator::global()->generate();
            dummy.fill(QColor::fromRgb(randcolor));
    
            GLCHK(f->glTexImage2D(GL_TEXTURE_2D, 0, GL_BGRA_EXT,  texWidth, texHeight,0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,  dummy.bits()));
            GLCHK(f->glUniform1i ( samplerLoc, 0 ));
    
            GLCHK(f->glBindTexture(GL_TEXTURE_2D, 0));
            GLCHK(f->glActiveTexture ( GL_TEXTURE0 ));
            GLCHK(f->glBindTexture(GL_TEXTURE_2D, m_fbotex));
            GLCHK(f->glDrawElements ( GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0 ));
            GLCHK(f->glReadPixels( 0, 0,  texWidth,  texHeight, GL_RGBA, GL_UNSIGNED_BYTE, imageCaptured.bits() ));
            GLCHK(f->glUseProgram(0));
            GLCHK(f->glBindTexture(GL_TEXTURE_2D, 0));
            GLCHK(f->glBindFramebuffer(GL_FRAMEBUFFER, prevFbo));
                            
            emit changed(imageCaptured); //the associated slot issue a update on MainGL (QOpenlGLWidget).
    	...
    	return true;
    			
    }
    
    

    If someone else could give a tip on what is causing this i would be thankful.
    Best Regards,
    Thanks in advance.


Log in to reply