Bug definiton:
Back facing polygons are CULLED away, --in contradiction-- upon
activation of GL_LIGHT_MODEL_TWO_SIDE, no matter glDisable(GL_CULL_FACE)
is called or not.
Possible suggestion for workaround: “Flip the normals” does not
work if there are open surfaces in the scene of which front and
back sides cannot be defined mathematically.
That is possible only for closed surfaces tough with some overhead.
Below is a code sample to reproduce this error.
On the output window:
1st row-> two-side OFF, SAME material for front&back
2nd row-> two-side ON, SAME material for front&back
3rd row-> two-side ON, DIFFERENT material for front&back
Note that in 3rd row, magenta is the back-face (interior) material of
the objects which should NOT be seen.
If you set glFrontFace(GL_CW) Sphere shows the bug,
elseif you set glFrontFace(GL_CCW) it is the Teapot.
Code to reproduce the bug:
(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(600, 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 LINE SWITCHES BUGGY OBJECTS **/
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glDisable(GL_CULL_FACE); /** HAS NO AFFECT **/
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-12-2000).]