为什么我的翻译矩阵需要转置?

2021-12-19 00:00:00 opengl matrix linear-algebra c++ glsl

我正在使用 OpenGL 开发一个小型图形引擎,但我的翻译矩阵出现了一些问题.我正在使用 OpenGL 3.3、GLSL 和 C++.情况是这样的:我定义了一个小立方体,我想在屏幕上渲染它.立方体使用它自己的坐标系,所以我创建了一个模型矩阵来转换立方体.为了让自己更容易一点,我开始时只使用一个平移矩阵作为立方体的模型矩阵,经过一些编码后,我设法使一切正常,立方体出现在屏幕上.没什么特别的,但我觉得我的翻译矩阵有一点有点奇怪.

I'm working on a small graphics engine using OpenGL and I'm having some issues with my translation matrix. I'm using OpenGL 3.3, GLSL and C++. The situation is this: I have defined a small cube which I want to render on screen. The cube uses it's own coordinate system, so I created a model matrix to be able to transform the cube. To make it myself a bit easier I started out with just a translation matrix as the cube's model matrix and after a bit of coding I've managed to make everything work and the cube appears on the screen. Nothing all to special, but there is one thing about my translation matrix that I find a bit odd.

现在据我所知,一个平移矩阵的定义如下:

Now as far as I know, a translation matrix is defined as follows:

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

但是,这对我不起作用.当我以这种方式定义我的翻译矩阵时,屏幕上没有任何显示.它仅在我这样定义翻译矩阵时才有效:

However, this does not work for me. When I define my translation matrix this way, nothing appears on the screen. It only works when I define my translation matrix like this:

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

现在我已经多次检查我的代码以找出为什么会出现这种情况,但我似乎无法找出原因或者我只是错了,并且翻译矩阵是否需要像转置矩阵一样定义在上面吗?

Now I've been over my code several times to find out why this is the case, but I can't seem to find out why or am I just wrong and does a translation matrix needs to be defined like the transposed one here above?

我的矩阵被定义为一个从左到右、从上到下的一维数组.

My matrices are defined as a one-dimensional array going from left to right, top to bottom.

以下是我的一些可能有帮助的代码:

Here is some of my code that might help:

//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);
}

这是我的简单测试顶点着色器:

This is my simple test vertex shader:

#version 150 core

in vec3 vPos;

uniform mat4 mvpMatrix;

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

我还进行了测试以检查我的矩阵乘法是否有效并且确实如此.我 * randomMatrix 仍然只是 randomMatrix

I've also did tests to check if my matrix multiplication works and it does. I * randomMatrix is still just randomMatrix

希望大家帮帮忙.谢谢

这是我将矩阵数据发送到 OpenGL 的方式:

This is how I send the matrix data to 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:

mvpMatrix.data is a std::vector:

推荐答案

对于 OpenGL

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

是正确的翻译矩阵.为什么?Opengl 使用 column-major 矩阵排序.这是您最初呈现的矩阵的转置,按行优先排序.大多数数学教科书和 DirectX 中都使用了行专业,因此对于 OpenGL 新手来说,这是一个常见的困惑点.

Is the correct Translation Matrix. Why? Opengl Uses column-major matrix ordering. Which is the Transpose of the Matrix you initially presented, which is in row-major ordering. Row major is used in most math text-books and also DirectX, so it is a common point of confusion for those new to OpenGL.

参见:http://www.mindcontrol.org/~hplus/graphics/matrix-layout.html

相关文章