pushMatrix- PopMatrix

Hi there,
Can anyone help me understand the logics of using pushMatrix and popMatrix. Please tell how they are used as I am not able to understand’em.

Do you understand the Stack data Structure?
http://en.wikipedia.org/wiki/Stack_(data_structure)

Or what to do with it in OpenGL?

I am not able to understand that how to use pushMatrix/popMatrix in OpenGL. I am not able to conceive which matrix is being pushed??

The current matrix mode is being pushed or popped.

e.g.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glTranslatef();
glPopMatrix();

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glPushMatrix();
//do something
glPopMatrix();

Basically you have the projection matrix that define the projection distortion
Then the model view matrix that pose your object in the world.
Normally you do something like this.
glMatrixMode(GL_PROJECTION); // set camera parameters
glPerspective(someParameters);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLookAt(someParameters); // set camera position
glMultMatrix(obj1.matrix);
obj1.render();

now I want to draw another object in another position.
I can do this…
glLoadIdentity();
glLookAt(sameParameters than before);
glMultMatrix(obj2.matrix);
but this is ugly… you have to compute the camera matrix for every object. You can do something better.

glMatrixMode(GL_PROJECTION); // set camera parameters
glPerspective(someParameters);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLookAt(someParameters); // set camera position
glPushMatrix(); // save camera matrix
glMultMatrix(obj1.matrix);
obj1.render();
glPopMatrix(); // get camera matrix
glPushMatrix(); // save camera matrix
glMultMatrix(obj2.matrix);
obj2.render();
glPopMatrix(); // get camera matrix
glPush… etc… etc…

You can use the push/pop also with the other openGL matrix (projection, texture…)

Please see the below code and tell me how to use the push-popmatrix to get the finger at correct position, and make more like that with their correct rotation/revolution.

#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <GLUT/glut.h>

static int shoulder = 0, elbow = 0, finger = 0;
void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);
glShadeModel (GL_FLAT);
}
void display(void)
{
glClear (GL_COLOR_BUFFER_BIT);
glPushMatrix();
glTranslatef (-1.0, 0.0, 0.0);
glRotatef ((GLfloat) shoulder, 0.0, 0.0, 1.0);
glTranslatef (1.0, 0.0, 0.0);

glPushMatrix(); 
glScalef (2.0, 0.5, 1.0); 
glutWireCube (1.0); 
glPopMatrix(); 
glTranslatef (1.0, 0.0, 0.0); 
glRotatef ((GLfloat) elbow, 0.0, 0.0, 1.0); 
glTranslatef (1.0, 0.0, 0.0); 

glPushMatrix(); 
glScalef (2.0, 0.5, 1.0); 
glutWireCube (1.0); 
glPopMatrix(); 
glPushMatrix(); 
glTranslatef(1.6, 0.22, 0.0);
glRotatef ((GLfloat) finger, 0.0, 0.0, 1.0); 

glScalef (0.6, 0.1, 0.08); 
glutWireCube (1.0); 

glPopMatrix(); 
glPopMatrix(); 
glutSwapBuffers(); 

}
void reshape (int w, int h)
{
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
gluPerspective(65.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef (0.0, 0.0, -5.0);
}
void keyboard (unsigned char key, int x, int y) {
switch (key) {
case ‘s’: /* s key rotates at shoulder /
shoulder = (shoulder + 5) % 360;
glutPostRedisplay();
break;
case ‘S’:
shoulder = (shoulder - 5) % 360;
glutPostRedisplay();
break;
case ‘e’: /
e key rotates at elbow /
elbow = (elbow + 5) % 360;
glutPostRedisplay();
break;
case ‘E’:
elbow = (elbow - 5) % 360;
glutPostRedisplay();
break;
case ‘f’: /
f key rotates at finger */
finger = (finger + 5) % 360;
glutPostRedisplay();
break;
case ‘F’:
finger = (finger - 5) % 360;
glutPostRedisplay();
break;

	default: 
		break; 
} 

}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize (700, 500);
glutInitWindowPosition (100, 100);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMainLoop();
return 0;
}

I am still learning how to use Push and PopMatrix efficiently. By looking at other people’s code posted to this forum I’ve learned that I tend to use Push and PopMatrix more than I have to!

All I did to your code was add a second glTranslate just before glutWireCube, and tweak your first glTranslate accordingly.

  glPushMatrix ();
     glTranslatef (1.0, 0.22, 0.0);
     glRotatef ((GLfloat) finger, 0.0, 0.0, 1.0);
     glScalef (0.6, 0.1, 0.08);
     glTranslatef (0.5, 0.0, 0.0);
     glutWireCube (1.0);
  glPopMatrix ();