Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding glPushMatrix() and glPopMatrix()

Tags:

opengl

I have the following code:

void drawObj1(){    
    glPushMatrix();
            glTranslatef(rBaseInitPos + (rBaseDim[0] / 2), rBaseDim[1] + baseIncrement + rBaseDim[1] / 2, rBaseDim[2] / 2);
            glRotatef(rBaseArmRotateAngle, 0, 1, 0);
            /*
                    glPushMatrix();
    */
            drawRobotBaseArm();
            /*
                    glPopMatrix();
    */
            glPushMatrix();
                glRotatef(90, 1, 0, 0);
                glEnable(GL_TEXTURE_2D);
                glBindTexture(GL_TEXTURE_2D, rCamouflage[0]);
                gluQuadricTexture(obj, GL_TRUE);
                gluQuadricDrawStyle(obj, GLU_FILL);
                gluDisk(obj, 0, (rBaseDim[0] / 2) - 0.5, 16, 4);
                gluCylinder(obj, (rBaseDim[0] / 2) - 0.5, (rBaseDim[0] / 2) - 0.5, rBaseDim[1] / 2, 16, 4);
                glDisable(GL_TEXTURE_2D);
            glPopMatrix();                      
        glPopMatrix();
    }


void drawScene(){
    glTranslatef(X, Y, Z);
    drawObj0();
    drawObj1();
}

With the above code, since there is one translation inside drawRobotBaseArm(); both the Diskand the Cylinder are also translated. Since I don't want that, I´ve uncomment the code up and down of drawRobotBaseArm();

Doing this, the following code:

glTranslatef(rBaseInitPos + (rBaseDim[0] / 2), rBaseDim[1] + baseIncrement + rBaseDim[1] / 2, rBaseDim[2] / 2);
glRotatef(rBaseArmRotateAngle, 0, 1, 0);

Only acts upon drawRobotBaseArm(); and now, the Diskand the Cylinder are not translated and rotated.

I can't seem to understand how glPushMatrix() and glPopMatrix() work. Any idea how can I achieve what I'm looking for?

like image 573
Favolas Avatar asked May 31 '14 15:05

Favolas


1 Answers

(Note that these functions are deprecated and removed in OpenGL 3.1+. Consider switching to a dedicated math library like GLM if you are working on a serious project.)

OpenGL keeps a stack of matrices to quickly apply and remove transformations. glPushMatrix copies the top matrix and pushes it onto the stack, while glPopMatrix pops the top matrix off the stack. All transformation functions (glScaled, etc.) function on the top matrix, and the top matrix is what all rendering commands use to transform their data.

By pushing and popping matrices, you can control what transformations apply to which objects, as well as apply transformations to groups of objects, and easily reverse the transformations so that they don't affect other objects.

An example:

glPushMatrix();          // Creates matrix 1 on the top
glTranslated(100, 0, 0); // Applies translation to matrix 1

drawSphere();            // Draws a sphere with translation <100, 0, 0>

glPushMatrix();          // Clones matrix 1 to create matrix 2 and pushes it on the top.
glScaled(2,2,2);         // Scales matrix 2; doesn't touch matrix 1

drawSphere();            // Draws a sphere with both translation <100, 0, 0> and scale <2,2,2>

glPopMatrix();           // Deletes matrix 2; matrix 1 becomes the top.

drawSphere();            // Same as the first sphere.

glPopMarix();            // Deletes matrix 1

In your example, doing glPush/PopMatrix around drawRobotBaseArm means that the transforms done by drawRobotBaseArm are reversed after it's called, so that they don't affect any other objects.

like image 126
Colonel Thirty Two Avatar answered Sep 17 '22 23:09

Colonel Thirty Two