PDA

View Full Version : QGraphicsScene and GL textures



bence.frenyo
22nd July 2008, 09:58
Hi all,
I'm new to GL, and I've got to get this working soon. I've several images to be blended together in the background of the scene, and it seems logical to upload the images to the textures outside of the drawBackground(). But I only get a white rectangle, so the textures are lost somewhere. If I uncomment the code in drawBackground() then it works, but not efficient. Please enlighten me.



#define GL_GLEXT_PROTOTYPES 1

#include <QtGui>
#include <QGLWidget>
#include <GL/glext.h>

class GraphicsView : public QGraphicsView
{
public:
GraphicsView(QWidget* parent = 0) : QGraphicsView(parent) { }

protected:
void resizeEvent(QResizeEvent *event) {
if (scene())
scene()->setSceneRect(QRect(QPoint(0, 0), event->size()));
QGraphicsView::resizeEvent(event);
}
};

class GLScene : public QGraphicsScene
{
public:
GLScene();
~GLScene();

protected:
virtual void drawBackground(QPainter *painter, const QRectF &rect);
virtual void wheelEvent(QGraphicsSceneWheelEvent*);

private:
QImage m_img1;
QImage m_img2;
double m_zoom;
GLuint m_tex1;
GLuint m_tex2;
};

GLScene::GLScene() : QGraphicsScene(),
m_img1("img1.png"),
m_img2("img2.png"),
m_zoom(0.8)
{
setBackgroundBrush(Qt::NoBrush);

addWidget(new QPushButton("hello"))->setPos(10, 10);
addEllipse(QRectF(50, 50, 100, 70), QPen(Qt::red), QBrush(QColor(128, 192, 0, 128)));

glGenTextures(1, &m_tex1);
glGenTextures(1, &m_tex2);

glBindTexture(GL_TEXTURE_2D, m_tex1);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_img1.width(), m_img1.height(), 0,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, m_img1.bits());

glBindTexture(GL_TEXTURE_2D, m_tex2);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_img2.width(), m_img2.height(), 0,
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, m_img2.bits());
glFlush();
}

GLScene::~GLScene()
{
glDeleteTextures(1, &m_tex1);
glDeleteTextures(1, &m_tex2);
}

void GLScene::drawBackground(QPainter*, const QRectF&)
{
glClearColor(0.0, 0.0, 0.0, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

GLint blendSrc;
GLint blendDst;
glGetIntegerv(GL_BLEND_SRC, &blendSrc);
glGetIntegerv(GL_BLEND_DST, &blendDst);

glViewport(0, 0, (GLsizei) width(), (GLsizei) height());
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluOrtho2D(-1.0, 1.0, 1.0, -1.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);

glColor4f(1.0, 1.0, 1.0, 1.0);
glBindTexture(GL_TEXTURE_2D, m_tex1);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_img1.width(), m_img1.height(), 0,
// GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, m_img1.bits());
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(-m_zoom, -m_zoom);
glTexCoord2f(1.0, 0.0); glVertex2f(m_zoom, -m_zoom);
glTexCoord2f(1.0, 1.0); glVertex2f(m_zoom, m_zoom);
glTexCoord2f(0.0, 1.0); glVertex2f(-m_zoom, m_zoom);
glEnd();

glColor4f(1.0, 1.0, 1.0, m_zoom);
glBindTexture(GL_TEXTURE_2D, m_tex2);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_img2.width(), m_img2.height(), 0,
// GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, m_img2.bits());
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex2f(-m_zoom*.9, -m_zoom*.9);
glTexCoord2f(1.0, 0.0); glVertex2f(m_zoom*.9, -m_zoom*.9);
glTexCoord2f(1.0, 1.0); glVertex2f(m_zoom*.9, m_zoom*.9);
glTexCoord2f(0.0, 1.0); glVertex2f(-m_zoom*.9, m_zoom*.9);
glEnd();

glDisable(GL_TEXTURE_2D);

glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glBlendFunc(blendSrc, blendDst);
glFlush();
}

void GLScene::wheelEvent(QGraphicsSceneWheelEvent* event)
{
m_zoom += (double)event->delta()/1200.0;
update();
}

int main(int argc, char **argv)
{
QApplication app(argc, argv);

GraphicsView view;
view.setViewport(
new QGLWidget(QGLFormat(QGL::DoubleBuffer |
QGL::Rgba | QGL::AlphaChannel |
QGL::DirectRendering | QGL::SampleBuffers)));
view.setViewportUpdateMode(QGraphicsView::FullView portUpdate);
view.setScene(new GLScene);
view.setRenderHints(QPainter::Antialiasing);
view.show();

view.resize(400, 400);

return app.exec();
}

bence.frenyo
22nd July 2008, 10:30
First error is that enabling blend feature must be moved after drawing the first rectangle, but I still don't get the textures.



glDisable(GL_BLEND);
glEnable(GL_TEXTURE_2D);
glColor4f(1.0, 1.0, 1.0, 1.0);
glBindTexture(GL_TEXTURE_2D, m_tex1);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_img1.width(), m_img1.height(), 0,
// GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, m_img1.bits());
glBegin(GL_QUADS);
...
glEnd();

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f(1.0, 1.0, 1.0, m_zoom);
glBindTexture(GL_TEXTURE_2D, m_tex2);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_img2.width(), m_img2.height(), 0,
// GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, m_img2.bits());
glBegin(GL_QUADS);
...
glEnd();

bence.frenyo
22nd July 2008, 13:26
Never mind.
When uploading the textures there must be a current GL context, e.g. the viewport can be passed here to call makeCurrent() on it, so glGenTextures() can return valid texture ids, which wasn't the case.