//
// bug.cpp
//
// This glut program demonstrates a bug in Mesa-3.1b1 and
// Mesa-3.1b1kw3
//
// The bug is not present in Mesa-3.0
//
// To show the bug, press SPACE once, and you will see a messed up
// spotlight with 3.1b1, but a proper one with 3.0
// The green light is the spot light.
//
// As long a the modelview is left untouched with scaling/rotating,
// the spotlight seems to remain intact.
// Press SPACE, and the sphere will rotate, causing a faulty
// spotlight. I don't believe point light sources are effected as well.
// I am not sure though.
//
// bug tested on linux-alpha-elf, linux-386-glide-opt-V2, linux-i386-elf
//
// BUILD CMDS:
// g++ -c -Wall -pipe -ggdb -O3 bug.cpp
// g++ -o bug bug.o -L/usr/local/lib/mesa -lglut -lMesaGLU -lMesaGL -L/usr/X11R6/lib
-ltiff -lX11 -lXext -lXmu -lXt -lXi -lSM -lICE
//
// If you have any questions, you can reach me at
// [EMAIL PROTECTED]
// I am not subscribed to the mesa bug mailing list, so messages
// on that channel will not reach me.
//
// Bram Stolk, 990320
//
#include <stdio.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
static float angle = 0.0;
static void SetupLighting(void)
{
static float red[] = { 1,0,0, 1 };
static float green[] = { 0,1,0, 1 };
static float position1[] ={ 0, -5, 0, 1 };
static float position2[] ={ 0, 0, -5, 1 };
static float dir2[] ={ 0, 0, 1};
#if 1
glLightfv(GL_LIGHT0, GL_DIFFUSE, red);
glLightfv(GL_LIGHT0, GL_POSITION, position1);
glEnable(GL_LIGHT0);
#endif
#if 1
glLightf( GL_LIGHT1, GL_SPOT_CUTOFF, 15.0);
glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, dir2);
glLightfv(GL_LIGHT1, GL_DIFFUSE, green);
glLightfv(GL_LIGHT1, GL_POSITION, position2);
glLightf( GL_LIGHT1, GL_SPOT_EXPONENT, 20.0);
glEnable(GL_LIGHT1);
#endif
}
static void SetupProjection(void)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum(-1.0,1.0,-1.0,1.0,5.0,600.0);
}
static void About(void)
{
fprintf(stderr,"GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
fprintf(stderr,"GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
fprintf(stderr,"GL_VENDOR: %s\n", (char *) glGetString(GL_VENDOR));
fprintf(stderr,"GLUT_API_VERSION: %d\n", GLUT_API_VERSION);
}
void Display(void)
{
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Move camera
glTranslatef(0,-3,-30);
// Make sure that the view trf is properly set
// in the modelview mat, before setting light positions.
static bool lights_set = false;
if (!lights_set)
{
SetupLighting();
SetupProjection();
lights_set = true;
}
glClearColor(0,0,1,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
static float white[] = { 1,1,1, 1 };
static GLUquadricObj *obj=0;
if (!obj)
{
obj = gluNewQuadric();
gluQuadricDrawStyle(obj,GLU_FILL);
gluQuadricNormals(obj,GLU_SMOOTH);
gluQuadricTexture(obj,GL_FALSE);
}
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, white);
// TRANSFORM
glRotatef(angle, 0,1,0);
gluSphere(obj,2.0,16,16);
// Make glut swap its buffers
glutSwapBuffers();
GLenum error = glGetError();
while (error != GL_NO_ERROR)
{
fprintf(stderr, "OpenGL error: %s\n", gluErrorString(error));
error = glGetError();
}
}
void Idle(void)
{
glutPostRedisplay();
}
void KeyboardDown(unsigned char key, int x, int y)
{
switch (key)
{
case 27:
exit(0);
case ' ' :
angle += 1;
break;
}
}
void Reshape(int w, int h)
{
glViewport(0, 0, w, h);
}
void SetupOGL(int width, int height)
{
glutInitWindowSize(width, height);
glutInitWindowPosition(0,0);
int argc=2;
char *argv[]={"courier.exe","-gldebug",0};
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
int retval = glutCreateWindow("courier");
if (!retval)
fprintf(stderr,"glutCreateWindow failed\n");
// Set the callbacks for glut
glutReshapeFunc(Reshape);
glutDisplayFunc(Display);
glutKeyboardFunc(KeyboardDown);
glutIdleFunc(Idle);
// Configure our culling
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// reset texture matrix
glMatrixMode(GL_TEXTURE);
glLoadIdentity();
// reset modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glEnable(GL_NORMALIZE); // needed to support scaling trfs
glEnable(GL_RESCALE_NORMAL);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
}
int main(int argc, char *argv[])
{
SetupOGL(64,64);
About();
glutMainLoop();
}