glViewport在Qt5.4 QOpenGLWidget :: resizeGL上不起作用

use*_*853 8 opengl qt5.4

我把glViewport放在QOpenGLWidget :: resizeGL覆盖的虚函数中,它实际上被调用并且set viewport只使用了widget空间的一部分.但它没有任何效果,内容仍然绘制到全尺寸的小部件.我错过了什么吗?

这是我的代码,

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;
};
Run Code Online (Sandbox Code Playgroud)

和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
}
Run Code Online (Sandbox Code Playgroud)

dat*_*olf 2

glViewport应该在绘图代码中调用,即paintGL处理程序,而不是其他地方。在窗口重塑处理程序中进行调用glViewport是一种不好的反模式,这种模式在 OpenGL 教程中传播得太广;它不属于那里。