OpenGL 在 window 调整大小时保持对象形状

OpenGL maintain object shape on window resize

我有一个正方形,我试图在 window 调整大小时使其保持正方形,而不是使用 window 进行拉伸。我有一些我认为可行的代码,但是当我调整 window 的大小时,正方形会缩小并消失。当我 return 将 window 恢复到原始大小时,它不会恢复。有人可以告诉我我做错了什么以及如何解决吗?

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT);

    glBegin(GL_POLYGON);
    glVertex2f(-0.5, -0.5);
    glVertex2f(-0.5, 0.5);
    glVertex2f(0.5, 0.5);
    glVertex2f(0.5, -0.5);
    glEnd();

    glFlush();
    return;
}

void reshape(int w, int h) {
    const float aspectRatio = ((float)w) / h;
    float xSpan = 1;
    float ySpan = 1;

    if (aspectRatio > 1) {
        xSpan *= aspectRatio;
    }
    else {
        ySpan *= aspectRatio;
    }

    gluOrtho2D(-1*xSpan, xSpan, -1*ySpan, ySpan);
    glViewport(0, 0, w, h);
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutCreateWindow("simple");
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutMainLoop();
}

函数gluOrtho2D and glOrtho将当前矩阵乘以新的正交投影矩阵。
这导致如果 reshape 被第二次调用,之前由 gluOrtho2D 设置的矩阵乘以新的矩阵,你会得到连续的变化。

你必须通过 glLoadIdentity. Further you should choose the projection matrix stack by glMatrixMode:

"reset" 矩阵堆栈上的矩阵(初始化恒等矩阵)
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-1*xSpan, xSpan, -1*ySpan, ySpan);

视口 glViewport 的设置是正确的,您也正确考虑了宽高比(在 gluOrtho2D 中)。但如果纵横比小于 1.0,就会出现问题。应该是ySpan /= aspectRatio;

我建议在display函数中设置视口和投影矩阵,并在reshape函数中设置一个通知标志。请注意,视口和投影矩阵应尽可能少地更改。

bool vp_valid = true;
int  width, height;

void reshape(int w, int h) {
    vp_valid = false;
    width = w;
    height = h;
}

void display(void)
{
    if (!vp_valid)
    {
      const float aspectRatio = (float)width / height;
      float sx = aspectRatio > 1.0f ? aspectRatio : 1.0f;
      float sy = aspectRatio > 1.0f ? 1.0f : 1.0f/aspectRatio;

      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluOrtho2D(-sx, sx, -sy, sy);

      glViewport(0, 0, width, height);
    }

    .....
}