Рисование перспективы в OpenGL с использованием glFrustum - PullRequest
1 голос
/ 07 мая 2020

Я пытаюсь нарисовать куб в перспективе inet кабины. Это куб в glOrtho:

cube

Другие грани: Сзади - голубой, Слева - пурпурный, внизу - синий

Вот что я получаю

Это то, чего я хочу достичь

Мой код:

//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 Ответ

2 голосов
/ 07 мая 2020

Объект обрезается ближней плоскостью Угол обзора .

Вам не нужно перемещать объект по отрицательной оси 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);

...