Question

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.

I have simplified my code as much as possible so it's standalone and still reproduces what I experience:

    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);

where the drawSphere function actually draws an icosahedron:

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 ();
}

A movie of what I see as the result is here. 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.

Was it helpful?

Solution

Try adding some vertex normals using glNormalPointer(). It looks like OpenGL ES is just using the default normal for everything.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top