
/*
 * Specular reflection demo.  The specular highlight is modulated by
 * a sphere-mapped texture.  The result is a high-gloss surface.
 * NOTE: you really need hardware acceleration for this.
 * Also note, this technique can't be implemented with multi-texture
 * and separate specular color interpolation because there's no way
 * to indicate that the second texture unit (the reflection map)
 * should modulate the specular color and not the base color.
 * A future multi-texture extension could fix that.
 *
 * 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 <string.h>
#include <GL/glew.h>
#include <GL/glut.h>

#include "readtex.h"
#include "trackball.h"


#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

/* for convolution */
#define FILTER_SIZE 7

static GLint WinWidth = 500, WinHeight = 500;
static GLuint CylinderObj = 0;
static GLuint TeapotObj = 0;
static GLuint Object = 0;
static GLboolean Animate = GL_TRUE;

static float CurQuat[4] = { 0, 0, 0, 1 };

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 = 6;

static GLuint BaseTexture, SpecularTexture;
static GLboolean DoSpecTexture = GL_TRUE;

static GLboolean ButtonDown = GL_FALSE;
static GLint ButtonX, ButtonY;


/* performance info */
static GLint T0 = 0;
static GLint Frames = 0;


static void Idle( void )
{
   static const float yAxis[3] = {0, 1, 0};
   static double t0 = -1.;
   float quat[4];
   double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
   if (t0 < 0.0)
      t0 = t;
   dt = t - t0;
   t0 = t;

   axis_to_quat(yAxis, 2.0 * dt, quat);
   add_quats(quat, CurQuat, CurQuat);

   glutPostRedisplay();
}


static void Display( void )
{
   GLfloat rot[4][4];

   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

   glPushMatrix();
   build_rotmatrix(rot, CurQuat);
   glMultMatrixf(&rot[0][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);
   glCallList(Object);

   /* Second pass: specular lighting with reflection texture */
   glEnable(GL_POLYGON_OFFSET_FILL);
   glBlendFunc(GL_ONE, GL_ONE);  /* add */
   glEnable(GL_BLEND);
   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);
   glDisable(GL_POLYGON_OFFSET_FILL);

   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);
         fflush(stdout);
         T0 = t;
         Frames = 0;
      }
   }
}


static void Reshape( int width, int height )
{
   GLfloat h = 30.0;
   GLfloat w = h * width / height;
   WinWidth = width;
   WinHeight = 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 'a':
      case ' ':
         ToggleAnimate();
         break;
      case 27:
         exit(0);
         break;
   }
   glutPostRedisplay();
}


static void
MouseMotion(int x, int y)
{
   if (ButtonDown) {
      float x0 = (2.0 * ButtonX - WinWidth) / WinWidth;
      float y0 = (WinHeight - 2.0 * ButtonY) / WinHeight;
      float x1 = (2.0 * x - WinWidth) / WinWidth;
      float y1 = (WinHeight - 2.0 * y) / WinHeight;
      float q[4];

      trackball(q, x0, y0, x1, y1);
      ButtonX = x;
      ButtonY = y;
      add_quats(q, CurQuat, CurQuat);

      glutPostRedisplay();
   }
}


static void
MouseButton(int button, int state, int x, int y)
{
  if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
     ButtonDown = GL_TRUE;
     ButtonX = x;
     ButtonY = y;
  }
  else if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
     ButtonDown = GL_FALSE;
  }
}


static void Init( int argc, char *argv[] )
{
   GLboolean convolve = GL_FALSE;
   GLboolean fullscreen = GL_FALSE;
   int i;

   for (i = 1; i < argc; i++) {
      if (strcmp(argv[i], "-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));
      }
      else if (strcmp(argv[i], "-c")==0) {
         convolve = GL_TRUE;
      }
      else if (strcmp(argv[i], "-f")==0) {
         fullscreen = GL_TRUE;
      }
   }

   if (fullscreen)
      glutFullScreen();

   /* Cylinder object */
   {
      static GLfloat height = 100.0;
      static GLfloat radius = 40.0;
      static GLint slices = 24;  /* pie slices around Z axis */
      static GLint stacks = 10;  /* subdivisions along length of cylinder */
      static GLint rings = 4;    /* rings in the end disks */
      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);

      glMatrixMode(GL_TEXTURE);
      glLoadIdentity();
      /*glScalef(8.0, 4.0, 2.0);*/
      glMatrixMode(GL_MODELVIEW);

      /* cylinder */
      gluQuadricNormals(q, GL_SMOOTH);
      gluQuadricTexture(q, GL_TRUE);
      gluCylinder(q, radius, radius, height, slices, stacks);

      /* end cap */
      glMatrixMode(GL_TEXTURE);
      glLoadIdentity();
      glScalef(3.0, 3.0, 1.0);
      glMatrixMode(GL_MODELVIEW);

      glTranslatef(0.0, 0.0, height);
      gluDisk(q, 0.0, radius, slices, rings);

      /* other end cap */
      glTranslatef(0.0, 0.0, -height);
      gluQuadricOrientation(q, GLU_INSIDE);
      gluDisk(q, 0.0, radius, slices, rings);

      glPopMatrix();

      glMatrixMode(GL_TEXTURE);
      glLoadIdentity();
      glMatrixMode(GL_MODELVIEW);

      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 (convolve) {
      /* use convolution to blur the texture to simulate a dull finish
       * on the object.
       */
      GLubyte *img;
      GLenum format;
      GLint w, h;
      GLfloat filter[FILTER_SIZE][FILTER_SIZE][4];

      for (h = 0; h < FILTER_SIZE; h++) {
         for (w = 0; w < FILTER_SIZE; w++) {
            const GLfloat k = 1.0 / (FILTER_SIZE * FILTER_SIZE);
            filter[h][w][0] = k;
            filter[h][w][1] = k;
            filter[h][w][2] = k;
            filter[h][w][3] = k;
         }
      }

      glEnable(GL_CONVOLUTION_2D);
      glConvolutionParameteri(GL_CONVOLUTION_2D,
                              GL_CONVOLUTION_BORDER_MODE, GL_CONSTANT_BORDER);
      glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_RGBA,
                            FILTER_SIZE, FILTER_SIZE,
                            GL_RGBA, GL_FLOAT, filter);

      img = LoadRGBImage(SPECULAR_TEXTURE_FILE, &w, &h, &format);
      if (!img) {
         printf("Error: couldn't load texture image file %s\n",
                SPECULAR_TEXTURE_FILE);
         exit(1);
      }

      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0,
                   format, GL_UNSIGNED_BYTE, img);
      free(img);
   }
   else {
      /* regular path */
      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);

   glPolygonOffset( -1, -1 );
}


int main( int argc, char *argv[] )
{
   glutInitWindowSize(WinWidth, WinHeight);
   glutInit( &argc, argv );
   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
   glutCreateWindow(argv[0] );
   glewInit();
   glutReshapeFunc( Reshape );
   glutKeyboardFunc( Key );
   glutDisplayFunc( Display );
   glutMotionFunc(MouseMotion);
   glutMouseFunc(MouseButton);
   if (Animate)
      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);

   Init(argc, argv);

   glutMainLoop();
   return 0;
}
