Типичная матрица проекции OpenGL (то, что вы получаете из glFrustum или gluPerspective) помещает точку камеры в исходную точку. Плоскость проекции в (0, 0, -1): один блок перед камерой.
Таким образом, для данной вершины вам нужно найти позиции X и Y, которые вы получите для проекции на плоскость (0, 0, -1). Технически это «трассировка лучей», но, поскольку это плоскость, выровненная по оси, а камера находится в начале координат, на самом деле это простая арифметика:
vec3 newPosition = oldPosition * (-1.0 / oldPosition.z);
Обратите внимание, что интерполяционные параметры в этой перспективной проекции будут линейными в окне пространстве, а не в пространстве глаза / камеры. То есть перспективной правильной интерполяции не будет .
Также обратите внимание, что вышеприведенная «простая арифметика» не учитывает 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.
Возможно, вы захотите отключить тесты глубины во время орфографической визуализации, если у вас есть орто-объекты, которые перекрывают перспективные.