Сначала немного фона.В трехмерной графике вам нужно беспокоиться о нескольких векторных пространствах:
- Пространство модели - обычно это координаты, которые вы указываете для OpenGL
- Мировое пространство - координаты задаются относительно некоторыхцентральная точка в мире.
- Просмотр пространства - координаты задаются относительно камеры
- Пространство проекции - все на экране помещается в интервале
[-1, +1]
в каждом измерении.
Координаты задаются однородно, поэтому каждый вектор имеет компоненты (x, y, z, w)
, где w
- коэффициент масштабирования.Вы можете получить координаты в 3-пространстве как (x/w, y/w, z/w)
.Коэффициент масштабирования необходим для определенных преобразований, таких как перспективная проекция, которая была бы невозможна при неоднородных координатах. Матрицы
4x4 необходимы для преобразования координат из одного векторного пространства в другое.У вас может быть три разных матрицы:
- Матрица модели (модель для мира)
- Матрица вида (мир для просмотра)
- Матрица проекции (вид на пространство проекции)
Вы бы проецировали координаты C
на экран по формуле:
C' = P * V * M * C
OpenGL поддерживает две матрицы: вид модели (модель и вид, умноженные вместе) и проекция,Существует также матрица текстур, о которой мы не будем беспокоиться.Когда вы звоните glMatrixMode
, вы переключаетесь между этими матрицами.Вы заменяете текущую матрицу единичной матрицей, используя glLoadIdentity
.Вы применяете преобразования к текущей матрице с помощью таких функций, как glTranslatef
, glRotatef
или gluProjection
.Каждая из этих функций просто создает матрицу 4x4, реализующую это конкретное преобразование, а затем умножает текущую матрицу на нее.Вы можете увидеть, что представляют собой матрицы преобразования на справочных страницах OpenGL 2.1 .
Теперь для фактического ответа.Вам необходимо поддерживать матрицу модели 4х4 для каждого объекта в вашей сцене.Матрица модели будет содержать все преобразования, необходимые для изменения координат модели в мировые координаты.Например, каждый раз, когда вы звоните glTranslate
, вы обновляете матрицу вашей модели:
T = [ 1 0 0 x ]
[ 0 1 0 y ]
[ 0 0 1 z ]
[ 0 0 0 1 ]
M' = M * T
Затем вы можете использовать матрицу модели, чтобы получить координаты в мировом пространстве (сначала убедитесь, что они являются однородными координатами; простоустановите w = 1
, если это не так):
V' = V * M
Поскольку вы поддерживаете эти преобразования параллельно, вам на самом деле больше не нужно поддерживать матрицу просмотра модели OpenGL.Вы можете передать свою матрицу модели как униформу своим шейдерам.Вы можете поддерживать свои собственные матрицы просмотра и проекции аналогичным образом.Это требуется в последних версиях OpenGL;все функции обработки матрицы устарели.