Search code examples
openglmatrixglm-mathmodel-view

openGL/glut & glm ModelView Matrix


I've been trying to use modelview matrix for one of my projects but for now I get a bit unexpected results, which blocks my further progress.

GameEntity::GameEntity{
   view_matrix = glm::lookAt(glm::vec3(0.f, 0.f, 0.f), glm::vec3(0.f, 0.f, 1.f), glm::vec3(0.f, -1.f, 0.f));
   //view_matrix = glm::mat4(1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0); //glLoadIdentity 
   //returns this matrix, since model_matrix is identity then this is clean view_matrix?
   model_matrix = glm::mat4(1.0f);
}

void GameEntity::Scale(glm::vec3 vector)
{
    model_matrix = glm::scale(model_matrix, vector);
}

void GameEntity::getMatrix(GLfloat arr[16])
{
    glm::mat4 modelview = view_matrix * model_matrix;
    for (int i = 0; i < 4; i++){
        arr[i] = modelview[i][0];
        arr[i+1] = modelview[i][1];
        arr[i+2] = modelview[i][2];
        arr[i+3] = modelview[i][3];
        }
}

and now the expected result is matrix (this is what I get from glLoadIdentity and glScale(0.3,0.3,1.0))

[ 0.3, 0.0, 0.0, 0.0 ]
[ 0.0, 0.0, 0.0, 0.0 ]
[ 0.0, 0.0, 0.0, 0.3 ]
[ 0.0, 0.0, 0.3, 0.0 ]

but instead after scaling I get matrix (right one is while using directly inputed view_matrix, GameEntity commented code)

[ 0.3, 0.0, 0.0, 0.0 ]    [ 0.3, 0.0, 0.0, 0.0 ]
[ 0.0, 0.0, 0.0, 0.0 ]    [ 0.0, 0.0, 0.0, 0.0 ]
[ 0.0, 0.0, 0.0, 0.0 ]    [ 0.0, 0.0, 0.0, 1.0 ]
[ 0.0, 0.0, 0.0, 1.0 ]    [ 0.0, 0.0, 1.0, 0.0 ]

With the 1st matrix I get a circle flattened to double line, with 2nd its stretched out on single axis. Any ideas what I'm doing wrong?


Solution

  • Your Get Matrix function is wrong. When you iterate through the loop, you're not skipping over the right amount of elements in arr, the first iteration is

        arr[0] = modelview[0][0];
        arr[1] = modelview[0][1];
        arr[2] = modelview[0][2];
        arr[3] = modelview[0][3];
    

    and the second goes

        arr[1] = modelview[1][0];
        arr[2] = modelview[1][1];
        arr[3] = modelview[1][2];
        arr[4] = modelview[1][3];
    

    and so on. You have to fix that by using

    for (int i = 0; i < 4; i++) {
        arr[4*i  ] = modelview[i][0];
        arr[4*i+1] = modelview[i][1];
        arr[4*i+2] = modelview[i][2];
        arr[4*i+3] = modelview[i][3];
    }
    

    BTW: Why are you bothering with a reference in your getMatrix prototype? Obviously you want to work with plain C arrays here, so just use pointers (or sized array function parameter types, which act like a pointer). void GameEntity::getMatrix(GLfloat arr[16]) works just as well and is much, much easier to read. And there's absolutely no benefit in using a pointer there.