//
// 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();
}

Reply via email to