Рисование перспективы в OpenGL с использованием glFrustum
Я пытаюсь нарисовать куб в перспективе шкафа. Это куб вglOrtho
:
Другие грани: Сзади - голубой, Слева - пурпурный, внизу - синий
Мой код:
//init function
glClearColor(1, 1, 1, 1);
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-10, 10, -10, 10, 4,6);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(0,0,-lat);//it doesn't show in the window without this.
DisplayAxis();
DisplayObject();
break;
//object initalization. I use glGenList and glCallList to draw it
void InitObject() {
glNewList(k, GL_COMPILE);
glColor3f(1, 0, 0);
glBegin(GL_QUADS);
glVertex3d(0, lat, lat);
glVertex3d(lat, lat, lat);
glVertex3d(lat, 0, lat);
glVertex3d(0, 0, lat);
glEnd();
glColor3f(1, 1, 0);
glBegin(GL_QUADS);
glVertex3d(lat, 0, 0);
glVertex3d(lat, 0, lat);
glVertex3d(lat, lat, lat);
glVertex3d(lat, lat, 0);
glEnd();
glColor3f(0, 1, 0);
glBegin(GL_QUADS);
glVertex3d(0, lat, lat);
glVertex3d(lat, lat, lat);
glVertex3d(lat, lat, 0);
glVertex3d(0, lat, 0);
glEnd();
glColor3f(0, 0, 1);
glBegin(GL_QUADS);
glVertex3d(0, 0, 0);
glVertex3d(lat, 0, 0);
glVertex3d(lat, 0, lat);
glVertex3d(0, 0, lat);
glEnd();
glColor3f(1, 0, 1);
glBegin(GL_QUADS);
glVertex3d(0, 0, lat);
glVertex3d(0, 0, 0);
glVertex3d(0, lat, 0);
glVertex3d(0, lat, lat);
glEnd();
glColor3f(0, 1, 1);
glBegin(GL_QUADS);
glVertex3d(0, lat, 0);
glVertex3d(lat, lat, 0);
glVertex3d(lat, 0, 0);
glVertex3d(0, 0, 0);
glEnd();
glEndList();
}
Что я здесь делаю не так? Я попробовал несколько поворотов объекта, но получил несколько искаженных результатов (при необходимости могу опубликовать больше изображений).
1 ответ
Объект отсечен ближней плоскостью усеченной пирамиды.
Вам не нужно перемещать объект по отрицательной оси Z, чтобы переместить объект между ближней и дальней плоскостями усеченной пирамиды:
glTranslated(0,0,-lat);//it doesn't show in the window without this.
Поскольку ось z пространства обзора указывает на окно просмотра, вам необходимо сместить объект вдоль отрицательной оси z.
Расстояние до ближней плоскости равно 4, а расстояние до дальней плоскости равно 6:
glFrustum(-10, 10, -10, 10, 4,6);
Расстояние до передней части куба меньше 4, поэтому он ограничен ближней плоскостью.
Измените усеченную вершину и оставьте куб полностью в усеченной вершине, чтобы решить проблему:
glFrustum(-10, 10, -10, 10, 4,6);
glFrustum(-2.5, 2.5, -2.5, 2.5, 1, 10);
glTranslated(0,0,-lat);
glTranslated(0, 0, -6);
Для хорошей перспективы и просмотра сцены используйте матрицу проекции (усеченную пирамиду) с меньшим полем обзора:
glFrustum(-1, 1, -1, 1, 1, 12);
В качестве альтернативы вы можете определить усеченную пирамиду с помощью gluPerspective
и задаем угол поля зрения в градусах:
gluPerspective(90, 1, 1, 12);
Матрица вида определяет положение и направление взгляда наблюдателя (зрителя) внутри сцены.
Если вы хотите по-другому взглянуть на сцену, вам нужно повернуть сцену (glRotate
):
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslated(0, 0, -8);
glRotatef(30, 1, 0, 0);
glRotatef(-45, 0, 1, 0);
В качестве альтернативы взгляд на сцену (матрица вида) может быть определен как gluLookAt
. Аргументы 1-3 - это положение наблюдателя (x,y, z компоненты глаза или положение камеры). Аргументы 4-6 являются целевой точкой (куда смотрит наблюдатель). Аргументы 7-9 - это восходящий вектор.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(5, 5, 7, 0, 0, 0, 0, 1, 0);