OpenGL поддерживает форму объекта при изменении размера окна - PullRequest
0 голосов
/ 14 мая 2018

У меня есть квадрат, и я пытаюсь заставить его оставаться квадратом при изменении размера окна, а не растягиваться с окном. У меня есть некоторый код, который, я думал, будет работать, но когда я изменяю размер окна, квадрат сжимается и исчезает. Он не возвращается, когда я возвращаю окно к его первоначальному размеру. Может кто-нибудь сказать мне, что я сделал не так и как это исправить?

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

1 Ответ

0 голосов
/ 14 мая 2018

Функции gluOrtho2D и glOrtho умножают текущую матрицу на новую матрицу ортографической проекции.
Это приводит к тому, что если reshape вызывается во 2-й раз, матрица, которая была установлена ​​gluOrtho2D ранее, умножается на новую, и вы получаете последовательные изменения.

Вы должны «сбросить» матрицу (инициализировать матрицу идентификации) в стеке матриц с помощью glLoadIdentity. Далее вы должны выбрать матрицу проекций на glMatrixMode:

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

    .....
}
...