Правильный формат матрицы OpenGL?

Мой вопрос просто: каков правильный формат для матрицы Projection и ModelView?

Мне сказали, что следующие примеры матриц транспонируются и не строятся, как должны выглядеть матрицы OpenGL.

ModelView Matrix
{(1, 0, 0, 0)
(0, 0.7071068, 0.7071068, 0)
(0, -0.7071068, 0.7071068, 0)
(0, -141.4214, -141.4214, 1)}

Projection Matrix
{(1.931371, 0, 0, 0)
(0, 2.414213, 0, 0)
(0, 0, -1.0002, -1)
(0, 0, -2.0002, 0)}

Ответ 1

Изменить: этот ответ серьезно нуждается в обновлении. А именно, нет никакого мнения о шейдерах.

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

Я оставляю этот ответ в качестве вики сообщества, если у кого-то есть время и будет его обновлять.


OpenGL определяет матрицы как одномерные массивы, перечисленные в основном порядке столбца, т.е. с элементами, упорядоченными так:

m0 m4 m8  m12
m1 m5 m9  m13
m2 m6 m10 m14
m3 m7 m11 m15

Итак, если вы инициализируете массив таким образом, на C или почти на любом другом языке, результирующая матрица будет выглядеть так, как будто она требует транспонирования, потому что код C сначала читает слева направо, а затем сверху вниз (в другие слова, как если бы они находились в строчном порядке):

int mat[16] = {
    0, 1, 2, 3,
    4, 5, 6, 7,
    8, 9, 10, 11,
    12, 13, 14, 15,
}

Кстати, OpenGL имеет glLoadTransposeMatrix и glMultTransposeMatrix, которые вы можете использовать вместо glLoadMatrix и glMultMatrix, поэтому это не должно быть проблемой.

Ответ 2

Вы можете использовать любую нотацию, которая вам нравится, если вы согласны с упорядочением операций с матрицей. Цитата из https://www.opengl.org/archives/resources/faq/technical/transformations.htm:

9.005 Являются ли матрицы OpenGL столбцами или строковыми?

В целях программирования матрицы OpenGL представляют собой 16-значные массивы с базовые векторы, выложенные смежно в памяти. Перевод компоненты занимают 13-й, 14-й и 15-й элементы 16-элементного матрица, где индексы пронумерованы от 1 до 16, как описано в раздел 2.11.2 спецификации OpenGL 2.1.

Колонка-майор и рядовая строка - это чисто условное обозначение. Заметка что пост-умножение с основными матрицами столбцов приводит к тому же результат как предварительное умножение на матрицы строк. OpenGL Спецификация и справочное руководство OpenGL используют колонок-майоров нотации. Вы можете использовать любые обозначения, если это четко указано.

то есть. в шейдере вы можете загрузить матрицы преобразования в виде массивов с плавающей запятой, упорядоченных столбцами, в равномерную и премножить вершину, чтобы преобразовать ее:

gl_Position = Proj * View * Model * vPosition;

или загрузите те же матрицы, что и массивы с плавающей запятой, упорядоченные по строкам и после умножения, чтобы добиться такого же эффекта:

gl_Position = vPosition * Model * View * Proj;

Транспортируя матрицу, вы эффективно ее преобразуете в другую запись, поэтому OpenGL имеет опции для транспонирования матриц по мере их ввода.