Why does my color go away when I enable lighting in OpenGL?

dangerChihuahua007 picture dangerChihuahua007 · Dec 13, 2011 · Viewed 26.9k times · Source

I am developing a graphics application in C++ with the OpenGL API and GLUT.

To add lighting, I made the following changes in my modelview matrix:

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);

// Create light components.
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[] = { 0.0f, 0.0f, 0.0f, 1.0f };

// Assign created components to 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);

The lighting largely works I believe, but the colors of my objects all go away. All I see is a black/white silhouette of my overall figure.

I was wondering why this is?

Answer

Christian Rau picture Christian Rau · Dec 13, 2011

When lighting is enabled, a vertex' color is not determined from the color set by glColor or glColorPointer, but by the currently set material colors combined with the lights' colors using the lighting computations.

So in order to change an object's color, you need to change the material setting (which by default is a diffuse grey material) before rendering, using the glMaterial functions. There is essentially a corresponding material color for each of the different light colors (GL_DIFFUSE, ...) along with some additional properties to approximate light emitting materials (GL_EMISSION) and controlling the material's roughness (GL_SHININESS). Read some introductory material on OpenGL's lighting features to understand their workings.

What you can do to quickly adapt your code from plain coloring to lighting (or to enable per-vertex material properties) is to use color material. By calling glEnable(GL_COLOR_MATERIAL) and setting an appropriate mapping with glColorMaterial you can configure OpenGL to change a specific material color, whenever you change the current vertex color (using either glColor or glColorPointer).