Limitation on two-sided rendering?

Do you all get the same result:

When glutSolidSphere and glutSolidTeapot are rendered under a light, using two-sided lighting model,
e.g.: glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE),
then one of them is not rendered properly depending on glFrontFace setting.

Such that:
If glFrontFace(GL_CCW) is set the Sphere is OK,
If glFrontFace(GL_CW) is set then the Teapot is OK.

Well, you can call glFrontFace with proper parameter (CCW or CW) before each object, however think of an external model which you don’t have control over the orientation of polygon vertices.

Is there a general setting that we can render both as desired?
Else, can we say this is a bug/limitation of OpenGL?

Below is a sample to reproduce this:
(modified from the distributed sample code TEA.C)


#include <GL/glut.h>

void init();
void reshape(int w, int h);
void display();

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500, 500);
glutInitWindowPosition(100, 100);
glutCreateWindow(“Tea in the Sahara”);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();

return 0;

}

void init()
{
GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };

glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);

glFrontFace (GL_CW); //****** THIS IS THE LINE IN QUESTION ******//     glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);

}

void reshape(int w, int h)
{
if (!h) return;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho (-4.0, 4.0, -4.0*(GLfloat)h/(GLfloat)w,
4.0*(GLfloat)h/(GLfloat)w, -10.0, 10.0);
else
glOrtho (-4.0*(GLfloat)w/(GLfloat)h,
4.0*(GLfloat)w/(GLfloat)h, -4.0, 4.0, -10.0, 10.0);

glMatrixMode(GL_MODELVIEW);

}

void drawScene()
{
glPushMatrix();
glTranslatef(2.0, 0.0, 0.0);
glutSolidTeapot(1.0);
glPopMatrix();

glPushMatrix();
glTranslatef(-2.0, 0.0, 0.0);
glutSolidSphere(1.0, 16.0, 16.0);
glPopMatrix();

}

void display()
{
GLfloat mat_diffuse[] = { 0.8, 0.8, 0.8, 1.0 };
GLfloat back_diffuse[] = { 0.8, 0.2, 0.8, 1.0 };

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glPushMatrix ();

/* one-sided lighting */
glLightModelf (GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
glPushMatrix ();
glTranslatef (0.0, 2.0, 0.0);
drawScene();
glPopMatrix ();

/* two-sided lighting, but same material */
glLightModelf (GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diffuse);
glPushMatrix ();
glTranslatef (0.0, 0.0, 0.0);
drawScene();
glPopMatrix ();

/* two-sided lighting, two different materials */
glMaterialfv (GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv (GL_BACK, GL_DIFFUSE, back_diffuse);
glPushMatrix ();
glTranslatef (0.0, -2.0, 0.0);
drawScene();
glPopMatrix ();

glLightModelf (GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE);
glPopMatrix ();
glFlush();

}

[This message has been edited by Suha Aktan (edited 12-09-2000).]