0
votes

For context, I've been learning OpenGL, and got to perspective projections. Spent a solid hour trying to figure out why my triangular pyramid wasn't showing up right, until I noticed one of my matrix multiplications (performed using operator* for glm::mat4) was giving me incorrect results. Tried multiplying two matrices with the same values, outside of that context, and sure enough, the result was still incorrect.

The two matrices I tried to multiply were:

glm::mat4 left, right;
left[0][0] = 2.09928f; left[0][1] = 0.0f; left[0][2] = 0.0f; left[0][3] = 0.0f; 
left[1][0] = 0.0f; left[1][1] = 3.73205f; left[1][2] = 0.0f; left[1][3] = 0.0f; 
left[2][0] = 0.0f; left[2][1] = 0.0f; left[2][2] = 1.0202f; left[2][3] = -2.0202f;
left[3][0] = 0.0f; left[3][1] = 0.0f; left[3][2] = 1.0f; left[3][3] = 0.0f;

right[0][0] = 0.999998f; right[0][1] = 0.0f; right[0][2] = -0.00174533f; right[0][3] = 0.0f; 
right[1][0] = 0.0f; right[1][1] = 1.0f; right[1][2] = 0.0f; right[1][3] = 0.0f; 
right[2][0] = 0.00174533f; right[2][1] = 0.0f; right[2][2] = 0.999998f; right[2][3] = 5.0f; 
right[3][0] = 0.0f; right[3][1] = 0.0f; right[3][2] = 0.0f; right[3][3] = 1.0f;

Using left * right, I get:

       2.09928,       0, -0.00178059, 0.00352592 
             0, 3.73205,           0,          0 
    0.00366393,       0,      6.0202,    -2.0202 
             0,       0,           1,          0 

which is incorrect. On the other hand, with this multiplication algorithm:

inline glm::mat4 Multiply(const glm::mat4& left, const glm::mat4 right)
{
    glm::mat4 ret;

    for (unsigned int i = 0; i < 4; i++) {
        for (unsigned int j = 0; j < 4; j++) {
            ret[i][j] = left[i][0] * right[0][j] +
                left[i][1] * right[1][j] +
                left[i][2] * right[2][j] +
                left[i][3] * right[3][j];
        }
    }

    return ret;
}

I get:

       2.09928,       0, -0.00366393,      0 
             0, 3.73205,           0,      0 
    0.00178059,       0,      1.0202,3.08081 
    0.00174533,       0,    0.999998,      5  

which is correct.

So, what am I doing wrong here?

Thanks in advance!

1

1 Answers

2
votes
       ret[i][j] = left[i][0] * right[0][j] +
            left[i][1] * right[1][j] +
            left[i][2] * right[2][j] +
            left[i][3] * right[3][j];

GLM uses column-major matrices. As such, left[0] is the first column. You are doing a dot-product between the column of the lhs matrix and the rows of the rhs matrix. That's backwards; it's row * column.

What you are probably doing wrong is building your matrices incorrectly, in row-major fashion.