diff options
| -rw-r--r-- | progs/demos/gloss.c | 358 | 
1 files changed, 358 insertions, 0 deletions
diff --git a/progs/demos/gloss.c b/progs/demos/gloss.c new file mode 100644 index 0000000000..5de3647d62 --- /dev/null +++ b/progs/demos/gloss.c @@ -0,0 +1,358 @@ +/* $Id: gloss.c,v 1.1 1999/10/22 20:34:57 brianp Exp $ */ + +/* + * Specular reflection demo.  The specular hightlight is modulated by + * a sphere-mapped texture.  The result is a high-gloss surface. + * NOTE: you really need hardware acceleration for this. + * + * Command line options: + *    -info      print GL implementation information + * + * + * Brian Paul  October 22, 1999  This program is in the public domain. + */ + + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <GL/glut.h> + +#include "../util/readtex.c"   /* I know, this is a hack. */ + +#define SPECULAR_TEXTURE_FILE "../images/reflect.rgb" +#define BASE_TEXTURE_FILE "../images/tile.rgb" + +/* Menu items */ +#define DO_SPEC_TEXTURE 1 +#define OBJECT 2 +#define ANIMATE 3 +#define QUIT 100 + +static GLuint CylinderObj = 0; +static GLuint TeapotObj = 0; +static GLuint Object = 0; +static GLboolean Animate = GL_TRUE; + +static GLfloat Xrot = 0.0, Yrot = 0.0, Zrot = 0.0; +static GLfloat DXrot = 1.0, DYrot = 2.5; + +static GLfloat Black[4] = { 0, 0, 0, 0 }; +static GLfloat White[4] = { 1, 1, 1, 1 }; +static GLfloat Diffuse[4] = { .3, .3, 1.0, 1.0 };  /* blue */ +static GLfloat Shininess = 15; + +static GLuint BaseTexture, SpecularTexture; +static GLboolean DoSpecTexture = GL_TRUE; + +/* performance info */ +static GLint T0 = 0; +static GLint Frames = 0; + + + + +static void Idle( void ) +{ +   if (Animate) { +      Xrot += DXrot; +      Yrot += DYrot; +      glutPostRedisplay(); +   } +} + + +static void Display( void ) +{ +   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + +   glPushMatrix(); +   glRotatef(Xrot, 1.0, 0.0, 0.0); +   glRotatef(Yrot, 0.0, 1.0, 0.0); +   glRotatef(Zrot, 0.0, 0.0, 1.0); + +   /* First pass: diffuse lighting with base texture */ +   glMaterialfv(GL_FRONT, GL_DIFFUSE, Diffuse); +   glMaterialfv(GL_FRONT, GL_SPECULAR, Black); +   glEnable(GL_TEXTURE_2D); +   glBindTexture(GL_TEXTURE_2D, BaseTexture); +   glMatrixMode(GL_TEXTURE); +   glLoadIdentity(); +   glScalef(2.0, 2.0, 2.0); +   glMatrixMode(GL_MODELVIEW); +   glCallList(Object); +   glMatrixMode(GL_TEXTURE); +   glLoadIdentity(); +   glMatrixMode(GL_MODELVIEW); + +   /* Second pass: specular lighting with reflection texture */ +   glBlendFunc(GL_ONE, GL_ONE);  /* add */ +   glEnable(GL_BLEND); +   glDepthFunc(GL_LEQUAL); +   glMaterialfv(GL_FRONT, GL_DIFFUSE, Black); +   glMaterialfv(GL_FRONT, GL_SPECULAR, White); +   if (DoSpecTexture) { +      glBindTexture(GL_TEXTURE_2D, SpecularTexture); +      glEnable(GL_TEXTURE_GEN_S); +      glEnable(GL_TEXTURE_GEN_T); +   } +   else { +      glDisable(GL_TEXTURE_2D); +   } +   glCallList(Object); +   glDisable(GL_TEXTURE_GEN_S); +   glDisable(GL_TEXTURE_GEN_T); +   glDisable(GL_BLEND); +   glDepthFunc(GL_LESS); + +   glPopMatrix(); + +   glutSwapBuffers(); + +   if (Animate) { +      GLint t = glutGet(GLUT_ELAPSED_TIME); +      Frames++; +      if (t - T0 >= 5000) { +         GLfloat seconds = (t - T0) / 1000.0; +         GLfloat fps = Frames / seconds; +         printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps); +         T0 = t; +         Frames = 0; +      } +   } +} + + +static void Reshape( int width, int height ) +{ +   GLfloat h = 30.0; +   GLfloat w = h * width / height; +   glViewport( 0, 0, width, height ); +   glMatrixMode( GL_PROJECTION ); +   glLoadIdentity(); +   glFrustum( -w, w, -h, h, 150.0, 500.0 ); +   glMatrixMode( GL_MODELVIEW ); +   glLoadIdentity(); +   glTranslatef( 0.0, 0.0, -380.0 ); +} + + +static void ToggleAnimate(void) +{ +   Animate = !Animate; +   if (Animate) { +      glutIdleFunc( Idle ); +      T0 = glutGet(GLUT_ELAPSED_TIME); +      Frames = 0; +   } +   else { +      glutIdleFunc( NULL ); +   } +} + + +static void ModeMenu(int entry) +{ +   if (entry==ANIMATE) { +      ToggleAnimate(); +   } +   else if (entry==DO_SPEC_TEXTURE) { +      DoSpecTexture = !DoSpecTexture; +   } +   else if (entry==OBJECT) { +      if (Object == TeapotObj) +         Object = CylinderObj; +      else +         Object = TeapotObj; +   } +   else if (entry==QUIT) { +      exit(0); +   } +   glutPostRedisplay(); +} + + +static void Key( unsigned char key, int x, int y ) +{ +   (void) x; +   (void) y; +   switch (key) { +      case 's': +         Shininess--; +         if (Shininess < 0.0) +            Shininess = 0.0; +         glMaterialf(GL_FRONT, GL_SHININESS, Shininess); +         printf("Shininess = %g\n", Shininess); +         break; +      case 'S': +         Shininess++; +         if (Shininess > 128.0) +            Shininess = 128.0; +         glMaterialf(GL_FRONT, GL_SHININESS, Shininess); +         printf("Shininess = %g\n", Shininess); +         break; +      case ' ': +         ToggleAnimate(); +         break; +      case 27: +         exit(0); +         break; +   } +   glutPostRedisplay(); +} + + +static void SpecialKey( int key, int x, int y ) +{ +   float step = 3.0; +   (void) x; +   (void) y; + +   switch (key) { +      case GLUT_KEY_UP: +         Xrot += step; +         break; +      case GLUT_KEY_DOWN: +         Xrot -= step; +         break; +      case GLUT_KEY_LEFT: +         Yrot += step; +         break; +      case GLUT_KEY_RIGHT: +         Yrot -= step; +         break; +   } +   glutPostRedisplay(); +} + + +static void Init( int argc, char *argv[] ) +{ +   /* Cylinder object */ +   { +      static GLfloat height = 100.0; +      static GLfloat radius = 40.0; +      GLUquadricObj *q = gluNewQuadric(); +      assert(q); +      gluQuadricTexture(q, GL_TRUE); + +      CylinderObj = glGenLists(1); +      glNewList(CylinderObj, GL_COMPILE); + +      glPushMatrix(); +      glTranslatef(0.0, 0.0, -0.5 * height); + +      /* cylinder */ +      gluQuadricNormals(q, GL_SMOOTH); +      gluQuadricTexture(q, GL_TRUE); +      gluCylinder(q, radius, radius, height, 24, 10); + +      /* end cap */ +      glTranslatef(0.0, 0.0, height); +      gluDisk(q, 0.0, radius, 24, 1); + +      /* other end cap */ +      glTranslatef(0.0, 0.0, -height); +      gluQuadricOrientation(q, GLU_INSIDE); +      gluDisk(q, 0.0, radius, 24, 1); + +      glPopMatrix(); +      glEndList(); +      gluDeleteQuadric(q); +   } + +   /* Teapot */ +   { +      TeapotObj = glGenLists(1); +      glNewList(TeapotObj, GL_COMPILE); + +      glFrontFace(GL_CW); +      glutSolidTeapot(40.0); +      glFrontFace(GL_CCW); + +      glEndList(); +   } + +   /* show cylinder by default */ +   Object = CylinderObj; + + +   /* lighting */ +   glEnable(GL_LIGHTING); +   { +      GLfloat pos[4] = { 3, 3, 3, 1 }; +      glLightfv(GL_LIGHT0, GL_AMBIENT, Black); +      glLightfv(GL_LIGHT0, GL_DIFFUSE, White); +      glLightfv(GL_LIGHT0, GL_SPECULAR, White); +      glLightfv(GL_LIGHT0, GL_POSITION, pos); +      glEnable(GL_LIGHT0); +      glMaterialfv(GL_FRONT, GL_AMBIENT, Black); +      glMaterialf(GL_FRONT, GL_SHININESS, Shininess); +      glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1); +   } + +   /* Base texture */ +   glGenTextures(1, &BaseTexture); +   glBindTexture(GL_TEXTURE_2D, BaseTexture); +   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +   if (!LoadRGBMipmaps(BASE_TEXTURE_FILE, GL_RGB)) { +      printf("Error: couldn't load texture image file %s\n", BASE_TEXTURE_FILE); +      exit(1); +   } + +   /* Specular texture */ +   glGenTextures(1, &SpecularTexture); +   glBindTexture(GL_TEXTURE_2D, SpecularTexture); +   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); +   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); +   if (!LoadRGBMipmaps(SPECULAR_TEXTURE_FILE, GL_RGB)) { +      printf("Error: couldn't load texture image file %s\n", SPECULAR_TEXTURE_FILE); +      exit(1); +   } + +   /* misc */ +   glEnable(GL_CULL_FACE); +   glEnable(GL_TEXTURE_2D); +   glEnable(GL_DEPTH_TEST); +   glEnable(GL_NORMALIZE); + +   if (argc > 1 && strcmp(argv[1], "-info")==0) { +      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER)); +      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION)); +      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR)); +      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS)); +   } +} + + +int main( int argc, char *argv[] ) +{ +   glutInit( &argc, argv ); +   glutInitWindowSize( 500, 500 ); + +   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); + +   glutCreateWindow(argv[0] ); + +   Init(argc, argv); + +   glutReshapeFunc( Reshape ); +   glutKeyboardFunc( Key ); +   glutSpecialFunc( SpecialKey ); +   glutDisplayFunc( Display ); +   glutIdleFunc( Idle ); + +   glutCreateMenu(ModeMenu); +   glutAddMenuEntry("Toggle Highlight", DO_SPEC_TEXTURE); +   glutAddMenuEntry("Toggle Object", OBJECT); +   glutAddMenuEntry("Toggle Animate", ANIMATE); +   glutAddMenuEntry("Quit", QUIT); +   glutAttachMenu(GLUT_RIGHT_BUTTON); + +   glutMainLoop(); +   return 0; +}  | 
