iDevGames Forums
Understanding glColorMaterial - Printable Version

+- iDevGames Forums (
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: Understanding glColorMaterial (/thread-2108.html)

Understanding glColorMaterial - PhysicsGuy - Nov 24, 2008 07:05 PM

As an excuse to learn OpenGL I wanted to create a program to plot in 3D the nested magnetic flux surfaces of our Stellarator experiment. So far I have been able to create and color them correctly. This is what it looks like without lighting.

The colors are important. They represent the strength of the magnetic field. I want to add some lighting so that the 3D structures are more distinct. I'm trying to use glColorMaterial to add some highlight on top of the colors. My code is

- (void)prepareOpenGL {
    if(dataLoaded) {
        [self compileFluxSurfaces];
    glViewport(0, 0, [self bounds].size.width, [self bounds].size.height);
    glOrtho(-1.0*xScale, 1.0*xScale, -1.0*yScale, 1.0*yScale, 1.0, -1.0);
    glClearColor(1.0, 1.0, 1.0, 0.0);
    float specular[] = {1.0, 1.0, 1.0, 0.1};
    glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
    float diffuse[] = {1.0, 1.0, 1.0, 0.01};
    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
    float ambient[] = {1.0, 1.0, 1.0, 0.1};
    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
    float position[] = {1.0, 1.0, 1.0, 1.0};
    glLightfv(GL_LIGHT0, GL_POSITION, position);
    glColorMaterial(GL_FRONT, GL_DIFFUSE);
    glColorMaterial(GL_FRONT, GL_AMBIENT);
    glColorMaterial(GL_FRONT, GL_SPECULAR);

The code to draw the surfaces striped down to just the OpenGL calls. Note that I'm converting from cylindrical coordinates to cartesian that's why my vertexes have z and y flipped.

- (void)drawFluxSurface:(int)flux from:(int)phiStart to:(int)phiStop {
    for(int phi = phiStart; phi < phiStop; phi++) {
        for(int theta = 1; theta <= NUM_PHI; theta++) {
            if(theta%2 == 1) {
            glColor4d(red, green, blue, 1.0);
            glVertex3d(x1, z1, y1);
            glColor4d(red, green, blue, 1.0);
            glVertex3d(x2, z2, y2);
        glColor4d(red, green, blue, 1.0);
        glVertex3d(r1*cos(phi1R), z1, r1*sin(phi1R));
        glColor4d(red, green, blue, 1.0);
        glVertex3d(r2*cos(phi2R), z2, r2*sin(phi2R));

However this is what gets rendered.

I have been playing around with it turning on and off various things. I have three conclusions.

1. glColorMaterial(GL_FRONT, GL_DIFFUSE) has no effect. If I set it up to have Diffuse light the only light all I get is black regardless of what value I set the light intensity too.

2. Using only specular light I get the color on the highlights and black everywhere else. This is what I would expect. When I turn on ambient the highlights become blown out. The light intensity appears to have no effect on how bright the model is.

3. Setting GL_FRONT or GL_BACK also seems to have no effect. I not sure if the vector in glnormal3d has to be normalized or not.

Am I using this correctly? I haven't found a tutorial on the web that really explains glColorMaterial aside from saying it's an alternative to setting glMaterial. Is there a way to control how bright the specular highlights are? Why aren't the diffuse lights working.

Understanding glColorMaterial - Najdorf - Nov 24, 2008 07:39 PM

Yeah normals must be normalized or you get lighting proportionally stronger-weaker based on the length of the vector.

just use


if you're not sure which side is the front

GL_SPECULAR values should be much lower than the diffuse light if i recall, if you're not using very high shininess (with glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess))

Your diffuse light alpha is way too low, much lower than your ambient light.

Also there's always some ambient light if you don't turn glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); to (0,0,0,1)

Also you usually keep the GL_SPECULAR value materials white (as specular light is intended to reflect light completely without the absorbing that causes colors to appear), so you don't call glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR), keeping the specular component to the white default and not affected by glColor4d (you can still change it with glMaterialfv)

Understanding glColorMaterial - TomorrowPlusX - Nov 25, 2008 09:27 AM

This may be beyond the scope of what you're doing, but in my experience, dropping glColor/glColorMaterial/etc in favor of GLSL and passing material properties as uniforms and attributes simplified my code greatly.

Understanding glColorMaterial - PhysicsGuy - Nov 25, 2008 06:25 PM

Najdorf Wrote:Yeah normals must be normalized or you get lighting proportionally stronger-weaker based on the length of the vector.

Thanks normalizing the vector fixed all the problems I was having.