Brak Danych
Brak Danych

Reputation: 395

Drawing cubes with stacked matrix

I am trying to understand some parts of OpenGL. I have to create a robot, which is made from a few part. At start I want to draw 3 cubes in a row. At first I want to draw a cube in the middle, and after that the rest two.

Can you tell me what I did wrong?

void drawScene(GLFWwindow* window) {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


    mat4 P=perspective(50.0f*PI/180.0f,aspect,1.0f,50.0f);
    mat4 V=lookAt(
                  vec3(0.0f,0.0f,-15.0f),
                  vec3(0.0f,0.0f,0.0f),
                  vec3(0.0f,1.0f,0.0f));
    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(value_ptr(P));
    glMatrixMode(GL_MODELVIEW);

    mat4 M=mat4(1.0f);
    glLoadMatrixf(value_ptr(V*M));

    glPushMatrix();                         //create matrix 1 on the top
    Models::cube.drawSolid();               //draw cube on 0,0,0 coords
    glTranslatef(3.0, 0.0, 0.0);            //apply translation to matrix 1
    Models::cube.drawSolid();               //draw cube on 3,0,0 coords
    glPopMatrix();                          
    glRotatef(180*PI/180, 1.0, 0.0, 0.0);
    glTranslatef(3.0, 0.0, 0.0);
    Models::cube.drawSolid();

    glfwSwapBuffers(window);
}

And another example which is giving me the same wrong results:

void drawScene(GLFWwindow* window) {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


    mat4 P=perspective(50.0f*PI/180.0f,aspect,1.0f,50.0f);
    mat4 V=lookAt(
                  vec3(0.0f,0.0f,-15.0f),
                  vec3(0.0f,0.0f,0.0f),
                  vec3(0.0f,1.0f,0.0f));
    glMatrixMode(GL_PROJECTION);
    glLoadMatrixf(value_ptr(P));
    glMatrixMode(GL_MODELVIEW);

    mat4 M=mat4(1.0f);
    glLoadMatrixf(value_ptr(V*M));

    glPushMatrix(); //Matrix 1 on the top
    glPushMatrix(); //Matrix 2 on the top
    Models::cube.drawSolid(); //Draw cube on matrix 2
    glTranslatef(3.0, 0.0, 0.0); //Apply translation on matrix 2
    glPushMatrix(); //Matrix 3 on the top
    Models::cube.drawSolid(); //Draw cube on matrix 3
    glPopMatrix(); //Matrix 2 on the top
    glPopMatrix(); //Matrix 1 on the top
    glRotatef(180*PI/180, 1.0, 0.0, 0.0); //Apply translation on matrix 1
    glTranslatef(3.0, 0.0, 0.0); //Apply translation on matrix 1
    Models::cube.drawSolid(); //Draw cube on matrix 1

    glfwSwapBuffers(window);
}

In both cases I have to translate last cube for 6.0 instead of 3.0. I dont really understand why. It seems to me that after backing to matrix 1 I apply effect on them.

To be clear, I want to do something like this:

Draw Cube in 0,0,0
    []
go to 3,0,0 
Draw Cube
    []  []
Go back to 0,0,0
Rotate in 180 degrees
Go to -3,0,0
Draw Cube   
[]  []  []

Upvotes: 1

Views: 711

Answers (1)

Rabbid76
Rabbid76

Reputation: 210878

You want to draw a cube in the center, a second cube translated to the right and a third cube translated to the left (along the X-axis).
This can be done in different ways:


You can draw the cube in the center, go one step to the right and draw the next cube and finally go two steps to the left an draw the third cube:

float step = 3.0f;

Models::cube.drawSolid();
glTranslatef( 1.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();
glTranslatef( -2.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();


You can draw the cube in the center and save (push) the model matirx, go one step to the right and draw the next cube and finally restore (pop) the model matrix, go one steps to the left an draw the third cube:

glPushMatrix();  
Models::cube.drawSolid();
glTranslatef( 1.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();
glPopMatrix();                          
glTranslatef( -1.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();


Finally what you desided to do.
Draw the cube in the center and save (push) the model matirx, go one step to the right and draw the next cube and finally restore (pop) the model matrix, turn around 180° degrees, go one steps to the right an draw the third cube. But you have to rotate around the up vector, which is (0, 1, 0) in your case, and not around the X-axis:

enter image description here

glPushMatrix();  
Models::cube.drawSolid();
glTranslatef( 1.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();
glPopMatrix();                          
glRotatef( 180*PI/180, 0.0, 1.0f, 0.0f ); // rotate around the up vector
glTranslatef( 1.0f * step, 0.0f, 0.0f );
Models::cube.drawSolid();


By the way, in your 2nd example you push 3 matrices onto the stack, but you pop only 2 matrices. Each matrix which is put on the stack should also be taken down again. This means the number of glPushMatrix and glPopMatrixshould always be equal. Else you would either stack up without an end, or you would try to take something from the empty stack.

Upvotes: 1

Related Questions