WorldViewProj = Proj * View * World
HPos = WorldViewProj * Pos
Я не араб, и меня этот способ начал со временем напрягать. Придётся переписывать всю матричную библиотеку - ошибки молодости :( Думаю через шаблоны сделать возможность указать, какая именно матрица собирается использоваться - row-major или column-major, и если идёт присваивание матриц с разным порядком записи, чтобы осуществлялось автоматическое траспонирование:
Mat4< column_major > m1 = GetWorldViewProj();
Mat4< row_major > m2( m1 ); // transpose
Важно не то как ты интерпретируешь матрицы (column-mаjor или row-major), а как ты хранишь элементы матрицы в памяти.
ОтветитьУдалитьВ памяти OpenGL COLUMN-MAJOR матрицы хранятся по столбцам (сначала первый столбец матрицы)
В памяти Direct3D ROW-MAJOR матрицы хранятся по строкам (сначала первая строка матрицы)
В любом случае в памяти массив элементов матрицы выглядит ОДИНАКОВО для OpenGL и для Direct3D.
Это удобно при использовании SSE инструкций (MULPS, ADDPS), оперирующих пакетно по 4 элемента сразу.
В GPU тоже можно использовать MUL и ADD (4 раза умножить пакетно и 3 раза сложить пакетно, 7 инструкций), но есть более удобная инструкция DP4 (и DPH), которая сразу делает 4 умножения и 3 сложения (что позволяет обойтись тремя-четырьмя инструкциями DP4 или DPH).
Ппоэтому перед использованием в GPU матрицы в любом случае придется транспонировать, хоть из OpenGL, хоть из Direct3D, т.к. они одинаково выглядят в памяти, а на GPU желательно иметь эти элементы в транспонированном виде.