矩阵类乘法产生不正确的结果

时间:2015-01-07 14:02:38

标签: c++ opengl math matrix 3d

我为作业创建了一个基本数学库,包括Matrix3和Matrix4类,以及其他一些。对于OpenGL,为了将立方体投影到屏幕上,我已经为Projection * View * Model算法创建了一个lookAt函数和一个Perspective函数,可以为场景生成正确的视图。它们旨在替换GLM库/其他库中的相应函数,因为它们将来必须与我的Matrix类接口。

lookAt函数产生正确的结果,Projection函数产生了接近的结果,并通过一些临时的手动调整来使其提供相同的结果。但是,当我将它们与Projection * View(lookat)* Model(一个Identity矩阵)相乘时,我的库会产生与GLM(MVP Matrix4)完全不同的结果。我的配对与图形计算器,GLM一个没有。 GLM实际上正确地在屏幕上显示立方体,我看起来好像立方体已经内爆。矩阵本身几乎没有相似之处。

GLM图书馆

        // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
    glm::mat4 ProjectionGLM = glm::perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
    // Camera matrix
    glm::mat4 ViewGLM = glm::lookAt(
        glm::vec3(4, 3, 3), // Camera is at (4,3,3), in World Space
        glm::vec3(0, 0, 0), // and looks at the origin
        glm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down)
        );
    // Model matrix : an identity matrix (model will be at the origin)
    glm::mat4 ModelGLM = glm::mat4(1.0f);  // Changes for each model !
                                        // Our ModelViewProjection : multiplication of our 3 matrices
    glm::mat4 MVP = ProjectionGLM * ViewGLM * ModelGLM; // Remember, matrix multiplication is the other way around
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP[0][0]);

输出母系(MVP Matrix4)

自定义库

    Vector3 vectornew1(4, 3, 3);
    Vector3 vectornew2(0, 0, 0); 
    Vector3 vectornew3(0, 1, 0);

    // Projection matrix : 45° Field of View, 4:3 ratio, display range : 0.1 unit <-> 100 units
    Matrix4 Projection = Matrix4::Perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
    Projection = Matrix4::Transpose(Projection);
    // Camera matrix
    Matrix4 View = Matrix4::lookAt(
        vectornew1, // Camera is at (4,3,3), in World Space
        vectornew2, // and looks at the origin
        vectornew3  // Head is up (set to 0,-1,0 to look upside-down)
        );
    // Model matrix : an identity matrix (model will be at the origin)
    Matrix4 Model = Matrix4::Identity();  // Changes for each model !
                                        // Our ModelViewProjection : multiplication of our 3 matrices
    Matrix4 MVP = Projection * View * Model; // Remember, matrix multiplication is the other way around
    glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &MVP.data[0][0]);

自定义Matrix4乘法代码:

temp.data[0][0] = this->data[0][0] * Other.data[0][0] + this->data[0][1] * Other.data[1][0] + this->data[0][2] * Other.data[2][0] + this->data[0][3] * Other.data[3][0];
temp.data[0][1] = this->data[0][0] * Other.data[0][1] + this->data[0][1] * Other.data[1][1] + this->data[0][2] * Other.data[2][1] + this->data[0][3] * Other.data[3][1];
temp.data[0][2] = this->data[0][0] * Other.data[0][2] + this->data[0][1] * Other.data[1][2] + this->data[0][2] * Other.data[2][2] + this->data[0][3] * Other.data[3][2];
temp.data[0][3] = this->data[0][0] * Other.data[0][3] + this->data[0][1] * Other.data[1][3] + this->data[0][2] * Other.data[2][3] + this->data[0][3] * Other.data[3][3];

temp.data[1][0] = this->data[1][0] * Other.data[0][0] + this->data[1][1] * Other.data[1][0] + this->data[1][2] * Other.data[2][0] + this->data[1][3] * Other.data[3][0];
temp.data[1][1] = this->data[1][0] * Other.data[0][1] + this->data[1][1] * Other.data[1][1] + this->data[1][2] * Other.data[2][1] + this->data[1][3] * Other.data[3][1];
temp.data[1][2] = this->data[1][0] * Other.data[0][2] + this->data[1][1] * Other.data[1][2] + this->data[1][2] * Other.data[2][2] + this->data[1][3] * Other.data[3][2];
temp.data[1][3] = this->data[1][0] * Other.data[0][3] + this->data[1][1] * Other.data[1][3] + this->data[1][2] * Other.data[2][3] + this->data[1][3] * Other.data[3][3];

temp.data[2][0] = this->data[2][0] * Other.data[0][0] + this->data[2][1] * Other.data[1][0] + this->data[2][2] * Other.data[2][0] + this->data[2][3] * Other.data[3][0];
temp.data[2][1] = this->data[2][0] * Other.data[0][1] + this->data[2][1] * Other.data[1][1] + this->data[2][2] * Other.data[2][1] + this->data[2][3] * Other.data[3][1];
temp.data[2][2] = this->data[2][0] * Other.data[0][2] + this->data[2][1] * Other.data[1][2] + this->data[2][2] * Other.data[2][2] + this->data[2][3] * Other.data[3][2];
temp.data[2][3] = this->data[2][0] * Other.data[0][3] + this->data[2][1] * Other.data[1][3] + this->data[2][2] * Other.data[2][3] + this->data[2][3] * Other.data[3][3];

temp.data[3][0] = this->data[3][0] * Other.data[0][0] + this->data[3][1] * Other.data[1][0] + this->data[3][2] * Other.data[2][0] + this->data[3][3] * Other.data[3][0];
temp.data[3][1] = this->data[3][0] * Other.data[0][1] + this->data[3][1] * Other.data[1][1] + this->data[3][2] * Other.data[2][1] + this->data[3][3] * Other.data[3][1];
temp.data[3][2] = this->data[3][0] * Other.data[0][2] + this->data[3][1] * Other.data[1][2] + this->data[3][2] * Other.data[2][2] + this->data[3][3] * Other.data[3][2];
temp.data[3][3] = this->data[3][0] * Other.data[0][3] + this->data[3][1] * Other.data[1][3] + this->data[3][2] * Other.data[2][3] + this->data[3][3] * Other.data[3][3];

GLM在Matrix乘法中可以做些什么来产生截然不同的结果?我的方法与图形计算器相匹配,并使用单位矩阵产生正确的结果。

1 个答案:

答案 0 :(得分:0)

我尝试在我的引擎中进行乘法运算(也基于glm,或者至少对它进行测试),当我交换它和其他时,结果是正确的。所以这应该是正确的:

temp.data[0][0] = Other.data[0][0] * this->data[0][0] + Other.data[0][1] * this->data[1][0] + Other.data[0][2] * this->data[2][0] + Other.data[0][3] * this->data[3][0];
temp.data[0][1] = Other.data[0][0] * this->data[0][1] + Other.data[0][1] * this->data[1][1] + Other.data[0][2] * this->data[2][1] + Other.data[0][3] * this->data[3][1];
temp.data[0][2] = Other.data[0][0] * this->data[0][2] + Other.data[0][1] * this->data[1][2] + Other.data[0][2] * this->data[2][2] + Other.data[0][3] * this->data[3][2];
temp.data[0][3] = Other.data[0][0] * this->data[0][3] + Other.data[0][1] * this->data[1][3] + Other.data[0][2] * this->data[2][3] + Other.data[0][3] * this->data[3][3];
temp.data[1][0] = Other.data[1][0] * this->data[0][0] + Other.data[1][1] * this->data[1][0] + Other.data[1][2] * this->data[2][0] + Other.data[1][3] * this->data[3][0];
temp.data[1][1] = Other.data[1][0] * this->data[0][1] + Other.data[1][1] * this->data[1][1] + Other.data[1][2] * this->data[2][1] + Other.data[1][3] * this->data[3][1];
temp.data[1][2] = Other.data[1][0] * this->data[0][2] + Other.data[1][1] * this->data[1][2] + Other.data[1][2] * this->data[2][2] + Other.data[1][3] * this->data[3][2];
temp.data[1][3] = Other.data[1][0] * this->data[0][3] + Other.data[1][1] * this->data[1][3] + Other.data[1][2] * this->data[2][3] + Other.data[1][3] * this->data[3][3];
temp.data[2][0] = Other.data[2][0] * this->data[0][0] + Other.data[2][1] * this->data[1][0] + Other.data[2][2] * this->data[2][0] + Other.data[2][3] * this->data[3][0];
temp.data[2][1] = Other.data[2][0] * this->data[0][1] + Other.data[2][1] * this->data[1][1] + Other.data[2][2] * this->data[2][1] + Other.data[2][3] * this->data[3][1];
temp.data[2][2] = Other.data[2][0] * this->data[0][2] + Other.data[2][1] * this->data[1][2] + Other.data[2][2] * this->data[2][2] + Other.data[2][3] * this->data[3][2];
temp.data[2][3] = Other.data[2][0] * this->data[0][3] + Other.data[2][1] * this->data[1][3] + Other.data[2][2] * this->data[2][3] + Other.data[2][3] * this->data[3][3];
temp.data[3][0] = Other.data[3][0] * this->data[0][0] + Other.data[3][1] * this->data[1][0] + Other.data[3][2] * this->data[2][0] + Other.data[3][3] * this->data[3][0];
temp.data[3][1] = Other.data[3][0] * this->data[0][1] + Other.data[3][1] * this->data[1][1] + Other.data[3][2] * this->data[2][1] + Other.data[3][3] * this->data[3][1];
temp.data[3][2] = Other.data[3][0] * this->data[0][2] + Other.data[3][1] * this->data[1][2] + Other.data[3][2] * this->data[2][2] + Other.data[3][3] * this->data[3][2];
temp.data[3][3] = Other.data[3][0] * this->data[0][3] + Other.data[3][1] * this->data[1][3] + Other.data[3][2] * this->data[2][3] + Other.data[3][3] * this->data[3][3];