title: OpenGL and gluLookAt function
body: <p>I have function moveCamera() that rotate camera around center sphere.</p>
  
  <pre><code>void moveCamera()
  {
      glLoadIdentity();
      int vec = ceil(theta / 3.1415);
      int y;
      if (vec%2)
          y = 1;
      else
          y = -1;
      gluLookAt(e_x, e_y, e_z, 0, 0, 0, 0, y, 0);
  }
  </code></pre>
  
  <p>This function is called inside display()</p>
  
  <pre><code>void display()
  {
      glClearColor(0, 0, 0, 1);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glLoadIdentity();
  
      moveCamera();
  
      glCallList(idList);
  
      GLfloat pos[] = {0, 0, 0, 1};
      glLightfv(GL_LIGHT0, GL_POSITION, pos);
  
      glFinish();
  }
  </code></pre>
  
  <p>In this situation all works fine. But I noticed some things, that I cannot explain.</p>
  
  <p>For example, if I modify display() function for drawing red line in the direction X-axis like this</p>
  
  <pre><code>void display()
  {
      glClearColor(0, 0, 0, 1);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glLoadIdentity();
  
      glColor3ub(255, 0, 0);
      glLineWidth(5);
      glBegin(GL_LINES);
          glVertex3i(0, 0, 0);
          glVertex3i(1000, 0, 0);
      glEnd();
  
      moveCamera();
  
      glCallList(idList);
  
      GLfloat pos[] = {0, 0, 0, 1};
      glLightfv(GL_LIGHT0, GL_POSITION, pos);
  
      glFinish();
  }
  </code></pre>
  
  <p>... nothing happened. Why???</p>
  
  <p>Another, if I remove glLoadIdentity() after glClear() the red line will draw, but when I move the camera by keyboard buttons, I see some bug in rendering this line (the line change their coordinates for drawing). For see it, run my code.</p>
  
  <p>The full code:</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include &lt;glut.h&gt;
  #include &lt;math.h&gt;
  #include &lt;QDebug&gt;
  using namespace std;
  
  #define WIDTH 1024
  #define HEIGHT 600
  
  void display();
  void reshape(int width, int height);
  void keyboard(unsigned char key, int x, int y);
  void moveCamera();
  void init();
  void mkList();
  void enableLight();
  //double z(const double &amp;x, const double &amp;y);
  void printMatrix(double *m)
  {
      for (int i = 0; i &lt; 4; i++)
          qDebug() &lt;&lt; QString("%1   %2   %3   %4").arg(m[i*4]).arg(m[i*4+1]).arg(m[i*4+2]).arg(m[i*4+3]);
      qDebug() &lt;&lt; "\n";
  }
  
  GLuint idList = 0;
  
  double e_x = 0;
  double e_y = 0;
  double e_z = 0;
  double r = 300;
  double phi = 0;
  double theta = 1.5;
  
  int main(int argc, char **argv)
  {
      glutInit(&amp;argc, argv);
      glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH);
      glutInitWindowSize(WIDTH, HEIGHT);
      glutInitWindowPosition(30, 100);
      glutCreateWindow("Lab#2");
      glutDisplayFunc(display);
      glutReshapeFunc(reshape);
      glutKeyboardFunc(keyboard);
  
      glEnable(GL_DEPTH_TEST);
      init();
      mkList();
      enableLight();
  
      glutMainLoop();
      return 0;
  }
  
  void display()
  {
      glClearColor(0, 0, 0, 1);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glLoadIdentity();
  
      glColor3ub(255, 0, 0);
      glLineWidth(5);
      glBegin(GL_LINES);
          glVertex3i(0, 0, 0);
          glVertex3i(1000, 0, 0);
      glEnd();
  
      moveCamera();
  
      glCallList(idList);
  
      GLfloat pos[] = {0, 0, 0, 1};
      glLightfv(GL_LIGHT0, GL_POSITION, pos);
  
      glFinish();
  }
  
  void reshape(int width, int height)
  {
      glViewport(0, 0, width, height);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective(45, 2, 100, 2000);
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
  }
  
  void keyboard(unsigned char key, int x, int y)
  {
  #define ESCAPE '\033'
  
      switch (key)
      {
      case ESCAPE:
          exit(0);
          break;
      case 's':
          theta += 0.1;
          break;
      case 'w':
          theta -= 0.1;
          break;
      case 'a':
          phi += 0.1;
          break;
      case 'd':
          phi -= 0.1;
          break;
      case 'q':
          r-=5;
          break;
      case 'e':
          r+=5;
          break;
      default:
          break;
      }
      e_x = r * sin(theta) * cos(phi);
      e_z = r * sin(theta) * sin(phi);
      e_y = r * cos(theta);
      glutPostRedisplay();
  }
  
  void moveCamera()
  {
      glLoadIdentity();
      int vec = ceil(theta / 3.1415);
      int y;
      if (vec%2)
          y = 1;
      else
          y = -1;
      gluLookAt(e_x, e_y, e_z, 0, 0, 0, 0, y, 0);
  }
  
  void init()
  {
      e_x = r * sin(theta) * cos(phi);
      e_z = r * sin(theta) * sin(phi);
      e_y = r * cos(theta);
  }
  
  void mkList()
  {
      int idInnerList = glGenLists(1);
      glNewList(idInnerList, GL_COMPILE);
  
      glColor3ub(255, 0, 0);
      glPushMatrix();
      glTranslatef(-200, 0, 0);
      glutWireSphere(50, 10, 10);
      glPopMatrix();
  
      glColor3ub(0, 255, 0);
      glPushMatrix();
      glTranslatef(200, 0, 0);
      glutSolidCube(100);
      glPopMatrix();
  
      glEndList();
  
      idList = glGenLists(1);
      glNewList(idList, GL_COMPILE);
      glCallList(idInnerList);
  
      glPushMatrix();
      glTranslatef(0, 0, 200);
      glCallList(idInnerList);
      glPopMatrix();
  
      glPushMatrix();
      glTranslatef(0, 0, -200);
      glCallList(idInnerList);
      glPopMatrix();
      glEndList();
  }
  
  void enableLight()
  {
      glEnable(GL_LIGHTING);
  
      glEnable(GL_COLOR_MATERIAL);
      glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
  
      GLfloat diffuse[] = {0.7, 0.7, 0.7, 1};
  
      glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
  
      glEnable(GL_LIGHT0);
  }
  </code></pre>