QGLFramebufferObject可以大于视口吗?

时间:2014-07-16 00:48:45

标签: qt opengl qt5

QGLFramebufferObject可以比视口大吗?例如,如果我有一个300x300像素的视口,那么fbo可以是600x300吗? ...所以显示fbo的一半......然后应用翻译,显示另一半。第一次make_text();被称为缩放是正确的,第二次x维度被拉伸。

main.h

#include <QGLWidget>
#include <QGLFunctions>
#include <QGLFramebufferObject>
#include <QFont>
#include <QGLShader>

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:
    void make_text(void);
    QGLFramebufferObject *fbo;
    QFont font;
    quint32 vbo_id[1], texture_id;
    QGLShaderProgram *txtovlp;
    QTimer *delay;

    private slots:
    void refresh(void);
};

的main.cpp

#include <QApplication>
#include <QPainter>
#include <QTimer>
#include "main.h"

struct txtr_vrtx {
    GLfloat   x;
    GLfloat   y;
    GLfloat   z;
    GLfloat   tx;
    GLfloat   ty;
}__attribute__((packed)) txtr_geo[] = {
    //   x, y, z, tx,ty
    {0, 0, 0, 0, 0},
    {0, 3, 0, 0, 1},
    {6, 3, 0, 1, 1},
    {6, 0, 0, 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)
{
    fbo = NULL;
    font.setFamily("Helvetica");
    delay = new QTimer;
    delay->start(2000);
    connect(delay, SIGNAL(timeout()), this, SLOT(refresh()));
}

glview::~glview()
{
    delete fbo;
}

void glview::refresh(void)
{
    delay->stop();
    qDebug() << "refresh fired";
    make_text();
    updateGL();
}

void glview::make_text(void)
{
    glBindBuffer(GL_ARRAY_BUFFER, 0);       // must unbind for QPainter

    glEnable(GL_TEXTURE_2D);
    if (fbo)
        delete fbo;
    makeCurrent();
    fbo =  new QGLFramebufferObject(600, 300, GL_TEXTURE_2D);
    fbo->bind();
    texture_id = fbo->texture();

    QPainter painter(fbo);
    font.setPointSize(20);
    painter.setFont(font);
    painter.eraseRect(0,0,600,300);
    painter.setPen(Qt::blue);
    painter.drawText(100, 140, "FBO");
    painter.setPen(Qt::red);
    painter.drawText(400, 140, "FBO");
    painter.end();

    fbo->release();
}

QSize glview::sizeHint() const
{
    return QSize(300, 300);
}

void glview::initializeGL()
{
    initializeGLFunctions();
    qglClearColor(Qt::white);

    QGLShader *txtovlp_vshader = new QGLShader(QGLShader::Vertex, this);
    const char *txtovlp_vsrc =
            "attribute highp vec4 vertex;\n"
            "attribute mediump vec2 texCoord;\n"
            "varying mediump vec2 texc;\n"
            "uniform mediump mat4 matrix;\n"
            "void main(void)\n"
            "{\n"
            "    gl_Position = matrix * vertex;\n"
            "    texc = texCoord;\n"
            "}\n";
    txtovlp_vshader->compileSourceCode(txtovlp_vsrc);

    QGLShader *txtovlp_fshader = new QGLShader(QGLShader::Fragment, this);
    const char *txtovlp_fsrc =
            "uniform sampler2D texture;\n"
            "varying mediump vec2 texc;\n"
            "void main(void)\n"
            "{\n"
            "    gl_FragColor = texture2D(texture, texc.st);\n"
            "}\n";
    txtovlp_fshader->compileSourceCode(txtovlp_fsrc);

    txtovlp = new QGLShaderProgram(this);
    txtovlp->addShader(txtovlp_vshader);
    txtovlp->addShader(txtovlp_fshader);
    txtovlp->link();

    glGenBuffers(1, vbo_id);
    glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(txtr_geo), txtr_geo, GL_STATIC_DRAW);

    make_text();

    glEnable(GL_DEPTH_TEST);
}

void glview::resizeGL(int w, int h)
{
    glViewport(0, 0, w, h);
}

void glview::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    QMatrix4x4 matrix;
    matrix.ortho(0, 3, 0, 3, -1, 1);
    //matrix.translate(-3,0,0);

    txtovlp->bind();
    txtovlp->setUniformValue("matrix", matrix);

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

    glBindBuffer(GL_ARRAY_BUFFER, vbo_id[0]);
    glBindTexture(GL_TEXTURE_2D, texture_id);

    int txtr_vertexLocation = txtovlp->attributeLocation("vertex");
    txtovlp->enableAttributeArray(txtr_vertexLocation);
    glVertexAttribPointer(txtr_vertexLocation, 3, GL_FLOAT, GL_FALSE, sizeof(struct txtr_vrtx), 0);

    int texCoordLocation = txtovlp->attributeLocation("texCoord");
    txtovlp->enableAttributeArray(texCoordLocation);
    glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, sizeof(struct txtr_vrtx), ((char*)NULL + 12));

    glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);

    glFlush();
}

1 个答案:

答案 0 :(得分:0)

QPainter破坏GL上下文,我已经了解到还包括视口。通过添加glViewport(0,0,width(),height());在make_text()的末尾(在QPainter完成之后)恢复下一个绘制事件的视口。