OpenGL project, using tessellation on a polygon rendered car - opengl

Ok so im seperating my problem up because i need a depthy answer cos im nooby with it and will fail if i have just a generalisation answer.
I have a car body which i originally drew using line_loop and have changed it to polygon so i can texture it. however it ignores the wheel arches like so.
(ignore the texturing for now, i need to figure that one out another time ;) )
This is what my car looks like with line_loop
If the way to make the wheel arches with polygon makes it a smoother circle then even better :)
This is my current code, (ignore the texture stuff) I did start tessellation with a prod in that direction from an earlier question but not sure exactly how to use it and which coords to pass etc etc. Thanks for all your help!!
void drawBody(int textureindex)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureLib[textureindex]);
GLUtesselator *tess = gluNewTess(); // create a tessellator
if(!tess) return 0; // failed to create tessellation object, return 0
glBegin(GL_POLYGON);
glTexCoord2f(0.0F, 0.0F);
glVertex2f(-1.0f, 0.0f);
glTexCoord2f(-0.97, 0.0);
glVertex2f(-1.97f, 0.0f);
//wheel arch begin.
glTexCoord2f(-0.93, 0.3);
glVertex2f(-1.93f, 0.3f);
glTexCoord2f(-0.95, 0.4);
glVertex2f(-1.95f, 0.4f);
glTexCoord2f(-1.2, 0.6);
glVertex2f(-2.2f, 0.6f);
glTexCoord2f(-1.6, 0.6);
glVertex2f(-2.6f, 0.6f);
glTexCoord2f(-1.82, 0.4);
glVertex2f(-2.82f, 0.4f);
glTexCoord2f(-1.8, 0.3);
glVertex2f(-2.8f, 0.3f);
glTexCoord2f(-1.78, 0.0);
glVertex2f(-2.78f, 0.0f);
//end wheel arch.
//Front of car.
glTexCoord2f(0.0, 0.0);
glVertex2f(-3.8f, 0.0f);
glTexCoord2f(0.0, 0.2);
glVertex2f(-3.7f, 0.2f);
glTexCoord2f(0.0, 0.4);
glVertex2f(-3.8f, 0.4f);
glTexCoord2f(0.0, 0.7);
glVertex2f(-2.8f, 0.7f);
glTexCoord2f(0.0, 0.7);
glVertex2f(-2.4f, 0.7f);
//Windscreen.
glTexCoord2f(0.0, 1.0);
glVertex2f(-1.0f, 1.0f);
glTexCoord2f(1.0, 1.0);
glVertex2f(0.5f, 1.05f);
glTexCoord2f(1.0, 0.8);
glVertex2f(2.3f, 0.8f);
//rear bumper.
glTexCoord2f(1.0, 0.5);
glVertex2f(2.15f, 0.5f);
glTexCoord2f(1.0, 0.3);
glVertex2f(2.15f, 0.3f);
glTexCoord2f(1.0, 0.3);
glVertex2f(2.35f, 0.3f);
glTexCoord2f(1.0, 0.0);
glVertex2f(2.0f, 0.0f);
glTexCoord2f(1.0, 0.0);
glVertex2f(1.83f, 0.0f);
//wheel arch begin.
glTexCoord2f(1.0, 0.3);
glVertex2f(1.85f, 0.3f);
glTexCoord2f(1.0, 0.4);
glVertex2f(1.86f, 0.4f);
glTexCoord2f(1.0, 0.6);
glVertex2f(1.6f, 0.6f);
glTexCoord2f(1.0, 0.6);
glVertex2f(1.2f, 0.6f);
glTexCoord2f(1.0, 0.4);
glVertex2f(1.0f, 0.4f);
glTexCoord2f(1.0, 0.3);
glVertex2f(1.0f, 0.3f);
glTexCoord2f(1.0, 0.0);
glVertex2f(1.05f, 0.0f);
//end wheel arch.
glEnd();
glDisable(GL_TEXTURE_2D);
}
Revised code for tessellation, (only attempted on one wheel arch so far and has had no affect).
GLdouble car[7][2] = { {-1.93,0.3}, {-1.95,0.4}, {-2.2,0.6}, {-2.6,0.6}, {-2.82,0.4}, {-2.8,0.3}, {-2.78,0.0} };
GLUtesselator *tess = gluNewTess(); // create a tessellator
gluTessBeginPolygon(tess, 0);
gluTessBeginContour(tess);
{
gluTessVertex(tess, car[0], car[0]);
gluTessVertex(tess, car[1], car[1]);
gluTessVertex(tess, car[2], car[2]);
gluTessVertex(tess, car[3], car[3]);
gluTessVertex(tess, car[4], car[4]);
gluTessVertex(tess, car[5], car[5]);
gluTessVertex(tess, car[6], car[6]);
}
gluTessEndContour(tess);
gluTessEndPolygon(tess);
Thanks for all your help, the final image looks like this:
Again thanks for all your help! Especially PeterT :)

You are not using the tessellator at all. Feeding the coordinates to the tessellator will look something like this
gluTessBeginContour(tess);
:
gluTessVertex(tess, v[i], v[i]);
:
gluTessEndContour(tess);
Read here and grab the examples http://www.songho.ca/opengl/gl_tessellation.html

GL_POLYGON is used for drawing convex polygons. Your car is not convex, so you can't draw everything in one go (glBegin.. glEnd). Split car into multiple parts that have different primitive types. GL_POLYGON can't be used for everything.
You aren't even using your tesselator.
Bottom line is that your question is very basic. Before going further with OpenGL, finish "OpenGL red book", that covers pretty much all basic information. Version 1.1 is available online for free in several different places.

Related

OpenGL color changing automatically and expand automatically

Trying to make some effect on these 2D shapes
How do I make the quad shape change color automatically without user interactive. Like a constant cycle of color from red, yellow and green?
void changecolor() {
glClear(GL_COLOR_BUFFER_BIT);
glBegin(GL_QUADS);
glVertex2f(0.0, 0.8);
glVertex2f(-0.2, 0.3);
glVertex2f(0.0, 0.0);
glVertex2f(0.2, 0.3);
glEnd();
}
Trying to make the quad to slow expansion animation as i run it. Currently it just shows the final expanded result as i run.
void q4() {
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(15, 15, 0);
glBegin(GL_QUADS);
glColor3f(1.0, 0, 0);
glVertex2f(0.1, 0.1);
glVertex2f(0.1, -0.1);
glVertex2f(-0.1, -0.1);
glVertex2f(-0.1, 0.1);
glEnd();
}

Draw multi-colored triangle with thick edges in opengl

Is it possible in opengl to draw this type to triangles?
I have already tried
glBegin(GL_TRIANGLES);
glBegin(GL_LINE_LOOP);
Code and Result i got using glBegin(GL_LINE_LOOP)
Code:
glBegin(GL_LINE_LOOP);
glColor3f(0.0f, 1.0f, 1.0f);
glVertex2f(-30.0, 30.0);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex2f(30.0, 30.0);
glColor3f(0.5f, 0.0f, 1.0f);
glVertex2f(0.0, -30);
glEnd();
Result:
I would change your code to this:
glLineWidth(5.0); // this makes 5 pixel thick lines
glBegin(GL_LINES);
glColor3f(0.0f, 1.0f, 1.0f); glVertex2f(-30.0, 30.0); glVertex2f( 30.0, 30.0);
glColor3f(1.0f, 1.0f, 0.0f); glVertex2f( 30.0, 30.0); glVertex2f( 0.0,-30.0);
glColor3f(0.5f, 0.0f, 1.0f); glVertex2f( 0.0,-30.0); glVertex2f(-30.0, 30.0);
glEnd();
glLineWidth(1.0); // return state to original conditions
So you should have thick lines and the coloring should not interpolate between lines ...
To remove color gradients, you have at least two options:
You could call glShadeModel(GL_FLAT); before rendering the triangle.
You could use GL_LINES, like so:
glBegin(GL_LINES);
glColor3f(0.0f, 1.0f, 1.0f);
glVertex2f(-30.0, 30.0);
glVertex2f(30.0, 30.0);
glColor3f(1.0f, 1.0f, 0.0f);
glVertex2f(30.0, 30.0);
glVertex2f(0.0, -30);
glColor3f(0.5f, 0.0f, 1.0f);
glVertex2f(0.0, -30);
glVertex2f(-30.0, 30.0);
glEnd();
To increase line width, you could use glLineWidth.
But you'll see that ends of wide lines normally don't look as pretty and round as on your image. If that's a problem for you, you'll have to draw the shape using lots of carefully placed GL_TRIANGLES instead.

Colors disappear after drawing image

I am trying to draw a sphere and a cube at the same time on my screen. But the colors of my cube(which gets drawn first) dissapear. I don't understand why.
the sphere on the right is fine. But my cube on the left isn't.
I added texture to both:
I can perfectly draw both of them seperately, but when I try to draw both of them on one widget something goes wrong.
I tought the popping and pushing would solve this issue, but it doesn't.
code:
void MyGLWidget::drawCube()
{
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glLoadIdentity();
gluLookAt(position,0.5,-0.1,-0.5,-0.5,0,0,0,1);
glTranslatef( 0.5, 0, 0.0);
glRotatef(getCubeAngle(), 1.0f, 0.0f, 0.0f);
glTranslatef(0, 0, 0);
glDisable(GL_TEXTURE_GEN_S);
glDisable(GL_TEXTURE_GEN_T);
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
//back
glTexCoord2f(0.0, 1.0); glVertex3f(-0.1, 0.1,-0.1 );
glTexCoord2f(1.0, 1.0); glVertex3f(0.1, 0.1,-0.1);
glTexCoord2f(1.0, 0.0); glVertex3f(0.1,-0.1,-0.1);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.1,-0.1,-0.1);
/*rest of cube gets drawn*/
glEnd();
glFlush();
glPopMatrix();
}
void MyGLWidget::drawSun()
{
glPushMatrix();
glLoadIdentity();
glBindTexture(GL_TEXTURE_2D, texturePlanet[0]);
glPushMatrix();
glScalef(1,1,1);
glLoadIdentity();
GLUquadricObj *quadric=gluNewQuadric();
gluQuadricTexture(quadric, GLU_TRUE);
gluQuadricNormals(quadric, GLU_SMOOTH);
glEnable(GL_TEXTURE_2D); //
glBindTexture(GL_TEXTURE_2D,texturePlanet[0]);//
gluSphere(quadric, 0.25, 360,360);
glDisable(GL_TEXTURE_2D);//
gluDeleteQuadric(quadric);
glPopMatrix();
}
void MyGLWidget::paintGL()
{
drawCube();
drawSun();
}
It is because In your cube drawing, you didn't enable texturing.
glEnable(GL_TEXTURE_2D); //ADD THIS TO ENABLE TEXTURING
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
//back
glTexCoord2f(0.0, 1.0); glVertex3f(-0.1, 0.1,-0.1 );
glTexCoord2f(1.0, 1.0); glVertex3f(0.1, 0.1,-0.1);
glTexCoord2f(1.0, 0.0); glVertex3f(0.1,-0.1,-0.1);
glTexCoord2f(0.0, 0.0); glVertex3f(-0.1,-0.1,-0.1);
/*rest of cube gets drawn*/
glEnd();
glFlush();
glPopMatrix();
glDisable(GL_TEXTURE_2D); // ADD THIS TO DISABLE TEXTURING

C++ OpenGL lighting only lights certain walls

I am lighting my scene in opengl and there are 4 walls, only 2 of them are being lit.
I think it is something wrong with the normals but I am not sure.
This is the lighting code:
glShadeModel(GL_SMOOTH);
//glEnable(GL_CULL_FACE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
GLfloat lightpos0[] = {-5, 1, 0, 0.};
GLfloat AmbientLight0[] = {0.2, 0.2, 0.2,1.0};
GLfloat DiffuseLight0[] = {0.8, 0.8, 0.8,1.0};
GLfloat SpecularLight0[] = {1.0, 1.0, 1.0,1.0};
glLightfv(GL_LIGHT0, GL_POSITION, lightpos0);
glLightfv(GL_LIGHT0, GL_AMBIENT, AmbientLight0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, DiffuseLight0);
glLightfv(GL_LIGHT0, GL_SPECULAR, SpecularLight0);
GLfloat lightpos1[] = {5, 1, 0, 0};
GLfloat AmbientLight1[] = {0.2, 0.2, 0.2,1.0};
GLfloat DiffuseLight1[] = {0.8, 0.8, 0.8,1.0};
GLfloat SpecularLight1[] = {1.0, 1.0, 1.0,1.0};
glLightfv(GL_LIGHT1, GL_POSITION, lightpos1);
glLightfv(GL_LIGHT1, GL_AMBIENT, AmbientLight1);
glLightfv(GL_LIGHT1, GL_DIFFUSE, DiffuseLight1);
glLightfv(GL_LIGHT1, GL_SPECULAR, SpecularLight1);
This is the code for drawing the 4 walls.
//north
glBegin(GL_QUADS);
glNormal3f(1.0,0,0);
glVertex3f(-10,0,-10);
glVertex3f( 10,0,-10);
glVertex3f( 10,5,-10);
glVertex3f(-10,5,-10);
glEnd();
//south
glBegin(GL_QUADS);
glNormal3f(-1.0, 0, 0);
glVertex3f(-10,0, 10);
glVertex3f( 10,0, 10);
glVertex3f( 10,5, 10);
glVertex3f(-10,5, 10);
glEnd();
//east
glBegin(GL_QUADS);
glNormal3f(0,0, -1.0);
glVertex3f( 10,0,-10);
glVertex3f( 10,0,10);
glVertex3f( 10,5,10);
glVertex3f( 10,5,-10);
glEnd();
//west
glBegin(GL_QUADS);
glNormal3f(0,0,1.0);
glVertex3f( -10,0,-10);
glVertex3f( -10,0,10);
glVertex3f( -10,5,10);
glVertex3f( -10,5,-10);
glEnd();
If it helps, here's and image of whats happening: http://i.stack.imgur.com/xRgVL.png
As pointed out by Vladislav Khorev, the normals must be directed out of the coordinate that is common to all points (given this special orthogonal arrangement).
But also one should consider the winding of the polygons:
// Polygon A -- north Polygon B -- south
glVertex3f(-10,0,-10); glVertex3f(-10,0, 10);
glVertex3f( 10,0,-10); glVertex3f( 10,0, 10);
glVertex3f( 10,5,-10); glVertex3f( 10,5, 10);
glVertex3f(-10,5,-10); glVertex3f(-10,5, 10);
Normal(0,0,1), Normal(0,0,-1);
The two polygons (north and south), are of different winding. The first is ClockWise observed from point 0,0,0 and the other of CCW. One should be consistent with these.
It seems that you pass wrong normal vector to walls.
If your wall got Z = -10 for all points (wall is parallel to X), then it must have normal vector directed in positive direction of Z: (0,0,1).
Same is true for all directions.
Try this:
glBegin(GL_QUADS);
glNormal3f(0,0,1);
glVertex3f(-10,0,-10);
glVertex3f( 10,0,-10);
glVertex3f( 10,5,-10);
glVertex3f(-10,5,-10);
glEnd();
//south
glBegin(GL_QUADS);
glNormal3f(0, 0, -1);
glVertex3f(-10,0, 10);
glVertex3f( 10,0, 10);
glVertex3f( 10,5, 10);
glVertex3f(-10,5, 10);
glEnd();
//east
glBegin(GL_QUADS);
glNormal3f(-1,0, -0);
glVertex3f( 10,0,-10);
glVertex3f( 10,0,10);
glVertex3f( 10,5,10);
glVertex3f( 10,5,-10);
glEnd();
//west
glBegin(GL_QUADS);
glNormal3f(1, 0, 0);
glVertex3f( -10,0,-10);
glVertex3f( -10,0,10);
glVertex3f( -10,5,10);
glVertex3f( -10,5,-10);
glEnd();

Problems with OpenGL lighting

I'm having trouble being able to see objects I've created when I have enabled lighting in OpenGL. I have an object that is imported from 3D Max that the lighting works correctly on but the rest of my scene does not. I know that I need to specify normals but this hasn't seemed to have helped. Although if I create a simple polygon in my display() function that works correctly but other polygons that have been created in methods of a class and called in the display() function are not showing up
Here is my lighting code
glewInit();
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT)
glShadeModel(GL_SMOOTH);
//light position and colour
GLfloat light_position[] = { 0.0, 0.0, 20.0,0.0 };
GLfloat white_light[] = {0.8,0.8,0.8,0.0};
GLfloat diff_light[] = {1.0,1.0,1.0,0.0};
GLfloat spec_light[] = {1.0,1.0,1.0,0.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, white_light);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diff_light);
glLightfv(GL_LIGHT0, GL_SPECULAR, spec_light);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
//ambient light
GLfloat ambient[] = {0.3,0.3,0.3};
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
//diffuse material component
GLfloat diff[] = {0.6,0.6,0.6};
glMaterialfv(GL_FRONT, GL_DIFFUSE, diff);
//specular material component
GLfloat WhiteSpec[] = {1,1,1};
glMaterialfv(GL_FRONT, GL_SPECULAR, WhiteSpec);
GLfloat shininess = 50;
glMaterialf(GL_FRONT, GL_SHININESS, shininess);
//ENABLE LIGHTING AND DEPTH TEST
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
This is my class method that is creating my sea
glColor3f(0,0,1);
glPushMatrix();
//enable texturing
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBindTexture(GL_TEXTURE_2D, seaTex);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
for(int i = 0, k = 0; i < (getWidth()/10); i++){
for(int j = 0; j < (getLength()/10); j++){
if(i >= Sea::waveLoc1 && i <= Sea::waveLoc1+Sea::sinArrayLength){
int nextK = k+1;
if(nextK == Sea::sinArrayLength){
nextK = 0;
}
if(i == Sea::waveLoc1+Sea::sinArrayLength){
//front of wave
glBegin(GL_POLYGON);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0, 1.0);glVertex3f(Sea::seaGrid[i][j].x, Sea::sinVals[nextK], Sea::seaGrid[i][j].z);
glTexCoord2f(0.0, 0.0);glVertex3f(Sea::seaGrid[i][j+1].x, Sea::sinVals[nextK], Sea::seaGrid[i][j+1].z);
glTexCoord2f(1.0, 0.0);glVertex3f(Sea::seaGrid[i+1][j+1].x, Sea::seaGrid[i+1][j+1].y , Sea::seaGrid[i+1][j+1].z);
glTexCoord2f(1.0, 1.0);glVertex3f(Sea::seaGrid[i+1][j].x, Sea::seaGrid[i+1][j].y, Sea::seaGrid[i+1][j].z);
glEnd();
}else{
//rest of wave
glBegin(GL_POLYGON);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0, 1.0);glVertex3f(Sea::seaGrid[i][j].x, Sea::sinVals[k], Sea::seaGrid[i][j].z);
glTexCoord2f(0.0, 0.0);glVertex3f(Sea::seaGrid[i][j+1].x, Sea::sinVals[k], Sea::seaGrid[i][j+1].z);
glTexCoord2f(1.0, 0.0);glVertex3f(Sea::seaGrid[i+1][j+1].x, Sea::sinVals[nextK], Sea::seaGrid[i+1][j+1].z);
glTexCoord2f(1.0, 1.0);glVertex3f(Sea::seaGrid[i+1][j].x, Sea::sinVals[nextK], Sea::seaGrid[i+1][j].z);
glEnd();
}
}else{
//draw flat sea
glBegin(GL_POLYGON);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f(0.0, 1.0);glVertex3f(Sea::seaGrid[i+1][j].x, Sea::seaGrid[i+1][j].y, Sea::seaGrid[i+1][j].z);
glTexCoord2f(0.0, 0.0);glVertex3f(Sea::seaGrid[i+1][j+1].x, Sea::seaGrid[i+1][j+1].y, Sea::seaGrid[i+1][j+1].z);
glTexCoord2f(1.0, 0.0);glVertex3f(Sea::seaGrid[i][j+1].x, Sea::seaGrid[i][j+1].y, Sea::seaGrid[i][j+1].z);
glTexCoord2f(1.0, 1.0);glVertex3f(Sea::seaGrid[i][j].x, Sea::seaGrid[i][j].y, Sea::seaGrid[i][j].z);
glEnd();
}
}
//increment k if i is in the area of the wave
if(k < Sea::sinArrayLength-1 && (i >= Sea::waveLoc1 && i <= Sea::waveLoc1+Sea::sinArrayLength)){
k++;
}else if(k == Sea::sinArrayLength){
k = 0;
}
}
if(Sea::waveLoc1 < 100 && Sea::waveInc == Sea::waveSpeedLimiter){
Sea::waveLoc1 +=1;
}else if(Sea::waveLoc1 >= 100){
Sea::waveLoc1 = 0;
}
//limits speed of wave
if(Sea::waveInc < Sea::waveSpeedLimiter){
Sea::waveInc++;
}else{
Sea::waveInc = 0;
}
//disable texturing
glDisable(GL_BLEND);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
This is then called in my display() function as below
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)screenWidth/(GLfloat)screenHeight,0.1f,1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
camera.updateCameraPosition(mouse_x,mouse_y,screenWidth,screenHeight);
sea.buildSeaPlane();
scene.buildEdges();
glPushMatrix();
glColor3f(0,1,0);
glTranslatef(0, 20, 200);
model.speedDisplayFaceNormals();
glPopMatrix();
glPushMatrix();
plane.updatePlanePosition();
glBegin(GL_POLYGON);
glNormal3f(0.0f, 1.0f, 0.0f);
glVertex3f(0, 25, 10);
glVertex3f(2, 25, 10);
glVertex3f(2, 25, 20);
glVertex3f(0, 25, 20);
glEnd();
glPopMatrix();
glFlush();
Any idea why I can't see any of this?
UPDATE:
I can see my sea if I disable texturing. How can I fix it so I can use textures and lighting?
UPDATE 2:
Have changed texturing to GL_MODULATE but I also had to remove the blending to make it work. Do I need blending enabled?
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
says to replace the lighting computation with the result of texturing. If you want lighting to affect texturing, us GL_MODULATE instead of GL_REPLACE.
Edit to add:
You only need blending if you want your geometry to be translucent (that's what blending is typically for). In your case, there are a number of issues in the code:
your light colors are fully transparent (all have 0. as the 4th component). So your light is making everything invisible. change it to 1.
your materials don't have a 4th component. That's even worse, as glMaterialfv expects 4 floats. That could even crash your app or reformat your disk. Add a forth component, preferably to 1. to make it fully opaque.
Try adding an ambient light for the whole scene. Something like:
GLfloat lightColor[] = {1.0f, 1.0f, 1.0f, 1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightColor);
In your glMaterialfv calls, the color parameter should have 4 values, not 3. Normally the 4th value is an alpha of 1.0. I'm not sure if it's OK to pass 0.0 as the 4th value for glLightfv either.