/*
 * This program is under the GNU GPL.
 * Use at your own risk.
 *
 * written by David Bucciarelli (tech.hmw@plus.it)
 *            Humanware s.r.l.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#ifdef WIN32
#include <windows.h>
#endif

#include <GL/glut.h>

#ifdef XMESA
#include "GL/xmesa.h"
static int fullscreen = 1;
#endif

static int WIDTH = 640;
static int HEIGHT = 480;

static GLint T0 = 0;
static GLint Frames = 0;

#define BASESIZE 7.5f
#define SPHERE_RADIUS 0.75f

#define TEX_CHECK_WIDTH 256
#define TEX_CHECK_HEIGHT 256
#define TEX_CHECK_SLOT_SIZE (TEX_CHECK_HEIGHT/16)
#define TEX_CHECK_NUMSLOT (TEX_CHECK_HEIGHT/TEX_CHECK_SLOT_SIZE)

#define TEX_REFLECT_WIDTH 256
#define TEX_REFLECT_HEIGHT 256
#define TEX_REFLECT_SLOT_SIZE (TEX_REFLECT_HEIGHT/16)
#define TEX_REFLECT_NUMSLOT (TEX_REFLECT_HEIGHT/TEX_REFLECT_SLOT_SIZE)

#ifndef M_PI
#define M_PI 3.1415926535
#endif

#define EPSILON 0.0001

#define clamp255(a)  ( (a)<(0.0f) ? (0.0f) : ((a)>(255.0f) ? (255.0f) : (a)) )

#ifndef fabs
#define fabs(x) ((x)<0.0f?-(x):(x))
#endif

#define vequ(a,b) { (a)[0]=(b)[0]; (a)[1]=(b)[1]; (a)[2]=(b)[2]; }
#define vsub(a,b,c) { (a)[0]=(b)[0]-(c)[0]; (a)[1]=(b)[1]-(c)[1]; (a)[2]=(b)[2]-(c)[2]; }
#define	dprod(a,b) ((a)[0]*(b)[0]+(a)[1]*(b)[1]+(a)[2]*(b)[2])
#define vnormalize(a,b) { \
  register float m_norm; \
  m_norm=sqrt((double)dprod((a),(a))); \
  (a)[0] /=m_norm; \
  (a)[1] /=m_norm; \
  (a)[2] /=m_norm; }

static GLubyte checkmap[TEX_CHECK_HEIGHT][TEX_CHECK_WIDTH][3];
static GLuint checkid;
static int checkmap_currentslot = 0;

static GLubyte reflectmap[TEX_REFLECT_HEIGHT][TEX_REFLECT_WIDTH][3];
static GLuint reflectid;
static int reflectmap_currentslot = 0;

static GLuint lightdlist;
static GLuint objdlist;

static float lightpos[3] = { 2.1, 2.1, 2.8 };
static float objpos[3] = { 0.0, 0.0, 1.0 };

static float sphere_pos[TEX_CHECK_HEIGHT][TEX_REFLECT_WIDTH][3];

static int win = 0;

static float fogcolor[4] = { 0.05, 0.05, 0.05, 1.0 };

static float obs[3] = { 7.0, 0.0, 2.0 };
static float dir[3];
static float v = 0.0;
static float alpha = -90.0;
static float beta = 90.0;

static int fog = 1;
static int bfcull = 1;
static int poutline = 0;
static int help = 1;
static int showcheckmap = 1;
static int showreflectmap = 1;
static int joyavailable = 0;
static int joyactive = 0;

static void
calcposobs(void)
{
   dir[0] = sin(alpha * M_PI / 180.0);
   dir[1] = cos(alpha * M_PI / 180.0) * sin(beta * M_PI / 180.0);
   dir[2] = cos(beta * M_PI / 180.0);

   if (dir[0] < 1.0e-5 && dir[0] > -1.0e-5)
      dir[0] = 0;
   if (dir[1] < 1.0e-5 && dir[1] > -1.0e-5)
      dir[1] = 0;
   if (dir[2] < 1.0e-5 && dir[2] > -1.0e-5)
      dir[2] = 0;

   obs[0] += v * dir[0];
   obs[1] += v * dir[1];
   obs[2] += v * dir[2];
}

static void
special(int k, int x, int y)
{
   switch (k) {
   case GLUT_KEY_LEFT:
      alpha -= 2.0;
      break;
   case GLUT_KEY_RIGHT:
      alpha += 2.0;
      break;
   case GLUT_KEY_DOWN:
      beta -= 2.0;
      break;
   case GLUT_KEY_UP:
      beta += 2.0;
      break;
   }
}

static void
key(unsigned char k, int x, int y)
{
   switch (k) {
   case 27:
      exit(0);
      break;

   case 's':
      lightpos[1] -= 0.1;
      break;
   case 'd':
      lightpos[1] += 0.1;
      break;
   case 'e':
      lightpos[0] -= 0.1;
      break;
   case 'x':
      lightpos[0] += 0.1;
      break;
   case 'w':
      lightpos[2] -= 0.1;
      break;
   case 'r':
      lightpos[2] += 0.1;
      break;

   case 'j':
      objpos[1] -= 0.1;
      break;
   case 'k':
      objpos[1] += 0.1;
      break;
   case 'i':
      objpos[0] -= 0.1;
      break;
   case 'm':
      objpos[0] += 0.1;
      break;
   case 'u':
      objpos[2] -= 0.1;
      break;
   case 'o':
      objpos[2] += 0.1;
      break;

   case 'a':
      v += 0.005;
      break;
   case 'z':
      v -= 0.005;
      break;

   case 'g':
      joyactive = (!joyactive);
      break;
   case 'h':
      help = (!help);
      break;
   case 'f':
      fog = (!fog);
      break;

   case '1':
      showcheckmap = (!showcheckmap);
      break;
   case '2':
      showreflectmap = (!showreflectmap);
      break;

   case 'b':
      if (bfcull) {
	 glDisable(GL_CULL_FACE);
	 bfcull = 0;
      }
      else {
	 glEnable(GL_CULL_FACE);
	 bfcull = 1;
      }
      break;
   case 'p':
      if (poutline) {
	 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	 poutline = 0;
      }
      else {
	 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	 poutline = 1;
      }
      break;
#ifdef XMESA
   case ' ':
      XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
      fullscreen = (!fullscreen);
      break;
#endif
   }
}

static void
reshape(int w, int h)
{
   WIDTH = w;
   HEIGHT = h;
   glViewport(0, 0, w, h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   gluPerspective(45.0, w / (float) h, 0.8, 40.0);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
}

static void
printstring(void *font, char *string)
{
   int len, i;

   len = (int) strlen(string);
   for (i = 0; i < len; i++)
      glutBitmapCharacter(font, string[i]);
}

static void
printhelp(void)
{
   glEnable(GL_BLEND);
   glColor4f(0.5, 0.5, 0.5, 0.5);
   glRecti(40, 40, 600, 440);
   glDisable(GL_BLEND);

   glColor3f(0.0, 0.0, 1.0);
   glRasterPos2i(300, 420);
   printstring(GLUT_BITMAP_HELVETICA_18, "Help");

   glRasterPos2i(60, 390);
   printstring(GLUT_BITMAP_HELVETICA_12, "h - Toggle Help");
   glRasterPos2i(60, 370);
   printstring(GLUT_BITMAP_HELVETICA_12, "f - Toggle Fog");
   glRasterPos2i(60, 350);
   printstring(GLUT_BITMAP_HELVETICA_12, "b - Toggle Back face culling");
   glRasterPos2i(60, 330);
   printstring(GLUT_BITMAP_HELVETICA_12, "p - Toggle Wire frame");
   glRasterPos2i(60, 310);
   printstring(GLUT_BITMAP_HELVETICA_12, "Arrow Keys - Rotate");
   glRasterPos2i(60, 290);
   printstring(GLUT_BITMAP_HELVETICA_12, "a - Increase velocity");
   glRasterPos2i(60, 270);
   printstring(GLUT_BITMAP_HELVETICA_12, "z - Decrease velocity");

   glRasterPos2i(60, 250);
   if (joyavailable)
      printstring(GLUT_BITMAP_HELVETICA_12,
		  "j - Toggle jostick control (Joystick control available)");
   else
      printstring(GLUT_BITMAP_HELVETICA_12,
		  "(No Joystick control available)");

   glRasterPos2i(60, 230);
   printstring(GLUT_BITMAP_HELVETICA_12,
	       "To move the light source: s - left,  d - right,  e - far,  x - near,  w - down r - up");
   glRasterPos2i(60, 210);
   printstring(GLUT_BITMAP_HELVETICA_12,
	       "To move the mirror sphere: j - left,  k - right,  i - far,  m - near,  u - down o - up");

   glRasterPos2i(60, 190);
   printstring(GLUT_BITMAP_HELVETICA_12,
	       "1 - Toggle the plane texture map window");

   glRasterPos2i(60, 170);
   printstring(GLUT_BITMAP_HELVETICA_12,
	       "2 - Toggle the sphere texture map window");
}

static GLboolean
seelight(float p[3], float dir[3])
{
   float c[3], b, a, d, t, dist[3];

   vsub(c, p, objpos);
   b = -dprod(c, dir);
   a = dprod(c, c) - SPHERE_RADIUS * SPHERE_RADIUS;

   if ((d = b * b - a) < 0.0 || (b < 0.0 && a > 0.0))
      return GL_FALSE;

   d = sqrt(d);

   t = b - d;

   if (t < EPSILON) {
      t = b + d;
      if (t < EPSILON)
	 return GL_FALSE;
   }

   vsub(dist, lightpos, p);
   if (dprod(dist, dist) < t * t)
      return GL_FALSE;

   return GL_TRUE;
}

static int
colorcheckmap(float ppos[3], float c[3])
{
   static float norm[3] = { 0.0f, 0.0f, 1.0f };
   float ldir[3], vdir[3], h[3], dfact, kfact, r, g, b;
   int x, y;

   x = (int) ((ppos[0] + BASESIZE / 2) * (10.0f / BASESIZE));
   if ((x < 0) || (x > 10))
      return GL_FALSE;

   y = (int) ((ppos[1] + BASESIZE / 2) * (10.0f / BASESIZE));
   if ((y < 0) || (y > 10))
      return GL_FALSE;

   r = 255.0f;
   if (y & 1) {
      if (x & 1)
	 g = 255.0f;
      else
	 g = 0.0f;
   }
   else {
      if (x & 1)
	 g = 0.0f;
      else
	 g = 255.0f;
   }
   b = 0.0f;

   vsub(ldir, lightpos, ppos);
   vnormalize(ldir, ldir);

   if (seelight(ppos, ldir)) {
      c[0] = r * 0.05f;
      c[1] = g * 0.05f;
      c[2] = b * 0.05f;

      return GL_TRUE;
   }

   dfact = dprod(ldir, norm);
   if (dfact < 0.0f)
      dfact = 0.0f;

   vsub(vdir, obs, ppos);
   vnormalize(vdir, vdir);
   h[0] = 0.5f * (vdir[0] + ldir[0]);
   h[1] = 0.5f * (vdir[1] + ldir[1]);
   h[2] = 0.5f * (vdir[2] + ldir[2]);
   kfact = dprod(h, norm);
   kfact = pow(kfact, 6.0) * 7.0 * 255.0;

   r = r * dfact + kfact;
   g = g * dfact + kfact;
   b = b * dfact + kfact;

   c[0] = clamp255(r);
   c[1] = clamp255(g);
   c[2] = clamp255(b);

   return GL_TRUE;
}

static void
updatecheckmap(int slot)
{
   float c[3], ppos[3];
   int x, y;

   glBindTexture(GL_TEXTURE_2D, checkid);

   ppos[2] = 0.0f;
   for (y = slot * TEX_CHECK_SLOT_SIZE; y < (slot + 1) * TEX_CHECK_SLOT_SIZE;
	y++) {
      ppos[1] = (y / (float) TEX_CHECK_HEIGHT) * BASESIZE - BASESIZE / 2;

      for (x = 0; x < TEX_CHECK_WIDTH; x++) {
	 ppos[0] = (x / (float) TEX_CHECK_WIDTH) * BASESIZE - BASESIZE / 2;

	 colorcheckmap(ppos, c);
	 checkmap[y][x][0] = (GLubyte) c[0];
	 checkmap[y][x][1] = (GLubyte) c[1];
	 checkmap[y][x][2] = (GLubyte) c[2];
      }
   }

   glTexSubImage2D(GL_TEXTURE_2D, 0, 0, slot * TEX_CHECK_SLOT_SIZE,
		   TEX_CHECK_WIDTH, TEX_CHECK_SLOT_SIZE, GL_RGB,
		   GL_UNSIGNED_BYTE,
		   &checkmap[slot * TEX_CHECK_SLOT_SIZE][0][0]);

}

static void
updatereflectmap(int slot)
{
   float rf, r, g, b, t, dfact, kfact, rdir[3];
   float rcol[3], ppos[3], norm[3], ldir[3], h[3], vdir[3], planepos[3];
   int x, y;

   glBindTexture(GL_TEXTURE_2D, reflectid);

   for (y = slot * TEX_REFLECT_SLOT_SIZE;
	y < (slot + 1) * TEX_REFLECT_SLOT_SIZE; y++)
      for (x = 0; x < TEX_REFLECT_WIDTH; x++) {
	 ppos[0] = sphere_pos[y][x][0] + objpos[0];
	 ppos[1] = sphere_pos[y][x][1] + objpos[1];
	 ppos[2] = sphere_pos[y][x][2] + objpos[2];

	 vsub(norm, ppos, objpos);
	 vnormalize(norm, norm);

	 vsub(ldir, lightpos, ppos);
	 vnormalize(ldir, ldir);
	 vsub(vdir, obs, ppos);
	 vnormalize(vdir, vdir);

	 rf = 2.0f * dprod(norm, vdir);
	 if (rf > EPSILON) {
	    rdir[0] = rf * norm[0] - vdir[0];
	    rdir[1] = rf * norm[1] - vdir[1];
	    rdir[2] = rf * norm[2] - vdir[2];

	    t = -objpos[2] / rdir[2];

	    if (t > EPSILON) {
	       planepos[0] = objpos[0] + t * rdir[0];
	       planepos[1] = objpos[1] + t * rdir[1];
	       planepos[2] = 0.0f;

	       if (!colorcheckmap(planepos, rcol))
		  rcol[0] = rcol[1] = rcol[2] = 0.0f;
	    }
	    else
	       rcol[0] = rcol[1] = rcol[2] = 0.0f;
	 }
	 else
	    rcol[0] = rcol[1] = rcol[2] = 0.0f;

	 dfact = 0.1f * dprod(ldir, norm);

	 if (dfact < 0.0f) {
	    dfact = 0.0f;
	    kfact = 0.0f;
	 }
	 else {
	    h[0] = 0.5f * (vdir[0] + ldir[0]);
	    h[1] = 0.5f * (vdir[1] + ldir[1]);
	    h[2] = 0.5f * (vdir[2] + ldir[2]);
	    kfact = dprod(h, norm);
            kfact = pow(kfact, 4.0);
            if (kfact < 1.0e-10)
               kfact = 0.0;
         }

	 r = dfact + kfact;
	 g = dfact + kfact;
	 b = dfact + kfact;

	 r *= 255.0f;
	 g *= 255.0f;
	 b *= 255.0f;

	 r += rcol[0];
	 g += rcol[1];
	 b += rcol[2];

	 r = clamp255(r);
	 g = clamp255(g);
	 b = clamp255(b);

	 reflectmap[y][x][0] = (GLubyte) r;
	 reflectmap[y][x][1] = (GLubyte) g;
	 reflectmap[y][x][2] = (GLubyte) b;
      }

   glTexSubImage2D(GL_TEXTURE_2D, 0, 0, slot * TEX_REFLECT_SLOT_SIZE,
		   TEX_REFLECT_WIDTH, TEX_REFLECT_SLOT_SIZE, GL_RGB,
		   GL_UNSIGNED_BYTE,
		   &reflectmap[slot * TEX_REFLECT_SLOT_SIZE][0][0]);
}

static void
drawbase(void)
{
   glColor3f(0.0, 0.0, 0.0);
   glBindTexture(GL_TEXTURE_2D, checkid);
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

   glBegin(GL_QUADS);
   glTexCoord2f(0.0f, 0.0f);
   glVertex3f(-BASESIZE / 2.0f, -BASESIZE / 2.0f, 0.0f);

   glTexCoord2f(1.0f, 0.0f);
   glVertex3f(BASESIZE / 2.0f, -BASESIZE / 2.0f, 0.0f);

   glTexCoord2f(1.0f, 1.0f);
   glVertex3f(BASESIZE / 2.0f, BASESIZE / 2.0f, 0.0f);

   glTexCoord2f(0.0f, 1.0f);
   glVertex3f(-BASESIZE / 2.0f, BASESIZE / 2.0f, 0.0f);

   glEnd();
}

static void
drawobj(void)
{
   glColor3f(0.0, 0.0, 0.0);
   glBindTexture(GL_TEXTURE_2D, reflectid);
   glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

   glPushMatrix();
   glTranslatef(objpos[0], objpos[1], objpos[2]);
   glCallList(objdlist);
   glPopMatrix();
}

static void
dojoy(void)
{
#ifdef WIN32
   static UINT max[2] = { 0, 0 };
   static UINT min[2] = { 0xffffffff, 0xffffffff }, center[2];
   MMRESULT res;
   JOYINFO joy;

   res = joyGetPos(JOYSTICKID1, &joy);

   if (res == JOYERR_NOERROR) {
      joyavailable = 1;

      if (max[0] < joy.wXpos)
	 max[0] = joy.wXpos;
      if (min[0] > joy.wXpos)
	 min[0] = joy.wXpos;
      center[0] = (max[0] + min[0]) / 2;

      if (max[1] < joy.wYpos)
	 max[1] = joy.wYpos;
      if (min[1] > joy.wYpos)
	 min[1] = joy.wYpos;
      center[1] = (max[1] + min[1]) / 2;

      if (joyactive) {
	 if (fabs(center[0] - (float) joy.wXpos) > 0.1 * (max[0] - min[0]))
	    alpha -=
	       2.5 * (center[0] - (float) joy.wXpos) / (max[0] - min[0]);
	 if (fabs(center[1] - (float) joy.wYpos) > 0.1 * (max[1] - min[1]))
	    beta += 2.5 * (center[1] - (float) joy.wYpos) / (max[1] - min[1]);

	 if (joy.wButtons & JOY_BUTTON1)
	    v += 0.005;
	 if (joy.wButtons & JOY_BUTTON2)
	    v -= 0.005;
      }
   }
   else
      joyavailable = 0;
#endif
}

static void
updatemaps(void)
{
   updatecheckmap(checkmap_currentslot);
   checkmap_currentslot = (checkmap_currentslot + 1) % TEX_CHECK_NUMSLOT;

   updatereflectmap(reflectmap_currentslot);
   reflectmap_currentslot =
      (reflectmap_currentslot + 1) % TEX_REFLECT_NUMSLOT;
}

static void
draw(void)
{
   static char frbuf[80] = "";

   dojoy();

   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   glEnable(GL_TEXTURE_2D);
   glEnable(GL_DEPTH_TEST);
   if (fog)
      glEnable(GL_FOG);
   else
      glDisable(GL_FOG);

   glPushMatrix();
   calcposobs();

   gluLookAt(obs[0], obs[1], obs[2],
	     obs[0] + dir[0], obs[1] + dir[1], obs[2] + dir[2],
	     0.0, 0.0, 1.0);

   drawbase();
   drawobj();

   glColor3f(1.0, 1.0, 1.0);
   glDisable(GL_TEXTURE_2D);

   glPushMatrix();
   glTranslatef(lightpos[0], lightpos[1], lightpos[2]);
   glCallList(lightdlist);
   glPopMatrix();

   glPopMatrix();

   glDisable(GL_DEPTH_TEST);
   glDisable(GL_FOG);

   glMatrixMode(GL_PROJECTION);
   glPushMatrix();
   glLoadIdentity();
   glOrtho(-0.5, 639.5, -0.5, 479.5, -1.0, 1.0);
   glMatrixMode(GL_MODELVIEW);

   glColor3f(0.0f, 0.3f, 1.0f);

   if (showcheckmap) {
      glEnable(GL_TEXTURE_2D);
      glBindTexture(GL_TEXTURE_2D, checkid);
      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

      glBegin(GL_QUADS);
      glTexCoord2f(1.0f, 0.0f);
      glVertex2i(10, 30);
      glTexCoord2f(1.0f, 1.0f);
      glVertex2i(10 + 90, 30);
      glTexCoord2f(0.0f, 1.0f);
      glVertex2i(10 + 90, 30 + 90);
      glTexCoord2f(0.0f, 0.0f);
      glVertex2i(10, 30 + 90);
      glEnd();

      glDisable(GL_TEXTURE_2D);
      glBegin(GL_LINE_LOOP);
      glVertex2i(10, 30);
      glVertex2i(10 + 90, 30);
      glVertex2i(10 + 90, 30 + 90);
      glVertex2i(10, 30 + 90);
      glEnd();
      glRasterPos2i(105, 65);
      printstring(GLUT_BITMAP_HELVETICA_18, "Plane Texture Map");
   }

   if (showreflectmap) {
      glEnable(GL_TEXTURE_2D);
      glBindTexture(GL_TEXTURE_2D, reflectid);
      glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

      glBegin(GL_QUADS);
      glTexCoord2f(1.0f, 0.0f);
      glVertex2i(540, 30);
      glTexCoord2f(1.0f, 1.0f);
      glVertex2i(540 + 90, 30);
      glTexCoord2f(0.0f, 1.0f);
      glVertex2i(540 + 90, 30 + 90);
      glTexCoord2f(0.0f, 0.0f);
      glVertex2i(540, 30 + 90);
      glEnd();

      glDisable(GL_TEXTURE_2D);
      glBegin(GL_LINE_LOOP);
      glVertex2i(540, 30);
      glVertex2i(540 + 90, 30);
      glVertex2i(540 + 90, 30 + 90);
      glVertex2i(540, 30 + 90);
      glEnd();
      glRasterPos2i(360, 65);
      printstring(GLUT_BITMAP_HELVETICA_18, "Sphere Texture Map");
   }

   glDisable(GL_TEXTURE_2D);

   glRasterPos2i(10, 10);
   printstring(GLUT_BITMAP_HELVETICA_18, frbuf);
   glRasterPos2i(360, 470);
   printstring(GLUT_BITMAP_HELVETICA_10,
	       "Ray V1.0 Written by David Bucciarelli (tech.hmw@plus.it)");

   if (help)
      printhelp();

   glMatrixMode(GL_PROJECTION);
   glPopMatrix();
   glMatrixMode(GL_MODELVIEW);

   updatemaps();

   glutSwapBuffers();

   Frames++;
   {
      GLint t = glutGet(GLUT_ELAPSED_TIME);
      if (t - T0 >= 2000) {
         GLfloat seconds = (t - T0) / 1000.0;
         GLfloat fps = Frames / seconds;
         sprintf(frbuf, "Frame rate: %f", fps);
         T0 = t;
         Frames = 0;
      }
   }
}

static void
inittextures(void)
{
   int y;

   glGenTextures(1, &checkid);
   glBindTexture(GL_TEXTURE_2D, checkid);

   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_CHECK_WIDTH, TEX_CHECK_HEIGHT,
		0, GL_RGB, GL_UNSIGNED_BYTE, checkmap);

   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

   for (y = 0; y < TEX_CHECK_NUMSLOT; y++)
      updatecheckmap(y);



   glGenTextures(1, &reflectid);
   glBindTexture(GL_TEXTURE_2D, reflectid);

   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   glTexImage2D(GL_TEXTURE_2D, 0, 3, TEX_REFLECT_WIDTH, TEX_REFLECT_HEIGHT,
		0, GL_RGB, GL_UNSIGNED_BYTE, reflectmap);

   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

   for (y = 0; y < TEX_REFLECT_NUMSLOT; y++)
      updatereflectmap(y);


}

static void
initspherepos(void)
{
   float alpha, beta, sa, ca, sb, cb;
   int x, y;

   for (y = 0; y < TEX_REFLECT_HEIGHT; y++) {
      beta = M_PI - y * (M_PI / TEX_REFLECT_HEIGHT);

      for (x = 0; x < TEX_REFLECT_WIDTH; x++) {
	 alpha = -x * (2.0f * M_PI / TEX_REFLECT_WIDTH);

	 sa = sin(alpha);
	 ca = cos(alpha);

	 sb = sin(beta);
	 cb = cos(beta);

	 sphere_pos[y][x][0] = SPHERE_RADIUS * sa * sb;
	 sphere_pos[y][x][1] = SPHERE_RADIUS * ca * sb;
	 sphere_pos[y][x][2] = SPHERE_RADIUS * cb;
      }
   }
}

static void
initdlists(void)
{
   GLUquadricObj *obj;

   obj = gluNewQuadric();

   lightdlist = glGenLists(1);
   glNewList(lightdlist, GL_COMPILE);
   gluQuadricDrawStyle(obj, GLU_FILL);
   gluQuadricNormals(obj, GLU_NONE);
   gluQuadricTexture(obj, GL_TRUE);
   gluSphere(obj, 0.25f, 6, 6);
   glEndList();

   objdlist = glGenLists(1);
   glNewList(objdlist, GL_COMPILE);
   gluQuadricDrawStyle(obj, GLU_FILL);
   gluQuadricNormals(obj, GLU_NONE);
   gluQuadricTexture(obj, GL_TRUE);
   gluSphere(obj, SPHERE_RADIUS, 16, 16);
   glEndList();

   gluDeleteQuadric(obj);
}

int
main(int ac, char **av)
{
   fprintf(stderr,
	   "Ray V1.0\nWritten by David Bucciarelli (tech.hmw@plus.it)\n");

   /*
      if(!SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS)) {
      fprintf(stderr,"Error setting the process class.\n");
      return 0;
      }

      if(!SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL)) {
      fprintf(stderr,"Error setting the process priority.\n");
      return 0;
      }
    */

   glutInitWindowSize(WIDTH, HEIGHT);
   glutInit(&ac, av);

   glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);

   if (!(win = glutCreateWindow("Ray"))) {
      fprintf(stderr, "Error, couldn't open window\n");
      return -1;
   }

   reshape(WIDTH, HEIGHT);

   glShadeModel(GL_FLAT);
   glEnable(GL_DEPTH_TEST);
   glDepthFunc(GL_LEQUAL);
   glEnable(GL_CULL_FACE);
   glEnable(GL_TEXTURE_2D);
   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

   glEnable(GL_FOG);
   glFogi(GL_FOG_MODE, GL_EXP2);
   glFogfv(GL_FOG_COLOR, fogcolor);

   glFogf(GL_FOG_DENSITY, 0.01);
#ifdef FX
   glHint(GL_FOG_HINT, GL_NICEST);
#endif

   calcposobs();

   initspherepos();

   inittextures();
   initdlists();

   glClearColor(fogcolor[0], fogcolor[1], fogcolor[2], fogcolor[3]);

   glutReshapeFunc(reshape);
   glutDisplayFunc(draw);
   glutKeyboardFunc(key);
   glutSpecialFunc(special);
   glutIdleFunc(draw);

   glutMainLoop();

   return 0;
}
