1

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?
desertnaut
  • 57,590
  • 26
  • 140
  • 166
mjeshtri
  • 263
  • 1
  • 5
  • 15
  • There is no OpenGL code here. Can you show us minimal (but preferably complete) code that demonstrates the problem you're having? What matrix/vector classes are you using (they are defining the multiplication operators)? – metal Dec 13 '17 at 14:38
  • 1
    glm::mat2 and glm::vec2 as commented in the first line. Even the (\*) operator is from glm – mjeshtri Dec 13 '17 at 14:39
  • Did you _actually_ check the sizes of your vectors and matrices ? – Labonneguigue Dec 13 '17 at 14:43
  • Could you please define "output" a bit more specifically? Were you matrix printouts generated by using `ostream<<`, or by you inspecting the memory by hand? –  Dec 13 '17 at 14:45
  • glm != OpenGL. OpenGL is a widely supported and stable library. GLM hasn't even hit version 1.0. Is your question really about GLM then, not OpenGL? – metal Dec 13 '17 at 14:45
  • @metal you are right. I will edit the header. My mistake. – mjeshtri Dec 13 '17 at 14:51
  • @Frank I am printing the output using the to_string() method – mjeshtri Dec 13 '17 at 14:54

1 Answers1

2

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.

  • Thank you for the quick answer. If I understood you correctly testMat[0] will give the first column, not the first row as expected, right? – mjeshtri Dec 13 '17 at 14:53
  • @surveyCorps What do you mean by "as expected?" GLSL's documentation is pretty clear about this. https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Matrices –  Dec 13 '17 at 14:58
  • In C++, if I want to access the elements of the first row of a 3x3 matrix, I have to write matrix[0][0]; matrix[0][1]; matrix[0][2]. But in GLM to access the elements of the first row of a 3x3 matrix I have to write matrix[0][0]; matrix[1][0]; matrix[2][0]. Is this correct? – mjeshtri Dec 13 '17 at 15:02
  • 1
    @surveyCorps It's not correct in the sense that C++ arrays of arrays have no notion of rows or columns. matrix[n] is just "the n'th sub-array". There is no mathematical meaning attached, just a memory storage one. –  Dec 13 '17 at 15:05
  • true. Thank you! – mjeshtri Dec 13 '17 at 15:07