Why QGLFramebufferObject in QGraphicsItem don’t work?



  • Hi. I have a problem with programming a QGLFramebufferObject in a QGraphicsItem class.

    I get an incorrect rendering of the framebufferobject and a message in my output result. (please look at the output image)

    QGLContext::chooseContext() : SetPixelFormat failed : The pixel format is invalid.

    The following source code init and renders a QGLFramebufferObject in the QGraphicsItem::paint method and after that it binds the FBO Texture to a GL_QUADS in the scene.

    header file:

    @
    #ifndef YidQt_FBOGraphicsItem_h
    #define YidQt_FBOGraphicsItem_h

    #include <QGraphicsItem>
    #include <QtOpenGL>

    class FBOGraphicsItem : public QGraphicsItem
    {

    public:

    FBOGraphicsItem();

    // pure virtual functions from QGraphicsItem
    virtual QRectF boundingRect() const;
    virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

    private:

    QGLContext *context;
    QGLFramebufferObject *fbo;

    QRectF myBoundingRect;
    float xx;
    float yy;

    };

    #endif // YidQt_FBOGraphicsItem_h
    @

    source file:

    @
    void FBOGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {

    if (painter->paintEngine()->type() != QPaintEngine::OpenGL &&
    painter->paintEngine()->type() != QPaintEngine::OpenGL2)
    {
    qWarning("TestGLGraphicsItem: drawBackground needs a QGLWidget to be set as viewport on the graphics view");
    return;
    }

    float a1 = 0.5f * 1;
    float b1 = 0.5f * 1;

    // !!! error with this context !!!
    context = new QGLContext(QGLFormat(QGL::SampleBuffers | QGL::DoubleBuffer | QGL::AlphaChannel), widget);
    context->create(); // this line create an error: QGLContext::chooseContext() : SetPixelFormat failed
    context->makeCurrent();

    // ------------ FBO begin ------------

    fbo = new QGLFramebufferObject(512, 512);

    fbo->bind();
    {
    glPushAttrib(GL_ALL_ATTRIB_BITS);
    {
    glViewport(0, 0, fbo->size().width(), fbo->size().height());

    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    {
     glLoadIdentity();
     glOrtho(-1.0, 1.0, -1.0, 1.0, 99, -99);
     gluLookAt(0.0, 0.0, 1.0, 
         0.0, 0.0, 0.0, 
         0.0, 1.0, 0.0);
     
     glMatrixMode(GL_MODELVIEW);
     glPushMatrix();
     {
      glLoadIdentity();
    
      // red rectangle
      glColor3f(1.0f, 0.0f, 0.0f);
      glBegin(GL_QUADS);
       glVertex2f(-a1, -b1);
       glVertex2f(-a1,  b1);
       glVertex2f( a1,  b1);
       glVertex2f( a1, -b1);
      glEnd();
    
      // control points
      glPointSize(5.0f); 
      glColor3f(0.0f, 0.0f, 0.0f);
      glBegin(GL_POINTS);           
       glVertex3f(0.0f, 0.0f, 0.0f);
    
       glVertex3f(a1, 0.0f, 0.0f);
       glVertex3f(-a1, 0.0f, 0.0f);
    
       glVertex3f(0.0f, a1, 0.0f);
       glVertex3f(0.0f, -a1, 0.0f);
    
       glVertex3f(0.0f, 0.0f, a1);
       glVertex3f(0.0f, 0.0f, -a1);
      glEnd();
     }
     glMatrixMode(GL_MODELVIEW);
     glPopMatrix();
    }
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();
    

    }
    glPopAttrib();
    }

    fbo->release();
    fbo->toImage().save("d:\fbo.bmp");

    // ------------ FBO end ------------

    // ------------ SZENE begin ------------

    painter->beginNativePainting();

    glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    {
    glLoadIdentity();
    gluPerspective(70, WIDTH / HEIGHT, 0.01, 1000);

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    {
    glLoadIdentity();
    gluLookAt(0,0,1,
    0,0,0,
    0,1,0);

    glTranslatef(0, 0, 0);
    
    glEnable(GL_TEXTURE_2D);
    {
     glBindTexture(GL_TEXTURE_2D, fbo->texture());
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    
     glBegin(GL_QUADS);
      glTexCoord2f(0.0f, 0.0f); glVertex2f(-xx, -yy);
      glTexCoord2f(0.0f, 1.0f); glVertex2f(-xx,  yy);
      glTexCoord2f(1.0f, 1.0f); glVertex2f( xx,  yy);
      glTexCoord2f(1.0f, 0.0f); glVertex2f( xx, -yy);
     glEnd();
    }
    glDisable(GL_TEXTURE_2D);     
    

    }
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();
    }
    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    painter->endNativePainting();

    // ------------ SZENE end ------------

    }
    @

    Ouput:

    !http://www.czepa.net/output.jpg(output image)!



  • good news, i've found a way to rendering a correct fbo to the quad in the scene.

    it was dependend of the order of the painter->beginNativePainting(); line. i changed the order, that the painter->beginNativePainting(); is before the QGLContext and QGLFramebufferobject is init.

    the message is still active but the result is correct.

    source
    @
    painter->beginNativePainting();

    // ------------ FBO begin ------------

    context = new QGLContext(QGLFormat(QGL::SampleBuffers | QGL::DoubleBuffer | QGL::AlphaChannel), widget);
    context->create(); // !!!
    context->makeCurrent();

    fbo = new QGLFramebufferObject(512, 512); // GLWidget::GLWidget (constructor)

    fbo->bind();
    {
    ...
    }
    fbo->release();
    @

    Output

    !http://www.czepa.net/output2.jpg(Output Image)!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.