title: opengl rotate an object around fixed axes
body: <p>Hi I'm trying to implement a opengl program with rotation&amp;translation. But I got this problem that, the world axes will rotating along with my object(a cube). It's like, first I rotate cube along Z-axis, it works fine, then I middle-click the mouse and want to rotate the cube along the original Y-axis. At the moment I click, the cube will stop rotating along Z and start to rotate along Y. But it turns out it will rotate along a "new and invisible" Y-axis. I figure out that's because when I rotate the cube along Z with glRotatef(), the other two axis:X,Y also rotate. How can I fix the axes when I'm rotating the cube. I know the glRotatef() will multiply all matrix in screen with a rotation axis, so I tried added a  glLoadIdentity() in each rotation but it still not work. can anyone give me the solution? </p>
  
  <p>the code is here for reference:</p>
  
  <pre><code>#include &lt;stdlib.h&gt;
  #include &lt;GL/glut.h&gt;
  #include &lt;iostream&gt;
  
  
  
  GLfloat vertices[8][3] =
  { { -1.0, -1.0, -1.0 }, { 1.0, -1.0, -1.0 },
  { 1.0, 1.0, -1.0 }, { -1.0, 1.0, -1.0 }, { -1.0, -1.0, 1.0 },
  { 1.0, -1.0, 1.0 }, { 1.0, 1.0, 1.0 }, { -1.0, 1.0, 1.0 } };
  GLuint listName;
  
  GLfloat theta[3] = { 0.0, 0.0, 0.0 };
  GLint axis = 2;
  GLfloat delta = 0.02;
  GLint stop = 0;
  GLfloat distance = 0;
  
  void face(int a, int b, int c, int d)
  {
      glBegin(GL_POLYGON);
      //glColor3fv(colors[a]);
      glVertex3fv(vertices[a]);
      //glColor3fv(colors[b]);
      glVertex3fv(vertices[b]);
      //glColor3fv(colors[c]);
      glVertex3fv(vertices[c]);
      //glColor3fv(colors[d]);
      glVertex3fv(vertices[d]);
      glEnd();
  }
  
  void cube(void)
  {
      glColor3f(1.0f,1.0f,1.0f);
      face(0, 3, 2, 1);
      face(2, 3, 7, 6);
      face(0, 4, 7, 3);
      face(1, 2, 6, 5);
      face(4, 5, 6, 7);
      face(0, 1, 5, 4);
      glutWireCube(2.5f);
      glutPostRedisplay();
  }
  
  void drawAxis(void){
      // save previous matrix
      glPushMatrix();
      // clear matrix
      glLoadIdentity();
      // draw our axes
      glRotatef(45.0, 1.0, 0.0, 0.0);
      glRotatef(45.0, 0.0, -1.0, 0.0);
      glBegin(GL_LINES);
      // draw line for x axis
      glColor3f(1.0, 0.0, 0.0);
      glVertex3f(0.0, 0.0, 0.0);
      glVertex3f(10.0, 0.0, 0.0);
      // draw line for y axis
      glColor3f(0.0, 1.0, 0.0);
      glVertex3f(0.0, 0.0, 0.0);
      glVertex3f(0.0, 10.0, 0.0);
      // draw line for Z axis
      glColor3f(0.0, 0.0, 1.0);
      glVertex3f(0.0, 0.0, 0.0);
      glVertex3f(0.0, 0.0, 10.0);
      glEnd();
      // load the previous matrix
      glPopMatrix();
      glutPostRedisplay();
  }
  
  void spinCube()
  {
  
  
      theta[axis] += delta;
      if (theta[axis] &gt; 360.0) theta[axis] -= 360.0;
  
      glutPostRedisplay();
  }
  
  void display(void)
  {
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glLoadIdentity();
      glRotatef(45.0, 1.0, 0.0, 0.0);
      glRotatef(45.0, 0.0, -1.0, 0.0);
      drawAxis();
  
  
      glPushMatrix();
      glRotatef(theta[0], 1.0, 0.0, 0.0); 
      glRotatef(theta[1], 0.0, 1.0, 0.0);
      glRotatef(theta[2], 0.0, 0.0, 1.0);
      glTranslatef(0.0, 0.0, distance + 2.0);
      glCallList(listName);
      glPopMatrix();
  
      glutSwapBuffers();
  }
  
  void myReshape(int w, int h)
  {
      GLfloat aspect = (GLfloat) w / (GLfloat) h;
      glViewport(0, 0, w, h);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      if (w &lt;= h)
          glOrtho(-10.0, 10.0, -10.0 / aspect, 10.0 / aspect, -50.0, 50.0);
      else
          glOrtho(-10.0*aspect, 10.0*aspect, -10.0, 10.0, -50.0, 50.0);
      glMatrixMode(GL_MODELVIEW);
  }
  
  void mouse(int btn, int state, int x, int y)
  {
      if (btn == GLUT_LEFT_BUTTON &amp;&amp; state == GLUT_DOWN) { axis = 0; 
      }
      if (btn == GLUT_MIDDLE_BUTTON &amp;&amp; state == GLUT_DOWN) { axis = 1; 
      }
      if (btn == GLUT_RIGHT_BUTTON &amp;&amp; state == GLUT_DOWN) { axis = 2; 
      }
  }
  
  void keyboard(unsigned char key, int x, int y)
  {
      if (key == 'q' || key == 'Q') exit(0);
      if (key == ' ') { stop = !stop; }
      if (stop)
          glutIdleFunc(NULL);
      else
          glutIdleFunc(spinCube);
  }
  
  int main(int argc, char** argv)
  {
      glutInit(&amp;argc, argv);
      glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB);
  
      glutInitWindowSize(600, 600);
      glutCreateWindow("cube");
      glutReshapeFunc(myReshape);
  
      glutDisplayFunc(display);
      glutIdleFunc(spinCube);
  
      glutMouseFunc(mouse);
      glutKeyboardFunc(keyboard);
  
  
      //creating a display list:
      listName = glGenLists(1);
      glNewList(listName, GL_COMPILE);
      cube();
      glEndList();
  
  
      glEnable(GL_DEPTH_TEST);
      glutMainLoop();
      return 0;
  }
  </code></pre>