132001f49Smrg
232001f49Smrg/*
332001f49Smrg * Textured cylinder demo: lighting, texturing, reflection mapping.
432001f49Smrg *
532001f49Smrg * Command line options:
632001f49Smrg *    -info      print GL implementation information
732001f49Smrg *
832001f49Smrg *
932001f49Smrg * Brian Paul  May 1997  This program is in the public domain.
1032001f49Smrg */
1132001f49Smrg
1232001f49Smrg#include <stdio.h>
1332001f49Smrg#include <stdlib.h>
1432001f49Smrg#include <math.h>
1532001f49Smrg#include <string.h>
1632001f49Smrg#include "glut_wrap.h"
1732001f49Smrg
1832001f49Smrg#include "readtex.h"
1932001f49Smrg
2032001f49Smrg#define TEXTURE_FILE DEMOS_DATA_DIR "reflect.rgb"
2132001f49Smrg
2232001f49Smrg#define LIT 1
2332001f49Smrg#define TEXTURED 2
2432001f49Smrg#define REFLECT 3
2532001f49Smrg#define ANIMATE 10
2632001f49Smrg#define POINT_FILTER 20
2732001f49Smrg#define LINEAR_FILTER 21
2832001f49Smrg#define QUIT 100
2932001f49Smrg
3032001f49Smrgstatic GLint Win = -1;
3132001f49Smrg
3232001f49Smrgstatic GLuint CylinderObj = 0;
3332001f49Smrgstatic GLboolean Animate = GL_TRUE;
3432001f49Smrg
3532001f49Smrgstatic GLfloat Xrot = 0.0, Yrot = 0.0, Zrot = 0.0;
3632001f49Smrgstatic GLfloat DXrot = 50.0, DYrot = 125.0;
3732001f49Smrg
3832001f49Smrg/* performance info */
3932001f49Smrgstatic GLint T0 = 0;
4032001f49Smrgstatic GLint Frames = 0;
4132001f49Smrg
4232001f49Smrg
4332001f49Smrgstatic void Idle( void )
4432001f49Smrg{
4532001f49Smrg   static double t0 = -1.;
4632001f49Smrg   double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
4732001f49Smrg   if (t0 < 0.0)
4832001f49Smrg      t0 = t;
4932001f49Smrg   dt = t - t0;
5032001f49Smrg   t0 = t;
5132001f49Smrg
5232001f49Smrg   if (Animate) {
5332001f49Smrg      Xrot += DXrot * dt;
5432001f49Smrg      Yrot += DYrot * dt;
5532001f49Smrg      glutPostRedisplay();
5632001f49Smrg   }
5732001f49Smrg}
5832001f49Smrg
5932001f49Smrg
6032001f49Smrgstatic void Display( void )
6132001f49Smrg{
6232001f49Smrg   glClear( GL_COLOR_BUFFER_BIT );
6332001f49Smrg
6432001f49Smrg   glPushMatrix();
6532001f49Smrg   glRotatef(Xrot, 1.0, 0.0, 0.0);
6632001f49Smrg   glRotatef(Yrot, 0.0, 1.0, 0.0);
6732001f49Smrg   glRotatef(Zrot, 0.0, 0.0, 1.0);
6832001f49Smrg   glScalef(5.0, 5.0, 5.0);
6932001f49Smrg   glCallList(CylinderObj);
7032001f49Smrg
7132001f49Smrg   glPopMatrix();
7232001f49Smrg
7332001f49Smrg   glutSwapBuffers();
7432001f49Smrg
7532001f49Smrg   if (Animate) {
7632001f49Smrg      GLint t = glutGet(GLUT_ELAPSED_TIME);
7732001f49Smrg      Frames++;
7832001f49Smrg      if (t - T0 >= 5000) {
7932001f49Smrg         GLfloat seconds = (t - T0) / 1000.0;
8032001f49Smrg         GLfloat fps = Frames / seconds;
8132001f49Smrg         printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
8232001f49Smrg         fflush(stdout);
8332001f49Smrg         T0 = t;
8432001f49Smrg         Frames = 0;
8532001f49Smrg      }
8632001f49Smrg   }
8732001f49Smrg}
8832001f49Smrg
8932001f49Smrg
9032001f49Smrgstatic void Reshape( int width, int height )
9132001f49Smrg{
9232001f49Smrg   glViewport( 0, 0, width, height );
9332001f49Smrg   glMatrixMode( GL_PROJECTION );
9432001f49Smrg   glLoadIdentity();
9532001f49Smrg   glFrustum( -1.0, 1.0, -1.0, 1.0, 10.0, 100.0 );
9632001f49Smrg   glMatrixMode( GL_MODELVIEW );
9732001f49Smrg   glLoadIdentity();
9832001f49Smrg   glTranslatef( 0.0, 0.0, -70.0 );
9932001f49Smrg}
10032001f49Smrg
10132001f49Smrg
10232001f49Smrgstatic void SetMode(GLuint m)
10332001f49Smrg{
10432001f49Smrg   /* disable everything */
10532001f49Smrg   glDisable(GL_LIGHTING);
10632001f49Smrg   glDisable(GL_TEXTURE_2D);
10732001f49Smrg   glDisable(GL_TEXTURE_GEN_S);
10832001f49Smrg   glDisable(GL_TEXTURE_GEN_T);
10932001f49Smrg
11032001f49Smrg   /* enable what's needed */
11132001f49Smrg   if (m==LIT) {
11232001f49Smrg      glEnable(GL_LIGHTING);
11332001f49Smrg   }
11432001f49Smrg   else if (m==TEXTURED) {
11532001f49Smrg      glEnable(GL_TEXTURE_2D);
11632001f49Smrg   }
11732001f49Smrg   else if (m==REFLECT) {
11832001f49Smrg      glEnable(GL_TEXTURE_2D);
11932001f49Smrg      glEnable(GL_TEXTURE_GEN_S);
12032001f49Smrg      glEnable(GL_TEXTURE_GEN_T);
12132001f49Smrg   }
12232001f49Smrg}
12332001f49Smrg
12432001f49Smrg
12532001f49Smrgstatic void ModeMenu(int entry)
12632001f49Smrg{
12732001f49Smrg   if (entry==ANIMATE) {
12832001f49Smrg      Animate = !Animate;
12932001f49Smrg      if (Animate)
13032001f49Smrg         glutIdleFunc(Idle);
13132001f49Smrg      else
13232001f49Smrg         glutIdleFunc(NULL);
13332001f49Smrg   }
13432001f49Smrg   else if (entry==POINT_FILTER) {
13532001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
13632001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
13732001f49Smrg   }
13832001f49Smrg   else if (entry==LINEAR_FILTER) {
13932001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
14032001f49Smrg      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
14132001f49Smrg   }
14232001f49Smrg   else if (entry==QUIT) {
14332001f49Smrg      exit(0);
14432001f49Smrg   }
14532001f49Smrg   else {
14632001f49Smrg      SetMode(entry);
14732001f49Smrg   }
14832001f49Smrg   glutPostRedisplay();
14932001f49Smrg}
15032001f49Smrg
15132001f49Smrg
15232001f49Smrgstatic void Key( unsigned char key, int x, int y )
15332001f49Smrg{
15432001f49Smrg   (void) x;
15532001f49Smrg   (void) y;
15632001f49Smrg   switch (key) {
15732001f49Smrg      case ' ':
15832001f49Smrg      Animate = !Animate;
15932001f49Smrg      if (Animate)
16032001f49Smrg         glutIdleFunc(Idle);
16132001f49Smrg      else
16232001f49Smrg         glutIdleFunc(NULL);
16332001f49Smrg      break;
16432001f49Smrg      case 27:
16532001f49Smrg         glutDestroyWindow(Win);
16632001f49Smrg         exit(0);
16732001f49Smrg         break;
16832001f49Smrg   }
16932001f49Smrg   glutPostRedisplay();
17032001f49Smrg}
17132001f49Smrg
17232001f49Smrg
17332001f49Smrgstatic void SpecialKey( int key, int x, int y )
17432001f49Smrg{
17532001f49Smrg   float step = 3.0;
17632001f49Smrg   (void) x;
17732001f49Smrg   (void) y;
17832001f49Smrg
17932001f49Smrg   switch (key) {
18032001f49Smrg      case GLUT_KEY_UP:
18132001f49Smrg         Xrot += step;
18232001f49Smrg         break;
18332001f49Smrg      case GLUT_KEY_DOWN:
18432001f49Smrg         Xrot -= step;
18532001f49Smrg         break;
18632001f49Smrg      case GLUT_KEY_LEFT:
18732001f49Smrg         Yrot += step;
18832001f49Smrg         break;
18932001f49Smrg      case GLUT_KEY_RIGHT:
19032001f49Smrg         Yrot -= step;
19132001f49Smrg         break;
19232001f49Smrg   }
19332001f49Smrg   glutPostRedisplay();
19432001f49Smrg}
19532001f49Smrg
19632001f49Smrg
19732001f49Smrgstatic void Init( int argc, char *argv[] )
19832001f49Smrg{
19932001f49Smrg   GLUquadricObj *q = gluNewQuadric();
20032001f49Smrg   CylinderObj = glGenLists(1);
20132001f49Smrg   glNewList(CylinderObj, GL_COMPILE);
20232001f49Smrg
20332001f49Smrg   glTranslatef(0.0, 0.0, -1.0);
20432001f49Smrg
20532001f49Smrg   /* cylinder */
20632001f49Smrg   gluQuadricNormals(q, GL_SMOOTH);
20732001f49Smrg   gluQuadricTexture(q, GL_TRUE);
20832001f49Smrg   gluCylinder(q, 0.6, 0.6, 2.0, 24, 1);
20932001f49Smrg
21032001f49Smrg   /* end cap */
21132001f49Smrg   glTranslatef(0.0, 0.0, 2.0);
21232001f49Smrg   gluDisk(q, 0.0, 0.6, 24, 1);
21332001f49Smrg
21432001f49Smrg   /* other end cap */
21532001f49Smrg   glTranslatef(0.0, 0.0, -2.0);
21632001f49Smrg   gluQuadricOrientation(q, GLU_INSIDE);
21732001f49Smrg   gluDisk(q, 0.0, 0.6, 24, 1);
21832001f49Smrg
21932001f49Smrg   glEndList();
22032001f49Smrg   gluDeleteQuadric(q);
22132001f49Smrg
22232001f49Smrg   /* lighting */
22332001f49Smrg   glEnable(GL_LIGHTING);
22432001f49Smrg   {
22532001f49Smrg      GLfloat gray[4] = {0.2, 0.2, 0.2, 1.0};
22632001f49Smrg      GLfloat white[4] = {1.0, 1.0, 1.0, 1.0};
22732001f49Smrg      GLfloat teal[4] = { 0.0, 1.0, 0.8, 1.0 };
22832001f49Smrg      glMaterialfv(GL_FRONT, GL_DIFFUSE, teal);
22932001f49Smrg      glLightfv(GL_LIGHT0, GL_AMBIENT, gray);
23032001f49Smrg      glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
23132001f49Smrg      glEnable(GL_LIGHT0);
23232001f49Smrg   }
23332001f49Smrg
23432001f49Smrg   /* fitering = nearest, initially */
23532001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
23632001f49Smrg   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
23732001f49Smrg
23832001f49Smrg   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
23932001f49Smrg   glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
24032001f49Smrg
24132001f49Smrg   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
24232001f49Smrg   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
24332001f49Smrg
24432001f49Smrg   if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
24532001f49Smrg      printf("Error: couldn't load texture image\n");
24632001f49Smrg      exit(1);
24732001f49Smrg   }
24832001f49Smrg
24932001f49Smrg   glEnable(GL_CULL_FACE);  /* don't need Z testing for convex objects */
25032001f49Smrg
25132001f49Smrg   SetMode(LIT);
25232001f49Smrg
25332001f49Smrg   if (argc > 1 && strcmp(argv[1], "-info")==0) {
25432001f49Smrg      printf("GL_RENDERER   = %s\n", (char *) glGetString(GL_RENDERER));
25532001f49Smrg      printf("GL_VERSION    = %s\n", (char *) glGetString(GL_VERSION));
25632001f49Smrg      printf("GL_VENDOR     = %s\n", (char *) glGetString(GL_VENDOR));
25732001f49Smrg      printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
25832001f49Smrg   }
25932001f49Smrg}
26032001f49Smrg
26132001f49Smrg
26232001f49Smrgint main( int argc, char *argv[] )
26332001f49Smrg{
26432001f49Smrg   glutInitWindowSize( 400, 400 );
26532001f49Smrg   glutInit( &argc, argv );
26632001f49Smrg   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
26732001f49Smrg
26832001f49Smrg   Win = glutCreateWindow(argv[0] );
26932001f49Smrg
27032001f49Smrg   Init(argc, argv);
27132001f49Smrg
27232001f49Smrg   glutReshapeFunc( Reshape );
27332001f49Smrg   glutKeyboardFunc( Key );
27432001f49Smrg   glutSpecialFunc( SpecialKey );
27532001f49Smrg   glutDisplayFunc( Display );
27632001f49Smrg   glutIdleFunc( Idle );
27732001f49Smrg
27832001f49Smrg   glutCreateMenu(ModeMenu);
27932001f49Smrg   glutAddMenuEntry("Lit", LIT);
28032001f49Smrg   glutAddMenuEntry("Textured", TEXTURED);
28132001f49Smrg   glutAddMenuEntry("Reflect", REFLECT);
28232001f49Smrg   glutAddMenuEntry("Point Filtered", POINT_FILTER);
28332001f49Smrg   glutAddMenuEntry("Linear Filtered", LINEAR_FILTER);
28432001f49Smrg   glutAddMenuEntry("Toggle Animation", ANIMATE);
28532001f49Smrg   glutAddMenuEntry("Quit", QUIT);
28632001f49Smrg   glutAttachMenu(GLUT_RIGHT_BUTTON);
28732001f49Smrg
28832001f49Smrg   glutMainLoop();
28932001f49Smrg   return 0;
29032001f49Smrg}
291