PDA

View Full Version : Problem with FBO in QGraphicsItem



Student3000
22nd September 2010, 09:35
Hi. I have a problem with programming a Framebufferobject in a QGraphicsItem Class.

It is simple, but it doesn’t work in the Context of the GraphicsItem. When it runs separated its works fine. The Problem when it should runs together has something to do with QGLContext. The following source code init and renders a Framebufferobject in the QGraphicsItem::paint method and after that it binds the FBO Texture to a GL_QUADS in the scene.

The Problem, look also at the picture in the attachment

1. If there is an additional QGLContext in QGraphicsItem::paint then the Framebufferobject rendering is correct, but the FBO texture didn’t bind to the Quad.

2. If there is no additional QGLContext, then the Framebufferobject rendering is disturbed, but the FBO texture is correctly bind to the Quad.


header file:



#ifndef __YidQt_FBOGraphicsItem_h__
#define __YidQt_FBOGraphicsItem_h__

#include <QGraphicsItem>
#include <QtOpenGL>


class FBOGraphicsItem : public QGraphicsItem
{

//Q_OBJECT

public:

FBOGraphicsItem();

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

private:

QWidget *widget2;
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;

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

// !!! additional context for rendering a correct framebufferobject
widget2 = new QWidget();
context = new QGLContext(QGLFormat(QGL::SampleBuffers | QGL::DoubleBuffer | QGL::AlphaChannel), widget2);
context->create();
context->makeCurrent();
fbo = new QGLFramebufferObject(512, 512);

fbo->bind();
{
// push the projection matrix and the entire GL state before
// doing any rendering into our framebuffer object
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();
{
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();
{
glColor3f(1.0f, 0.0f, 0.0f);
glBegin(GL_QUADS);
glVertex2f(-a1, -b1);
glVertex2f(-a1, b1);
glVertex2f( a1, b1);
glVertex2f( a1, -b1);
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, // eye
0,0,0, // center
0,1,0); // up

glTranslatef(0, 0, 0);

glEnable(GL_TEXTURE_2D);
{

// !!! bind texture to quad only works without additional content
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(1.0f, 0.0f); glVertex2f(-xx, yy);
glTexCoord2f(1.0f, 1.0f); glVertex2f( xx, yy);
glTexCoord2f(0.0f, 1.0f); glVertex2f( xx, -yy);
glEnd();

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

painter->endNativePainting();

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

}