I am trying to learn how to use QPainter with a QGLFramebufferObject. When I try to display the texture in a QGLWidget, it is not visible. (complete code below)
The end goal is to use QPainter to draw text onto textures and then alpha blend the texture overtop of the 2D line geometry.
texture.pro
QT += core gui widgets opengl
TARGET = test
TEMPLATE = app
SOURCES = main.cpp
HEADERS = main.h
main.h
#include <QGLWidget>
#include <QGLFunctions>
class glview : public QGLWidget, protected QGLFunctions
{
Q_OBJECT
public:
explicit glview(QWidget *parent = 0);
~glview();
QSize sizeHint() const;
protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
private:
quint32 vbo_id[2], texture_id;
};
main.cpp
#include <QApplication>
#include <QGLFramebufferObject>
#include <QPainter>
#include "main.h"
struct vrtx {
GLint x;
GLint y;
GLubyte r;
GLubyte g;
GLubyte b;
}__attribute__((packed)) line_geo[] = {
// x, y, r, g, b
{1, 1, 255, 0, 0},
{1, 2, 0, 255, 0},
{1, 2, 0, 255, 0},
{2, 2, 255, 0, 0},
{2, 2, 255, 0, 0},
{2, 1, 0, 255, 0},
{2, 1, 0, 255, 0},
{1, 1, 255, 0, 0},
};
struct txtr_vrtx {
GLint x;
GLint y;
GLint tx;
GLint ty;
}__attribute__((packed)) txtr_geo[] = {
// x, y, tx,ty
{3, 1, 0, 0},
{3, 2, 0, 1},
{4, 2, 1, 1},
{4, 1, 1, 0},
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
glview widget;
widget.show();
return app.exec();
}
glview::glview(QWidget *parent) : QGLWidget(parent)
{
}
glview::~glview()
{
}
QSize glview::sizeHint() const
{
return QSize(500, 300);
}
void glview::initializeGL()
{
initializeGLFunctions();
qglClearColor(Qt::white);
glGenBuffers(2, vbo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
glBufferData(GL_ARRAY_BUFFER, sizeof(line_geo), line_geo, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1]);
glBufferData(GL_ARRAY_BUFFER, sizeof(txtr_geo), txtr_geo, GL_STATIC_DRAW);
QGLFramebufferObject fbo(100, 100, QGLFramebufferObject::CombinedDepthStencil/*GL_TEXTURE_2D*/);
fbo.bind();
texture_id = fbo.texture();
QPainter painter(&fbo);
painter.fillRect(0, 0, 100, 100, Qt::blue);
painter.end();
fbo.release();
}
void glview::resizeGL(int w, int h)
{
glViewport(0, 0, w, h);
}
void glview::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glOrtho(0, 5, 0, 3, -1, 1);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
glVertexPointer(2, GL_INT, sizeof(struct vrtx), 0);
glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(struct vrtx), ((char*)NULL + 8));
glDrawArrays(GL_LINES, 0, sizeof(line_geo) / sizeof(struct vrtx));
//glColor4ub(0, 0, 255, 255);
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glDisableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id[1]);
glBindTexture(GL_TEXTURE_2D, texture_id);
glVertexPointer(2, GL_INT, sizeof(struct txtr_vrtx), 0);
glTexCoordPointer(2, GL_INT, sizeof(struct txtr_vrtx), ((char*)NULL + 8));
glDrawArrays(GL_QUADS, 0, 4);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisable(GL_TEXTURE_2D);
//glDisable(GL_BLEND);
glFlush();
}
The QGLFramebufferObject instance is destroyed when leaving initializeGL(). This results in deleting the texture too. You need to keep the QGLFramebufferObject alive until the texture is no longer needed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With