OpenGL矩阵乘法C ++

时间:2015-03-23 12:57:58

标签: c++ opengl math matrix glsl

所以我试图将旋转和翻译矩阵相乘,我无法弄清楚出了什么问题。

如果在程序中我将一个平移矩阵乘以一个旋转矩阵,那么将该矩阵作为一个均匀的方式发送到我的着色器程序中我最终得到的对象变为2D然后再次3D,因为它旋转[https://a.pomf.se/xvvrsg.mp4](对象在右边。)

shader.setUniformMat4("model_matrix", Matrix4::translation(Vector3(10.0f, 0.0f, 0.0f)) * Matrix4::rotation(rotation, Vector3(0.0f, 1.0f, 0.0f)));

(顶点着色器)

#version 330 core

layout (location = 0) in vec4 in_position;
layout (location = 1) in vec4 in_normal;

uniform mat4 pr_matrix;
uniform mat4 vw_matrix = mat4(1.0);
uniform mat4 model_matrix = mat4(1.0);

out vec4 pos;
out vec4 normal;

void main()
{
    pos = pr_matrix * vw_matrix * model_matrix * in_position;

    normal = in_normal;
    gl_Position = pos;
}

但是,如果我将单独的平移和旋转矩阵作为单独的制服发送,然后在着色器中将它们相乘以创建我的模型矩阵,则按预期[https://a.pomf.se/jyxpnb.mp4](右侧的对象)工作。

shader.setUniformMat4("translation_matrix", Matrix4::translation(Vector3(10.0f, 0.0f, 0.0f)));
shader.setUniformMat4("rotation_matrix", Matrix4::rotation(rotation, Vector3(0.0f, 1.0f, 0.0f)));
shader.setUniformMat4("scale_matrix", Matrix4::identity());

(顶点着色器)

#version 330 core

layout (location = 0) in vec4 in_position;
layout (location = 1) in vec4 in_normal;

uniform mat4 pr_matrix;
uniform mat4 vw_matrix = mat4(1.0);
uniform mat4 translation_matrix = mat4(1.0);
uniform mat4 rotation_matrix = mat4(1.0);
uniform mat4 scale_matrix = mat4(1.0);

out vec4 pos;
out vec4 normal;

void main()
{
    mat4 model_matrix = translation_matrix * rotation_matrix * scale_matrix;
    pos = pr_matrix * vw_matrix * model_matrix * in_position;

    normal = in_normal;
    gl_Position = pos;
}

这让我相信我的矩阵乘法一定存在错误,这就是我目前正在做的事情:

        Matrix4 &Matrix4::multiply(const Matrix4 &other)
        {
            elements[0] = elements[0]  * other.elements[0]  + elements[4] * other.elements[1]  + elements[8]  * other.elements[2]  + elements[12] * other.elements[3];
            elements[1] = elements[1]  * other.elements[0]  + elements[5] * other.elements[1]  + elements[9]  * other.elements[2]  + elements[13] * other.elements[3];
            elements[2] = elements[2]  * other.elements[0]  + elements[6] * other.elements[1]  + elements[10] * other.elements[2]  + elements[14] * other.elements[3];
            elements[3] = elements[3]  * other.elements[0]  + elements[7] * other.elements[1]  + elements[11] * other.elements[2]  + elements[15] * other.elements[3];
            elements[4] = elements[0]  * other.elements[4]  + elements[4] * other.elements[5]  + elements[8]  * other.elements[6]  + elements[12] * other.elements[7];
            elements[5] = elements[1]  * other.elements[4]  + elements[5] * other.elements[5]  + elements[9]  * other.elements[6]  + elements[13] * other.elements[7];
            elements[6] = elements[2]  * other.elements[4]  + elements[6] * other.elements[5]  + elements[10] * other.elements[6]  + elements[14] * other.elements[7];
            elements[7] = elements[3]  * other.elements[4]  + elements[7] * other.elements[5]  + elements[11] * other.elements[6]  + elements[15] * other.elements[7];
            elements[8] = elements[0]  * other.elements[8]  + elements[4] * other.elements[9]  + elements[8]  * other.elements[10] + elements[12] * other.elements[11];
            elements[9] = elements[1]  * other.elements[8]  + elements[5] * other.elements[9]  + elements[9]  * other.elements[10] + elements[13] * other.elements[11];
            elements[10] = elements[2] * other.elements[8]  + elements[6] * other.elements[9]  + elements[10] * other.elements[10] + elements[14] * other.elements[11];
            elements[11] = elements[3] * other.elements[8]  + elements[7] * other.elements[9]  + elements[11] * other.elements[10] + elements[15] * other.elements[11];
            elements[12] = elements[0] * other.elements[12] + elements[4] * other.elements[13] + elements[8]  * other.elements[14] + elements[12] * other.elements[15];
            elements[13] = elements[1] * other.elements[12] + elements[5] * other.elements[13] + elements[9]  * other.elements[14] + elements[13] * other.elements[15];
            elements[14] = elements[2] * other.elements[12] + elements[6] * other.elements[13] + elements[10] * other.elements[14] + elements[14] * other.elements[15];
            elements[15] = elements[3] * other.elements[12] + elements[7] * other.elements[13] + elements[11] * other.elements[14] + elements[15] * other.elements[15];
            return *this;
        }

我确实有一个嵌套循环来执行此操作,但我最终写完了所有内容,同时试图找到这个问题的答案。请记住,矩阵是专业列,不会被OpenGL转换

旋转和翻译矩阵如下,但我不相信它们有任何问题:

        Matrix4 Matrix4::translation(const Vector3 &translation)
        {
            Matrix4 result(1.0f);
            result.elements[0 + 3 * 4] = translation.x;
            result.elements[1 + 3 * 4] = translation.y;
            result.elements[2 + 3 * 4] = translation.z;
            return result;
        }

        Matrix4 Matrix4::rotation(float angle, const Vector3 &axis)
        {
            Matrix4 result(1.0f);
            float r = toRadians(angle);
            float c = (float)cos(r);
            float s = (float)sin(r);
            float cFlip = 1.0f - c;

            result.elements[0 + 0 * 4] = axis.x * cFlip + c;
            result.elements[1 + 0 * 4] = axis.y * axis.x * cFlip + axis.z * s;
            result.elements[2 + 0 * 4] = axis.x * axis.z * cFlip - axis.y * s;

            result.elements[0 + 1 * 4] = axis.x * axis.y * cFlip - axis.z * s;
            result.elements[1 + 1 * 4] = axis.y * cFlip + c;
            result.elements[2 + 1 * 4] = axis.y * axis.z * cFlip + axis.x * s;

            result.elements[0 + 2 * 4] = axis.x * axis.y * cFlip + axis.y * s;
            result.elements[1 + 2 * 4] = axis.y * axis.z * cFlip - axis.x * s;
            result.elements[2 + 2 * 4] = axis.z * cFlip + c;
            return result;
        }

关于这里可能存在的问题或如何解决问题的任何想法都将非常感激:^)

2 个答案:

答案 0 :(得分:1)

在你的乘法函数中,你写道:

elements[0] = elements[0]  * other.elements[0] ...
...

请注意,element[0]现在已实现其内容,然后执行:

elements[8] = elements[0]  * other.elements[8] ...

使用新值而不是原始值。我想,你想在做这个乘法之前制作原始矩阵的副本

答案 1 :(得分:0)

opssss !!我刚看到!!! 在multiply中,输出矩阵是第一个输入矩阵,因此最新的运算是用乘法矩阵的系数计算的! :

elements[0] = elements[0]  * .....
....       
elements[4] = elements[0]  * ..... /* here element[ 0 ] is the top left
                                      element of the multiplied matix */

此外,operator*不应该修改(也不返回)他的一个操作数,operator*=就在这里