QPaint到QGLFramebufferObject纹理?

时间:2013-12-28 21:06:45

标签: qt opengl textures vbo

我正在尝试学习如何将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();
}

2 个答案:

答案 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();
}