У меня есть квадрат, и я пытаюсь сделать так, чтобы он оставался квадратом при изменении размера окна, а не растягивался вместе с окном. У меня есть код, который, как я думал, сработает, но когда я изменяю размер окна, квадрат сжимается и исчезает. Он не возвращается, когда я возвращаю окно к исходному размеру. Может кто подскажет, что я сделал не так и как это исправить?
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 и glOrtho умножают текущую матрицу на новую матрицу ортогональной проекции.
Это приводит к тому, что если reshape вызывается второй раз, матрица, которая была установлена 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);
}
.....
}
Почему вы вызываете
gluOrtho2Dв функции изменения формы? Он должен скорее содержать код, который сбрасывает матрицу проекции до идентичности ... Вместо этого вызовитеgluOrtho2Dв функции отображения.