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)!