Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

glViewport didn't work on Qt5.4 QOpenGLWidget::resizeGL

Tags:

opengl

qt5.4

I put glViewport in QOpenGLWidget::resizeGL overwritted virtual function, which did get called and set viewport only use part of widget space. But it didn't have any effect, content still draw to full-size of widget. Did I missing anything?

Here is my code,

mywidget.h:

class MyWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
    Q_OBJECT

public:
    explicit MyWidget(QWidget* parent = NULL);

protected:
    virtual void initializeGL();
    virtual void paintGL();
    virtual void resizeGL(int w, int h);

private:
    QOpenGLShaderProgram program;
};

and mywidget.cpp:

MyWidget::MyWidget(QWidget* parent) : QOpenGLWidget(parent)
{
}

static const GLfloat squareVertices[] = {
    -1.0f, -1.0f,
     1.0f, -1.0f,
    -1.0f,  1.0f
};

void MyWidget::initializeGL()
{
    initializeOpenGLFunctions();
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

    program.addShaderFromSourceCode(QOpenGLShader::Vertex,
        "attribute highp vec4 vec;\n"
        "void main(void)\n"
        "{\n"
        "    gl_Position = vec;\n"
        "}");
    program.addShaderFromSourceCode(QOpenGLShader::Fragment,
        "void main(void)\n"
        "{\n"
        "    gl_FragColor = vec4(0.5, 0.5, 0.5, 1.0);\n"
        "}");
    program.link();
    program.bind();

    program.enableAttributeArray(0);
    program.setAttributeArray(0, squareVertices, 2);
}

void MyWidget::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT);

    //glViewport(0, 0, width()/2, height()/2);
    // if I put glViewport here, everything work as intended,
    // but we shouldn't need to set viewport everytime render a frame

    program.bind();
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
}

void MyWidget::resizeGL(int w, int h)
{
    glViewport(0, 0, w/2, h/2);
    // this line didn't have any effect, opengl still draw using full widget space
}
like image 625
user3724853 Avatar asked Jun 23 '15 11:06

user3724853


1 Answers

glViewport should be called in the drawing code, i.e. the paintGL handler, not somewhere else. Having the glViewport call in the window reshape handler is a bad anti-pattern that's just too far spread in OpenGL tutorials; it doesn't belong there.

like image 191
datenwolf Avatar answered Oct 23 '22 13:10

datenwolf