Как воссоздать / модифицировать матрицу ортографической проекции (OpenGL)

#c #opengl #glfw #opengl-compat

#c #opengl #glfw #opengl-compat

Вопрос:

Я создал простую программу OpenGL, которая рисует 2D текстуру на экране. При изменении размера окна оно не настраивается должным образом, поэтому, чтобы исправить это, я бы просто снова запустил код матрицы проекции:

 if (windowSizeChange)
{
    std::cout << "Window resized." << std::endl;
    std::cout << windowWidth << " " << windowHeight << std::endl;
    windowSizeChange = false;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, windowWidth, windowHeight, 0.0, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
}
  

Однако выполнение этого кода искажает изображение. Насколько я понимаю, чтобы я мог рисовать на экране в формате 2D, моя текстура рисуется с использованием матрицы ортогональной проекции, что означает, что есть плоскость, которая «параллельна» порту окна или чему-то подобному тому, на чем я рисую. Когда я пытаюсь переделать ее, чтобы приспособить к новому размеру окна, она не настраивается должным образом. Что происходит не так с этим кодом?

Ответ №1:

В вашем коде вы меняете ортогональную матрицу, но вам также необходимо изменить glViewport:

 if (windowSizeChange)
{
    glViewport(0, 0, windowWidth, windowHeight); // <-- Add this
    std::cout << "Window resized." << std::endl;
    std::cout << windowWidth << " " << windowHeight << std::endl;
    windowSizeChange = false;
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(0.0, windowWidth, windowHeight, 0.0, -1.0, 1.0);
    glMatrixMode(GL_MODELVIEW);
}
  

Ортографические матрицы — это, как вы сказали, просто матрица, которая в данном случае параллельна экрану. Когда мы вызываем glOrtho, он изменяет размер матрицы, с которой мы работаем, а glViewport сообщает OpenGL размер области просмотра (в данном случае нашего окна), с которой мы работаем. Обычно вы хотите, чтобы glOrtho и glViewport имели одинаковые размеры

Ответ №2:

Когда размер окна и фреймбуфера был изменен, вам нужно настроить прямоугольник области просмотра.
Прямоугольник окна просмотра может быть установлен с помощью glViewport и определяет, как нормализованные координаты устройства сопоставляются с координатами окна. Она определяет область фреймбуфера, куда отображаются нормализованные координаты устройства от (-1, -1) до (1, 1).

 glViewport(0, 0, windowWidth, windowHeight);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0, windowWidth, windowHeight, 0.0, -1.0, 1.0);