Search code examples
c++openglmatrixglm-math

Compositing a transformation in glm and OpenGL


From Linear Algebra, if you have a translation matrix:

enter image description here

and a scaling matrix:

enter image description here
The net effect that we translate and scale is given by:

enter image description here

Now I just use VSCode to see how the translation is handled by glm for using these operations:

//my code
glm::mat4 modelMatrix(1.0f); 
modelMatrix = glm::translate(modelMatrix, glm::vec3(0.5, 0.5f, 0.5f));
modelMatrix = glm::scale(modelMatrix,glm::vec3(1.5, 1.5, 1.0));

the code for glm::translate is :

//glm code
template<typename T, qualifier Q>
    GLM_FUNC_QUALIFIER mat<4, 4, T, Q> translate(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v)
    {
        mat<4, 4, T, Q> Result(m);
        Result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
        return Result;
    }  

which is essentially altering the third column of the identity matrix and turning modelMatrix to the translation matrix T, but what is surprising is, it doesn't form the composite transformation matrix, instead it does this:

//glm code
  template<typename T, qualifier Q>
    GLM_FUNC_QUALIFIER mat<4, 4, T, Q> scale(mat<4, 4, T, Q> const& m, vec<3, T, Q> const& v)
    {
        mat<4, 4, T, Q> Result;
        Result[0] = m[0] * v[0];
        Result[1] = m[1] * v[1];
        Result[2] = m[2] * v[2];
        Result[3] = m[3];
        return Result;
    }  

which is essentially just scaling the columns of the transformation matrix like so:
(I've put the value of the translation matrix as shown in my code above):

enter image description here

Which is not the composite transformation matrix I expected it to be at all, which was from what I learned from the Linear Algebra theory:

enter image description here

What is going on here?


Solution

  • The matrix multiplication order is wrong. The example code calculates T * S instead of S * T. Matrix multiplications are not commutative, thus the result defers from your expectation.

    The following code should produce the result you need:

    glm::mat4 modelMatrix(1.0f); 
    modelMatrix = glm::scale(modelMatrix,glm::vec3(1.5, 1.5, 1.0));
    modelMatrix = glm::translate(modelMatrix, glm::vec3(0.5, 0.5f, 0.5f));