I have been learning OpenGL 3.3 and I saw this expression:

gl_Position = projection * view * model * vertex

I am confused because I read in some book that if the vector (vertex) is placed on the right side of the matrix then it would be a column vector and to transform this vector you should have a column major matrix.

But glm library follows GLSL right. So I printed the glm::mat4 and it was a row-major matrix.


There is no 100% consensus on what order matrix multiplication should model things, worse the industry is split along this. Some sources use row major and some sources use column major matrices. Great care should be taken to verify which is being used in your source and what is being used by your API!

Some API's go as far as allowing one to multiply vectors on both sides of the matrix. The wisdom is thus in reading your API reference and verifying how it works. Old, fixed pipeline OpenGL and glm, does in fact use column major matrices. While (warning) DirectX had chosen to use row major matrices [source]. Obviously with programmable shaders any application can have any order, even mixed one

Due to fundamental properties of matrices this duality is the same as transposing the matrix. If you transpose the matrix you reverse the order of calculation, as you are now thinking outside in instead of inside out or vice versa.

The moral of the story is that you should always check your assumptions. And just printing out values does not always help as the printing function can screw things up, and memory not aligned the same way. Also simple testing may make you blind to having mixed conventions inside your program. Read what convention is in use! Because, as confusing as having two sources with different conventions is, it pales in comparasion to a piece of software that mixes the two in the codebase.

| improve this answer | |

OpenGL uses column-major matrices. For example, the translation values will be in the last row rather than the last column of the matrix. For example when loading matrices into uniforms in glsl, the glUniformMatrix4fv() function takes its matrix parameters in column-major order:

Each matrix is assumed to be supplied in column major order.

In glm, the matrices are also in column-major order. From the matrix_transform.hpp header, the comment for the translate() method says this:

/// #include <glm/glm.hpp>
/// #include <glm/gtc/matrix_transform.hpp>
/// ...
/// glm::mat4 m = glm::translate(glm::mat4(1.0f), glm::vec3(1.0f));
/// // m[0][0] == 1.0f, m[0][1] == 0.0f, m[0][2] == 0.0f, m[0][3] == 0.0f
/// // m[1][0] == 0.0f, m[1][1] == 1.0f, m[1][2] == 0.0f, m[1][3] == 0.0f
/// // m[2][0] == 0.0f, m[2][1] == 0.0f, m[2][2] == 1.0f, m[2][3] == 0.0f
/// // m[3][0] == 1.0f, m[3][1] == 1.0f, m[3][2] == 1.0f, m[3][3] == 1.0f

Note that the translation amount (1,1,1) is in the last row rather than the last column.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.