Search code examples
c++matrix-multiplicationglm-math

Is GLM matrix multiplication Left or Right


I am having some confusion regarding matrix multiplication in GLM, using C++.

Yes, I know that

However, the output is confusing. I am posting the code for clarity.

//Initialize two empty 2dim vectors, and two empty 2x2 glm matrices
mat2 testMat (0.0f);
mat2 idMat(0.0f);
vec2 testVec (0.0f);
vec2 resultVec (0.0f);


//testVec: ( 1)
//         (-1)
testVec[0] = 1.0f;
testVec[1] = -1.0f;

// idMat: (1  0)
//        (0 -1)
idMat[0][0] = 1.0f;
idMat[1][1] = -1.0f;

// testMat: (2  3)
//          (4  5)
int blabla = 2;
for (int row = 0; row < testMat[0].length(); row++){
    for (int col = 0; col < testMat[0].length(); col++){
        testMat[row][col] = blabla;
        blabla += 1;
    }
}

//                     REAL RESULT   EXPECTED RESULT
// (2  3)      ( 1)       (-2)             (-1)
// (4  5)  *   (-1)   =   (-2)             (-1)
resultVec = testMat * testVec;


//                        REAL RESULT   EXPECTED RESULT
// (2  3)      (1   0)       ( 2  3)        (2  -3)
// (4  5)  *   (0  -1)   =   (-4 -5)        (4  -5)
mat2 resultMat = testMat * idMat;


//                        REAL RESULT   EXPECTED RESULT
// (2  3)      (1   0)       (2  -3)        ( 2   3)
// (4  5)  *   (0  -1)   =   (4  -5)        (-4  -5)
mat2 result2Mat = idMat * testMat;

I checked the library code that defined the (*) operator (for mat2 * mat2), and it seems that OpenGL is doing left-multiplication, i.e A multiply B is producing the result of (B * A).

Whereas the (*) operator (for mat2 * vec2) is multiplying the columns of the matrix with the vector elements instead of multiplying the rows of the matrix with the vector elements.

Question:

  1. Is the (*) operator behaving in this way because OpenGL matrices are column-major?

Solution

  • The following is wrong:

    testMat[row][col] = blabla;

    glm's [] operator on matrices returns a column, not a row. The math is fine, but you are initializing your matrix in a transposed manner.