Почему необходимо перенести мою матрицу перевода?

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

Ответ 1

Для 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

Ответ 2

Вы не можете поменять матрицы матричным умножением, поэтому 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);
}