Я работаю над небольшим графическим движком, использующим 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:
Для 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
Вы не можете поменять местами матрицы при умножении матриц, поэтому 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);
}