Функции 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);
}
.....
}