Почему моя матрица перевода должна быть транспонирована?

Я работаю над небольшим графическим движком, использующим OpenGL, и у меня есть некоторые проблемы с моей матрицей перевода. Я использую OpenGL 3.3, GLSL и C ++.
Ситуация такова: я определил небольшой куб, который я хочу визуализировать на экране. Куб использует свою собственную систему координат, поэтому я создал матрицу модели, чтобы иметь возможность преобразовывать куб. Чтобы сделать это немного проще, я начал с матрицы перевода в качестве матрицы модели куба, и после небольшого кода мне удалось заставить все работать, и куб появился на экране. Ничего особенного, но есть одна вещь в моей матрице перевода, которая мне кажется немного странной.

Теперь, насколько мне известно, матрица перевода определяется следующим образом:

1, 0, 0, x
0, 1, 0, y
0, 0, 1, z
0, 0, 0, 1

Тем не менее, это не работает для меня. Когда я определяю свою матрицу перевода таким образом, на экране ничего не появляется. Это работает только тогда, когда я определяю свою матрицу перевода следующим образом:

1, 0, 0, 0
0, 1, 0, 0
0, 0, 1, 0
x, y, z, 1

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

Мои матрицы определены как одномерный массив, идущий слева направо, сверху вниз.

Вот часть моего кода, который может помочь:

//this is called just before cube is being rendered
void DisplayObject::updateMatrices()
{
modelMatrix = identityMatrix();
modelMatrix = modelMatrix * translateMatrix( xPos, yPos, zPos );

/* update modelview-projection matrix */
mvpMatrix = modelMatrix * (*projMatrix);
}

//this creates my translation matrix which causes the cube to disappear
const Matrix4 translateMatrix( float x, float y, float z )
{
Matrix4 tranMatrix = identityMatrix();

tranMatrix.data[3]  = x;
tranMatrix.data[7]  = y;
tranMatrix.data[11] = z;

return Matrix4(tranMatrix);
}

Это мой простой тестовый вершинный шейдер:

#version 150 core

in vec3 vPos;

uniform mat4 mvpMatrix;

void main()
{
gl_Position = mvpMatrix * vec4(vPos, 1.0);
}

Я также сделал тесты, чтобы проверить, работает ли мое умножение матриц, и это работает.
Я * randomMatrix все еще просто randomMatrix

Я надеюсь, что вы, ребята, можете помочь.
Спасибо

РЕДАКТИРОВАТЬ:

Вот как я отправляю данные матрицы в OpenGL:

void DisplayObject::render()
{
updateMatrices();

glBindVertexArray(vaoID);
glUseProgram(progID);
glUniformMatrix4fv( glGetUniformLocation(progID, "mvpMatrix"), 1, GL_FALSE, &mvpMatrix.data[0] );
glDrawElements(GL_TRIANGLES, bufferSize[index], GL_UNSIGNED_INT, 0);
}

mvpMatrix.data является std :: vector:

24

Решение

Для OpenGL

1, 0, 0, 0
0, 1, 0, 0
0, 0, 1, 0
x, y, z, 1

Это правильная матрица перевода.
Зачем? Opengl использует столбцам упорядочение матрицы. Что такое транспонирование матрицы, которую вы изначально представили, рядные основнымы упорядоченность. Основные строки используются в большинстве учебников по математике, а также в DirectX, так что это обычная путаница для новичков в OpenGL.

Увидеть: http://www.mindcontrol.org/~hplus/graphics/matrix-layout.html

30

Другие решения

Вы не можете поменять местами матрицы при умножении матриц, поэтому A * B отличается от B * A. Вы должны транспонировать B, прежде чем поменять местами матрицы.

A * B = t(B) * A

пытаться

void DisplayObject::updateMatrices()
{
modelMatrix = identityMatrix();
modelMatrix = translateMatrix( xPos, yPos, zPos ) * modelMatrix;

/* update modelview-projection matrix */
mvpMatrix = modelMatrix * (*projMatrix);
}
3

По вопросам рекламы [email protected]