PDA

View Full Version : Why QGLFramebufferObject in QGraphicsItem don’t work?



Student3000
22nd September 2010, 21:26
Hi. I still have the problem with programming a QGLFramebufferObject in a QGraphicsItem class.

This time i used another approach and got an incorrect rendering of the framebufferobject and a message in my output result. (look at the attachment)

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
{

//Q_OBJECT

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();

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

}

Student3000
23rd September 2010, 21:12
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 switch 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();


http://www.czepa.net/output2.jpg