Почему OpenGL обрезает полигоны (даже если эта настройка отключена)?

Я читал похожие предлагаемые вопросы и их решения, но не нашел ответа .

Я пытаюсь нарисовать сцену с изометрическим видом в OpenGL.

Функция рисования:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glRotatef(atan(0.5f) * 180.0f / PI, 1.0f, 0.0f, 0.0f);
glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
    
glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();

glPopMatrix();

В итоге я получаю такой результат. У камеры есть изометрическая проекция, но полигоны почему-то обрезаны.

Экран 1

Если я добавлю glTranslatef(-0.8f, 0, -0.8f) перед рисованием четырехугольника, результат будет следующим:

Экран 2

Проблема в том, что я не применяю никакой оптимизации к рендерингу OpenGL. Но почему полигоны должны быть обрезаны?


person Mark R.    schedule 30.06.2020    source источник


Ответы (1)


Полигоны отсекаются ближней или дальней плоскостью объема просмотра.

Если вы не зададите матрицу проекции, то пространство просмотра, пространство клипа и нормализованное пространство устройства будут одинаковыми. Нормализованное пространство устройств представляет собой уникальный куб, левый нижний край которого равен (-1, -1, -1), а правый верхний край далеко от (1, 1, 1). Вся геометрия, которая не находится внутри этого куба, обрезается.

На самом деле вы рисуете четырехугольник со стороной 1. Одна вершина четырехугольника находится в начале координат (0, 0, 0). Четырехугольник вращается вокруг исходной точки с помощью glRotate. Поскольку длина диагонали четырехугольника равна sqrt(2.0), одна вершина повернутого четырехугольника отсекается либо ближней, либо дальней плоскостью.

Если вы создадите и повернете четырехугольник с центром (0, 0, 0), он не будет обрезан, потому что длина от центра до каждой вершины равна sqrt(2.0)/2.0. То есть меньше 1 (расстояние до ближней и дальней плоскости от центра объема просмотра)

glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(-0.5f, 0.0f, -0.5f);
glVertex3f( 0.5f, 0.0f, -0.5f);
glVertex3f( 0.5f, 0.0f,  0.5f);
glVertex3f(-0.5f, 0.0f,  0.5f);
glEnd();

соответственно

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glRotatef(atan(0.5f) * 180.0f / PI, 1.0f, 0.0f, 0.0f);
glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);

glTranslate(-0.5f, 0.0f, -0.5f);

glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();

В качестве альтернативы вы можете установить ортографическую проекцию, которая увеличивает объем просмотра на glOrtho:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glOrtho(-1.0, 1.0, -1.0, 1.0, -2.0, 2.0);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

glRotatef(atan(0.5f) * 180.0f / PI, 1.0f, 0.0f, 0.0f);
glRotatef(-45.0f, 0.0f, 1.0f, 0.0f);    

glBegin(GL_QUADS);
glColor3f(1.0f, 1.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 0.0f);
glVertex3f(1.0f, 0.0f, 1.0f);
glVertex3f(0.0f, 0.0f, 1.0f);
glEnd();
person Rabbid76    schedule 30.06.2020
comment
Я воспользовался вашим предложением о glOrtho, и это действительно решило проблему. Спасибо. - person Mark R.; 01.07.2020