Типичная матрица проекции OpenGL (которую вы получаете от glFrustum или gluPerspective) помещает точку камеры в начало координат. Плоскость проецирования находится в точке (0, 0, -1): одна единица перед камерой.
Итак, для данной вершины вам нужно найти позиции X и Y, которые вы получите для проекции на плоскость (0, 0, -1). Технически это «трассировка лучей», но поскольку это плоскость, выровненная по оси, а камера находится в начале координат, на самом деле это простая арифметика:
vec3 newPosition = oldPosition * (-1.0 / oldPosition.z);
Обратите внимание, что параметры интерполяции в этой перспективной проекции будут линейными в пространстве window, а не в пространстве глаза / камеры. То есть не будет правильной интерполяции перспективы.
Также обратите внимание, что приведенная выше «простая арифметика» не учитывает FOV. Чтобы справиться с этим, вам нужно преобразовать X и Y oldPosition
в левую верхнюю часть матрицы перспективы. Или просто извлеките значения 0,0 и 1,1 из матрицы проекции и умножьте их на X и Y oldPosition
. Это позаботится о масштабировании.
Еще одно замечание, поскольку вы не указали общую цель этого.
OpenGL не требует, чтобы вы визуализировали всю сцену с помощью одной матрицы проекции. Вы можете визуализировать часть сцены ортогонально, а для остальных использовать матрицу перспективы. Это часто делается в играх, где HUD и текстовые элементы отображаются ортографически, а сама игра находится в трехмерной перспективе.
Если это то, что вы делаете, все, что вам нужно сделать, это что-то вроде следующего:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(...);
glMatrixMode(GL_MODELVIEW);
//Render my perspective stuff here.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(...);
glMatrixMode(GL_MODELVIEW);
// Render my orthographic stuff here.
Вы можете отключить проверку глубины во время ортогонального рендеринга, если у вас есть ортообъекты, которые перекрывают перспективные.
person
Nicol Bolas
schedule
05.08.2011