glFrustum не создает перспективу

Я пытаюсь создать программу для работы с 3D, используя C ++ и openGL. Я относительно новичок в openGL, поэтому мне часто приходится искать документацию, чтобы найти подходящую функцию для выполнения того, что я хочу. Я думал, что у меня было хорошее понимание ортогональных и перспективных проекций (в этом glOrtho создает ортогональную проекцию, где разные значения z не выглядят по-разному и glFrustum создает перспективную проекцию, где значения z, которые ближе, выглядят больше). Тем не менее, когда я меняю glOrtho а также glFrustum в моей программе я не вижу никакой разницы. Я воспроизвел небольшую программу ниже, которая показывает эффекты. Для справки я использую openGL с freeglut.

#include "GL/freeglut.h"void initFunc()
{
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1, 1, -1, 1, -1, 1);

}

void displayFunc()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

glColor3f(1.0f, 1.0f, 0.0f);
glLineWidth(1.0f);
glutWireTeapot(0.3);

glTranslatef(0, -0.5, -0.5);
glutWireTeapot(0.3);

glutSwapBuffers();
}

int main(int argc, char ** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(600, 600);
glutInitWindowPosition(0, 0);

glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutCreateWindow("Teapot Perspective");

initFunc();

glutDisplayFunc(displayFunc);

glutMainLoop();
}

Я рисую два чайника, слегка смещенных по осям y и z. Из того, что я понимаю, glOrtho следует сделать оба чайника идентичными, только со смещением y, тогда как glFrustum должен сделать один из них больше другого. Тем не менее, оба они делают чайники одинаково.

Я что-то здесь упускаю? Есть ли другие шаги, которые я должен предпринять, чтобы правильно настроить перспективную проекцию? Или я неправильно понимаю, как glFrustum работает? Я также пытался использовать gluPerspective вместо glFrustum но я не могу найти правильные значения для использования. Я экспериментировал с полем зрения 90, аспектом 1 и различными значениями z, но все они либо не производят чайник, либо чайник искажается до неузнаваемости. Кроме того, gluPerspective похоже, имеет другое поведение, чем glFrustum вызов с соответствующими параметрами. Я не уверен, что мне здесь не хватает.

1

Решение

В ортогональной проекции координаты в пространстве вида линейно отображаются на координаты пространства отсечения, а координаты пространства отсчета равны нормализованным координатам устройства, поскольку w Компонент равен 1 (для декартовой входной координаты).
Значения слева, справа, снизу, сверху, близко и далеко определяют поле. Вся геометрия, которая находится внутри объема окна, «видна» в окне просмотра.

Матрица ортогональной проекции, определяемая glOrtho является:

r = right, l = left, b = bottom, t = top, n = near, f = far

x:  2/(r-l)         0               0               0
y:  0               2/(t-b)         0               0
z:  0               0               -2/(f-n)        0
t:  -(r+l)/(r-l)    -(t+b)/(t-b)    -(f+n)/(f-n)    1

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

Матрица перспективной проекции может быть определена усечением (glFrustum).
Расстояния left, right, bottom а также top, — расстояния от центра вида до боковых граней усеченного конуса в ближней плоскости. near а также far Укажите расстояния до ближней и дальней плоскости на усеченном конусе.

r = right, l = left, b = bottom, t = top, n = near, f = far

x:  2*n/(r-l)      0              0                0
y:  0              2*n/(t-b)      0                0
z:  (r+l)/(r-l)    (t+b)/(t-b)    -(f+n)/(f-n)    -1
t:  0              0              -2*f*n/(f-n)     0

Спецификация, как это от вас вопрос:

glFrustum(-1, 1, -1, 1, -1, 1);

не определяет правильный усеченный, потому что значение для ближней плоскости является отрицательным, а значение для дальней плоскости положительным.

Если вы будете проверять наличие ошибок OpenGL (по glGetError), тогда вы получите INVALID_OPERATION ошибка.

Спецификация профиля совместимости API OpenGL 4.6; 12.1. ФИКСИРОВАННЫЕ ФУНКЦИОНАЛЬНЫЕ ПРЕОБРАЗОВАНИЯ VERTEX; страница 501:
>

void Frustum( double l, double r, double b, double t, double n, double f );

координаты (l b −n) Т а (r t −n) T указывает точки на ближней плоскости отсечения, которые отображаются в нижний левый и верхний правый углы окна соответственно (при условии, что глаз расположен в точке (0 0 0) T). f дает расстояние от глаза до дальней плоскости отсечения.

ошибки
Ошибка INVALID_VALUE генерируется, если n <= 0, f <= 0, l == r, b == t, или же n == f,

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]