title: Lighting and OpenGL ES
body: <p>I'm working on getting a simple lighting right on my OpenGL ES iPhone scene. I'm displaying a simple object centered on the origin, and using an arcball to rotate it by touching the screen. All this works nicely, except I try to add one fixed light (fixed w.r.t. eye position) and it is badly screwed: the whole object (an icosahedron in this example) is lit uniformly, i.e. it all appears in the same color.</p>
  
  <p>I have simplified my code as much as possible so it's standalone and still reproduces what I experience:</p>
  
  <pre><code>    glClearColor (0.25, 0.25, 0.25, 1.);
      glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glEnable (GL_DEPTH_TEST);
  
      glEnable(GL_LIGHTING);
  
      glMatrixMode (GL_PROJECTION);
      glLoadIdentity ();
      glOrthof(-1, 1, -(float)backingWidth/backingHeight, (float)backingWidth/backingHeight, -10, 10);
  
      glMatrixMode (GL_MODELVIEW);
      glLoadIdentity ();
  
      GLfloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
      GLfloat diffuseLight[] = { 0.8f, 0.8f, 0.8, 1.0f };
      GLfloat specularLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
      GLfloat position[] = { -1.5f, 1.0f, -400.0f, 0.0f };
  
      glEnable(GL_LIGHT0);
      glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
      glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
      glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
      glLightfv(GL_LIGHT0, GL_POSITION, position);
  
      glShadeModel(GL_SMOOTH);
      glEnable(GL_NORMALIZE);
  
      float currRot[4];
      [arcball getCurrentRotation:currRot];
      glRotatef (currRot[0], currRot[1], currRot[2], currRot[3]);
  
      float f[4];
      f[0] = 0.5; f[1] = 0; f[2] = 0; f[3] = 1;
      glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, f);
      glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, f);
  
      f[0] = 0.2;     f[1] = 0.2; f[2] = 0.2; f[3] = 1;
      glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, f);
  
      glEnableClientState (GL_VERTEX_ARRAY);
      drawSphere(0, 0, 0, 1);
  </code></pre>
  
  <p>where the drawSphere function actually draws an icosahedron:</p>
  
  <pre><code>static void drawSphere (float x, float y, float z, float rad)
  { 
      glPushMatrix ();
      glTranslatef (x, y, z);
      glScalef (rad, rad, rad);
  
      // Icosahedron
      const float vertices[] =
      { 0., 0., -1., 0., 0., 1., -0.894427, 0., -0.447214, 0.894427, 0.,
              0.447214, 0.723607, -0.525731, -0.447214, 0.723607, 0.525731,
              -0.447214, -0.723607, -0.525731, 0.447214, -0.723607, 0.525731,
              0.447214, -0.276393, -0.850651, -0.447214, -0.276393, 0.850651,
              -0.447214, 0.276393, -0.850651, 0.447214, 0.276393, 0.850651,
              0.447214 };
      const GLubyte indices[] =
      { 1, 11, 7, 1, 7, 6, 1, 6, 10, 1, 10, 3, 1, 3, 11, 4, 8, 0, 5, 4, 0,
              9, 5, 0, 2, 9, 0, 8, 2, 0, 11, 9, 7, 7, 2, 6, 6, 8, 10, 10, 4, 3,
              3, 5, 11, 4, 10, 8, 5, 3, 4, 9, 11, 5, 2, 7, 9, 8, 6, 2 };
  
      glVertexPointer (3, GL_FLOAT, 0, vertices);
      glDrawElements (GL_TRIANGLES, sizeof(indices)/sizeof(indices[0]), GL_UNSIGNED_BYTE, indices);
      glPopMatrix ();
  }
  </code></pre>
  
  <p>A movie of what I see as the result is <a href="http://quatramaran.ens.fr/~coudert/tmp/ScreenFlow.mov" rel="nofollow noreferrer">here</a>. Thanks to anyone who can shed some light into this (no kidding!). I'm sure it will look embarassingly trivial to someone, but I swear I have looked at many lighting tutorials before this and am stuck.</p>