Understanding glColorMaterial

Apprentice
Posts: 6
Joined: 2007.12
Post: #1
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.

http://homepage.mac.com/cianci66/UnLighted.jpg

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

Code:
- (void)prepareOpenGL {
    if(dataLoaded) {
        [self compileFluxSurfaces];
    }
    
    glLoadIdentity();
    glViewport(0, 0, [self bounds].size.width, [self bounds].size.height);
    
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-1.0*xScale, 1.0*xScale, -1.0*yScale, 1.0*yScale, 1.0, -1.0);
    
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    
    glShadeModel(GL_SMOOTH);
    
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glClearDepth(1.0);
    
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LEQUAL);
    
    glEnable(GL_LINE_SMOOTH);
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    
    glEnable(GL_LIGHTING);
    
    glEnable(GL_LIGHT0);
    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);
    
    glEnable(GL_COLOR_MATERIAL);
    glColorMaterial(GL_FRONT, GL_DIFFUSE);
    glColorMaterial(GL_FRONT, GL_AMBIENT);
    glColorMaterial(GL_FRONT, GL_SPECULAR);
    
    glLineWidth(1.0);
}

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.

Code:
- (void)drawFluxSurface:(int)flux from:(int)phiStart to:(int)phiStop {
    ...
    
    for(int phi = phiStart; phi < phiStop; phi++) {
        ...
        
        glBegin(GL_QUAD_STRIP);
        
        for(int theta = 1; theta <= NUM_PHI; theta++) {
            ...
            
            if(theta%2 == 1) {
                glNormal3d((z2-z1)*(y2-y1)-(y3-y1)*(z3-z1),
                           (y2-y1)*(x2-x1)-(x3-x1)*(y3-y1),
                           (x2-x1)*(z2-z1)-(z3-z1)*(x3-x1));
            }
            
            ...
                
            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));
            
        glEnd();
    }
}

However this is what gets rendered.

http://homepage.mac.com/cianci66/Lighted.jpg

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.
Quote this message in a reply
Member
Posts: 749
Joined: 2003.01
Post: #2
Yeah normals must be normalized or you get lighting proportionally stronger-weaker based on the length of the vector.

just use

glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT);
glColorMaterial(GL_FRONT_AND_BACK, GL_SPECULAR);

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)

©h€ck øut µy stuƒƒ åt ragdollsoft.com
New game in development Rubber Ninjas - Mac Games Downloads
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #3
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.
Quote this message in a reply
Apprentice
Posts: 6
Joined: 2007.12
Post: #4
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.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Understanding multisampled FBOs Coyote 12 8,423 Nov 27, 2009 01:01 AM
Last Post: arekkusu
  Minor issue with understanding ExitToShell 15 6,028 Jul 13, 2005 10:22 AM
Last Post: MattDiamond
  glTexImage2D() &amp; memory understanding... sealfin 4 3,396 Aug 7, 2004 03:15 PM
Last Post: OneSadCookie