我正在尝试学习如何将QPainter与QGLFramebufferObject一起使用。当我尝试在QGLWidget中显示纹理时,它是不可见的。 (下面的完整代码)
最终目标是使用QPainter在纹理上绘制文本,然后将纹理混合到2D线几何体的顶部。
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();
}
答案 0 :(得分:1)
离开initializeGL()时会破坏QGLFramebufferObject实例。这导致也删除纹理。您需要保持QGLFramebufferObject保持活动状态,直到不再需要纹理。
答案 1 :(得分:0)
这是更正后的代码。还有alpha弯曲。
main.h
#include <QGLWidget>
#include <QGLFunctions>
#include <QGLFramebufferObject>
#include <QFont>
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:
QGLFramebufferObject *fbo;
QFont font;
quint32 vbo_id[2], texture_id;
};
的main.cpp
#include <QApplication>
#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)
{
font.setFamily("Helvetica");
}
glview::~glview()
{
delete fbo;
}
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);
glBindBuffer(GL_ARRAY_BUFFER, 0); // must unbind for QPainter
fbo = new QGLFramebufferObject(100, 100, GL_TEXTURE_2D);
fbo->bind();
texture_id = fbo->texture();
QPainter painter(fbo);
painter.setPen(Qt::blue);
font.setPointSize(20);
painter.setFont(font);
painter.drawText(0, 60, "FBO");
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));
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
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();
}