Lighting and rotation

I’ve created a small demo that uses two lights to light a tank. The main light, the “sun” rotates around a horizontal axis to give the impression of rising and setting. It lights the base of my tank fine but does not do so for the turret, which is rotating. No matter which angle the turret is at, the “sun” shines from a fixed side, where I would have liked the shading to change to reflect which side of the turret was lit while it rotates. My code is below. Can anyone point out what is wrong.

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Clear screen and depth buffer.
glLoadIdentity(); // Clear the matrix.
glTranslated(CameraX, CameraY, -CameraZ);
// Position scene to camera.
glPushMatrix(); // Save current matrix.
glRotatef(Rot, 1, -1, 0); // Rotate light.
glLightfv(GL_LIGHT0, GL_AMBIENT, Light0Amb);
// Set light 0’s ambient value.
glLightfv(GL_LIGHT0, GL_POSITION, Light0Pos);
// Position light 0.
glPopMatrix(); // Restore current matrix.
… // Other stuff for second light as flash from barrel.
glColor3f(0.5823f, 0.5216f, 0.3623f); // Set tank colour.
glPushMatrix(); // Save current matrix.
glTranslated(0, -0.1, 0); // Position for turret.
glRotatef(tRot, 0, 0, -1); // Rotate turret.
glCallList(ImageOffset + gTANKTURRETDL);
// Draw turret and attachments.
glPopMatrix(); // Restore current matrix.
glCallList(ImageOffset + gTANKBASEDL);
// Draw tank base.

Rot += 0.2f; // Increase angle of sun.
if (Rot >= 360) // Keep Rot between 0 and 360.
Rot -= 360;
else if (Rot < 0)
Rot += 360;
tRot += 2.5f; // Increment turret rotation.
if (tRot >= 360) // Keep turret rotation between 0 and 360.
tRot -= 360;
else if (tRot < 0)
tRot += 360;

Its like the turret rotation affects Light0 even thought it should have been fixed when I used glLightfv() earlier.

[Edit] Fixed a typo.

Another weird thing. Setting glListBase to ImageOffset then doing glCallList(gTANKBASEDL) does not work. Yet it draws above, and using glListBase to draw text works. I debugged it and found ImageOffset = 97 which means it’s correct. Any Ideas what went wrong?

[This message has been edited by Furrage (edited 04-29-2002).]

Are you sure you are working with the correct matrix ?

Originally posted by thewizard75:
[b]Are you sure you are working with the correct matrix ?

[/b]

As far as I know (i.e. MODELVIEWS_MATRIX). Light0Pos is defined as GLfloat Light0Pos = {0.0f, 0.0f, 1.0f, 0.0f}; It doesn’t change during the program. The command glRotate(Rot, 1, -1, 0) is supposed to rotate it from North East to South West and back. But when the turret is lit the light is always relative to the turret.

Anyone?

The code looks OK, are you sure you don’t have any glLight calls in the display list for the turret?

What about surface normals?

The only other thing might be that the light rotation matches the turret rotation as you move the light and turret, this would explain what you see but would be a silly mistake.

Nope. There are no lights defined in the definition of the display list. The light is positioned between a push/pop matrix pair before the turret is drawn (starting line 4 in the code above). I’m actually beginning to wonder if there is a bug in the dll (I’m using the generic drivers that come with Win 98 and VC++ 6.0). It makes no sense whatsoever. Anyway, here’s the display list code.

// Create tank turret DL.
glNewList(ImageOffset + gTANKTURRETDL, GL_COMPILE);
N = (Shape[37] - Shape[39]).cross(Shape[38] - Shape[39]).unit();
glNormal3d(N.x, N.y, N.z);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(Shape[38].x, Shape[38].y, Shape[38].z);
glVertex3d(Shape[39].x, Shape[39].y, Shape[39].z);
glVertex3d(Shape[37].x, Shape[37].y, Shape[37].z);
glVertex3d(Shape[40].x, Shape[40].y, Shape[40].z);
glVertex3d(Shape[36].x, Shape[36].y, Shape[36].z);
glVertex3d(Shape[41].x, Shape[41].y, Shape[41].z);
glEnd();
N = (Shape[28] - Shape[37]).cross(Shape[29] - Shape[37]).unit();
glNormal3d(N.x, N.y, N.z);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(Shape[29].x, Shape[29].y, Shape[29].z);
glVertex3d(Shape[37].x, Shape[37].y, Shape[37].z);
glVertex3d(Shape[28].x, Shape[28].y, Shape[28].z);
glVertex3d(Shape[36].x, Shape[36].y, Shape[36].z);
glEnd();
N = (Shape[29] - Shape[38]).cross(Shape[30] - Shape[38]).unit();
glNormal3d(N.x, N.y, N.z);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(Shape[30].x, Shape[30].y, Shape[30].z);
glVertex3d(Shape[38].x, Shape[38].y, Shape[38].z);
glVertex3d(Shape[29].x, Shape[29].y, Shape[29].z);
glVertex3d(Shape[37].x, Shape[37].y, Shape[37].z);
glEnd();
N = (Shape[38] - Shape[32]).cross(Shape[31] - Shape[32]).unit();
glNormal3d(N.x, N.y, N.z);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(Shape[31].x, Shape[31].y, Shape[31].z);
glVertex3d(Shape[32].x, Shape[32].y, Shape[32].z);
glVertex3d(Shape[38].x, Shape[38].y, Shape[38].z);
glVertex3d(Shape[39].x, Shape[39].y, Shape[39].z);
glEnd();
N = (Shape[40] - Shape[33]).cross(Shape[39] - Shape[33]).unit();
glNormal3d(N.x, N.y, N.z);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(Shape[39].x, Shape[39].y, Shape[39].z);
glVertex3d(Shape[33].x, Shape[33].y, Shape[33].z);
glVertex3d(Shape[40].x, Shape[40].y, Shape[40].z);
glVertex3d(Shape[34].x, Shape[34].y, Shape[34].z);
glEnd();
N = (Shape[41] - Shape[34]).cross(Shape[40] - Shape[34]).unit();
glNormal3d(N.x, N.y, N.z);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(Shape[40].x, Shape[40].y, Shape[40].z);
glVertex3d(Shape[34].x, Shape[34].y, Shape[34].z);
glVertex3d(Shape[41].x, Shape[41].y, Shape[41].z);
glVertex3d(Shape[35].x, Shape[35].y, Shape[35].z);
glEnd();
N = (Shape[28] - Shape[41]).cross(Shape[36] - Shape[41]).unit();
glNormal3d(N.x, N.y, N.z);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(Shape[36].x, Shape[36].y, Shape[36].z);
glVertex3d(Shape[41].x, Shape[41].y, Shape[41].z);
glVertex3d(Shape[28].x, Shape[28].y, Shape[28].z);
glVertex3d(Shape[35].x, Shape[35].y, Shape[35].z);
glEnd();
glBegin(GL_TRIANGLES);
N = (Shape[38] - Shape[31]).cross(Shape[30] - Shape[31]).unit();
glNormal3d(N.x, N.y, N.z);
glVertex3d(Shape[30].x, Shape[30].y, Shape[30].z);
glVertex3d(Shape[31].x, Shape[31].y, Shape[31].z);
glVertex3d(Shape[38].x, Shape[38].y, Shape[38].z);
N = (Shape[39] - Shape[33]).cross(Shape[32] - Shape[33]).unit();
glNormal3d(N.x, N.y, N.z);
glVertex3d(Shape[32].x, Shape[32].y, Shape[32].z);
glVertex3d(Shape[33].x, Shape[33].y, Shape[33].z);
glVertex3d(Shape[39].x, Shape[39].y, Shape[39].z);
glEnd();
N = (Shape[45] - Shape[43]).cross(Shape[42] - Shape[43]).unit();
glNormal3d(N.x, N.y, N.z);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(Shape[42].x, Shape[42].y, Shape[42].z);
glVertex3d(Shape[43].x, Shape[43].y, Shape[43].z);
glVertex3d(Shape[45].x, Shape[45].y, Shape[45].z);
glVertex3d(Shape[44].x, Shape[44].y, Shape[44].z);
glEnd();
glBegin(GL_TRIANGLE_STRIP);
glNormal3d(-1, 0, 0);
glVertex3d(Shape[46].x, Shape[46].y, Shape[46].z);
glVertex3d(Shape[47].x, Shape[47].y, Shape[47].z);
glNormal3d(0, 0, 1);
glVertex3d(Shape[51].x, Shape[51].y, Shape[51].z);
glVertex3d(Shape[48].x, Shape[48].y, Shape[48].z);
glNormal3d(1, 0, 0);
glVertex3d(Shape[50].x, Shape[50].y, Shape[50].z);
glVertex3d(Shape[49].x, Shape[49].y, Shape[49].z);
glEnd();
glEndList();