2014-07-16 2 views
1

QGLFramebufferObject peut-il être plus grand que la fenêtre d'affichage? Par exemple, si j'ai une fenêtre de 300x300 pixels, le fbo peut-il être 600x300? ... donc une moitié du fbo est affichée ... puis en appliquant une traduction, l'autre moitié est montrée. La première fois make_text(); est appelé la mise à l'échelle est correcte, la deuxième fois la dimension x est étirée.QGLFramebufferObject peut-il être plus grand que la fenêtre d'affichage?

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

Répondre

0

QPainter Trashes le contexte de GL et je l'ai appris, qui comprend également la fenêtre. En ajoutant glViewport (0, 0, width(), height()); à la fin de make_text() (après que QPainter est terminé) restaure la fenêtre pour l'événement paint suivant.

Questions connexes