Remove demos that have moved to git+ssh://git.freedesktop.org/git/mesa/demos.
[mesa.git] / progs / demos / shadowtex.c
diff --git a/progs/demos/shadowtex.c b/progs/demos/shadowtex.c
deleted file mode 100644 (file)
index 677a421..0000000
+++ /dev/null
@@ -1,1039 +0,0 @@
-/*
- * Shadow demo using the GL_ARB_depth_texture, GL_ARB_shadow and
- * GL_ARB_shadow_ambient extensions.
- *
- * Brian Paul
- * 19 Feb 2001
- *
- * Added GL_EXT_shadow_funcs support on 23 March 2002
- * Added GL_EXT_packed_depth_stencil support on 15 March 2006.
- * Added GL_EXT_framebuffer_object support on 27 March 2006.
- * Removed old SGIX extension support on 5 April 2006.
- * Added vertex / fragment program support on 7 June 2007 (Ian Romanick).
- *
- * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <GL/glew.h>
-#include <GL/glut.h>
-
-#define DEG_TO_RAD (3.14159 / 180.0)
-
-static GLint WindowWidth = 450, WindowHeight = 300;
-static GLfloat Xrot = 15, Yrot = 0, Zrot = 0;
-
-static GLfloat Red[4] = {1, 0, 0, 1};
-static GLfloat Green[4] = {0, 1, 0, 1};
-static GLfloat Blue[4] = {0, 0, 1, 1};
-static GLfloat Yellow[4] = {1, 1, 0, 1};
-
-static GLfloat LightDist = 10;
-static GLfloat LightLatitude = 45.0;
-static GLfloat LightLongitude = 45.0;
-static GLfloat LightPos[4];
-static GLfloat SpotDir[3];
-static GLfloat SpotAngle = 40.0 * DEG_TO_RAD;
-static GLfloat ShadowNear = 4.0, ShadowFar = 24.0;
-static GLint ShadowTexWidth = 256, ShadowTexHeight = 256;
-
-static GLboolean LinearFilter = GL_FALSE;
-
-static GLfloat Bias = -0.06;
-
-static GLboolean Anim = GL_TRUE;
-
-static GLboolean NeedNewShadowMap = GL_FALSE;
-static GLuint ShadowTexture, GrayTexture;
-static GLuint ShadowFBO;
-
-static GLfloat lightModelview[16];
-static GLfloat lightProjection[16];
-
-static GLuint vert_prog;
-static GLuint frag_progs[3];
-static GLuint curr_frag = 0;
-static GLuint max_frag = 1;
-
-#define NUM_FRAG_MODES 3
-static const char *FragProgNames[] = {
-   "fixed-function",
-   "program without \"OPTION ARB_fragment_program_shadow\"",
-   "program with \"OPTION ARB_fragment_program_shadow\"",
-};
-
-static GLboolean HaveShadow = GL_FALSE;
-static GLboolean HaveFBO = GL_FALSE;
-static GLboolean UseFBO = GL_FALSE;
-static GLboolean HaveVP = GL_FALSE;
-static GLboolean HaveFP = GL_FALSE;
-static GLboolean HaveFP_Shadow = GL_FALSE;
-static GLboolean UseVP = GL_FALSE;
-static GLboolean HavePackedDepthStencil = GL_FALSE;
-static GLboolean UsePackedDepthStencil = GL_FALSE;
-static GLboolean HaveEXTshadowFuncs = GL_FALSE;
-static GLboolean HaveShadowAmbient = GL_FALSE;
-
-static GLint Operator = 0;
-static const GLenum OperatorFunc[8] = {
-   GL_LEQUAL, GL_LESS, GL_GEQUAL, GL_GREATER,
-   GL_EQUAL, GL_NOTEQUAL, GL_ALWAYS, GL_NEVER };
-static const char *OperatorName[8] = {
-   "GL_LEQUAL", "GL_LESS", "GL_GEQUAL", "GL_GREATER",
-   "GL_EQUAL", "GL_NOTEQUAL", "GL_ALWAYS", "GL_NEVER" };
-
-
-static GLuint DisplayMode;
-#define SHOW_SHADOWS        0
-#define SHOW_DEPTH_IMAGE    1
-#define SHOW_DEPTH_MAPPING  2
-#define SHOW_DISTANCE       3
-
-
-
-#define MAT4_MUL(dest_vec, src_mat, src_vec) \
-    "DP4       " dest_vec ".x, " src_mat "[0], " src_vec ";\n" \
-    "DP4       " dest_vec ".y, " src_mat "[1], " src_vec ";\n" \
-    "DP4       " dest_vec ".z, " src_mat "[2], " src_vec ";\n" \
-    "DP4       " dest_vec ".w, " src_mat "[3], " src_vec ";\n"
-
-#define MAT3_MUL(dest_vec, src_mat, src_vec) \
-    "DP3       " dest_vec ".x, " src_mat "[0], " src_vec ";\n" \
-    "DP3       " dest_vec ".y, " src_mat "[1], " src_vec ";\n" \
-    "DP3       " dest_vec ".z, " src_mat "[2], " src_vec ";\n"
-
-#define NORMALIZE(dest, src) \
-    "DP3       " dest ".w, " src ", " src ";\n" \
-    "RSQ       " dest ".w, " dest ".w;\n" \
-    "MUL       " dest ", " src ", " dest ".w;\n"
-   
-/**
- * Vertex program for shadow mapping.
- */
-static const char vert_code[] =
-    "!!ARBvp1.0\n"
-    "ATTRIB iPos        = vertex.position;\n"
-    "ATTRIB iNorm       = vertex.normal;\n"
-
-    "PARAM  mvinv[4]    = { state.matrix.modelview.invtrans };\n"
-    "PARAM  mvp[4]      = { state.matrix.mvp };\n"
-    "PARAM  mv[4]       = { state.matrix.modelview };\n"
-    "PARAM  texmat[4]   = { state.matrix.texture[0] };\n"
-    "PARAM  lightPos    = state.light[0].position;\n"
-    "PARAM  ambientCol  = state.lightprod[0].ambient;\n"
-    "PARAM  diffuseCol  = state.lightprod[0].diffuse;\n"
-
-    "TEMP   n, lightVec;\n"
-    "ALIAS  V = lightVec;\n"
-    "ALIAS  NdotL = n;\n"
-
-    "OUTPUT oPos = result.position;\n"
-    "OUTPUT oColor = result.color;\n"
-    "OUTPUT oTex = result.texcoord[0];\n"
-
-    /* Transform the vertex to clip coordinates. */
-    MAT4_MUL("oPos", "mvp",    "iPos")
-
-    /* Transform the vertex to eye coordinates. */
-    MAT4_MUL("V",    "mv",     "iPos")
-
-    /* Transform the vertex to projected light coordinates. */
-    MAT4_MUL("oTex", "texmat", "iPos")
-
-    /* Transform the normal to eye coordinates. */
-    MAT3_MUL("n",    "mvinv",  "iNorm")
-
-    /* Calculate the vector from the vertex to the light in eye
-     * coordinates.
-     */
-    "SUB       lightVec, lightPos, V;\n"
-    NORMALIZE("lightVec", "lightVec")
-
-    /* Compute diffuse lighting coefficient.
-     */
-    "DP3       NdotL.x, n, lightVec;\n"
-    "MAX       NdotL.x, NdotL.x, {0.0};\n"
-    "MIN       NdotL.x, NdotL.x, {1.0};\n"
-
-    /* Accumulate color contributions.
-     */
-    "MOV       oColor, diffuseCol;\n"
-    "MAD       oColor.xyz, NdotL.x, diffuseCol, ambientCol;\n"
-    "END\n"
-    ;
-
-static const char frag_code[] =
-    "!!ARBfp1.0\n"
-
-    "TEMP   shadow, temp;\n"
-
-    "TXP       shadow, fragment.texcoord[0], texture[0], 2D;\n"
-    "RCP       temp.x, fragment.texcoord[0].w;\n"
-    "MUL       temp.x, temp.x, fragment.texcoord[0].z;\n"
-    "SGE       shadow, shadow.x, temp.x;\n"
-    "MUL       result.color.rgb, fragment.color, shadow.x;\n"
-    "MOV       result.color.a, fragment.color;\n"
-    "END\n"
-    ;
-
-static const char frag_shadow_code[] =
-    "!!ARBfp1.0\n"
-    "OPTION ARB_fragment_program_shadow;\n"
-
-    "TEMP   shadow;\n"
-
-    "TXP       shadow, fragment.texcoord[0], texture[0], SHADOW2D;\n"
-    "MUL       result.color.rgb, fragment.color, shadow.x;\n"
-    "MOV       result.color.a, fragment.color.a;\n"
-    "END\n"
-    ;
-
-static void
-DrawScene(void)
-{
-   GLfloat k = 6;
-
-   /* sphere */
-   glPushMatrix();
-   glTranslatef(1.6, 2.2, 2.7);
-   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Green);
-   glColor4fv(Green);
-   glutSolidSphere(1.5, 15, 15);
-   glPopMatrix();
-   /* dodecahedron */
-   glPushMatrix();
-   glTranslatef(-2.0, 1.2, 2.1);
-   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Red);
-   glColor4fv(Red);
-   glutSolidDodecahedron();
-   glPopMatrix();
-   /* icosahedron */
-   glPushMatrix();
-   glTranslatef(-0.6, 1.3, -0.5);
-   glScalef(1.5, 1.5, 1.5);
-   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Yellow);
-   glColor4fv(Red);
-   glutSolidIcosahedron();
-   glPopMatrix();
-   /* a plane */
-   glPushMatrix();
-   glTranslatef(0, -1.1, 0);
-   glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, Blue);
-   glColor4fv(Blue);
-   glNormal3f(0, 1, 0);
-   glBegin(GL_POLYGON);
-   glVertex3f(-k, 0, -k);
-   glVertex3f( k, 0, -k);
-   glVertex3f( k, 0,  k);
-   glVertex3f(-k, 0,  k);
-   glEnd();
-   glPopMatrix();
-}
-
-
-/**
- * Calculate modelview and project matrices for the light
- * 
- * Stores the results in \c lightProjection (projection matrix) and
- * \c lightModelview (modelview matrix).
- */
-static void
-MakeShadowMatrix(const GLfloat lightPos[4], const GLfloat spotDir[3],
-                 GLfloat spotAngle, GLfloat shadowNear, GLfloat shadowFar)
-{
-   /* compute frustum to enclose spot light cone */
-   const GLfloat d = shadowNear * tan(spotAngle);
-
-   glMatrixMode(GL_PROJECTION);
-   glPushMatrix();
-   glLoadIdentity();
-   glFrustum(-d, d, -d, d, shadowNear, shadowFar);
-   glGetFloatv(GL_PROJECTION_MATRIX, lightProjection);
-   glPopMatrix();
-
-   glMatrixMode(GL_MODELVIEW);
-   glPushMatrix();
-   glLoadIdentity();
-   gluLookAt(lightPos[0], lightPos[1], lightPos[2],
-             lightPos[0] + spotDir[0],
-             lightPos[1] + spotDir[1],
-             lightPos[2] + spotDir[2],
-             0.0, 1.0, 0.0);
-   glGetFloatv(GL_MODELVIEW_MATRIX, lightModelview);
-   glPopMatrix();
-}
-
-
-/**
- * Load \c GL_TEXTURE matrix with light's MVP matrix.
- */
-static void SetShadowTextureMatrix(void)
-{
-   static const GLfloat biasMatrix[16] = {
-      0.5, 0.0, 0.0, 0.0,
-      0.0, 0.5, 0.0, 0.0,
-      0.0, 0.0, 0.5, 0.0,
-      0.5, 0.5, 0.5, 1.0,
-   };
-
-   glMatrixMode(GL_TEXTURE);
-   glLoadMatrixf(biasMatrix);
-   glTranslatef(0.0, 0.0, Bias);
-   glMultMatrixf(lightProjection);
-   glMultMatrixf(lightModelview);
-   glMatrixMode(GL_MODELVIEW);
-}
-
-
-static void
-EnableIdentityTexgen(void)
-{
-   /* texgen so that texcoord = vertex coord */
-   static GLfloat sPlane[4] = { 1, 0, 0, 0 };
-   static GLfloat tPlane[4] = { 0, 1, 0, 0 };
-   static GLfloat rPlane[4] = { 0, 0, 1, 0 };
-   static GLfloat qPlane[4] = { 0, 0, 0, 1 };
-
-   glTexGenfv(GL_S, GL_EYE_PLANE, sPlane);
-   glTexGenfv(GL_T, GL_EYE_PLANE, tPlane);
-   glTexGenfv(GL_R, GL_EYE_PLANE, rPlane);
-   glTexGenfv(GL_Q, GL_EYE_PLANE, qPlane);
-   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-   glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-   glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-   glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-
-   glEnable(GL_TEXTURE_GEN_S);
-   glEnable(GL_TEXTURE_GEN_T);
-   glEnable(GL_TEXTURE_GEN_R);
-   glEnable(GL_TEXTURE_GEN_Q);
-}
-
-
-/*
- * Setup 1-D texgen so that the distance from the light source, between
- * the near and far planes maps to s=0 and s=1.  When we draw the scene,
- * the grayness will indicate the fragment's distance from the light
- * source.
- */
-static void
-EnableDistanceTexgen(const GLfloat lightPos[4], const GLfloat lightDir[3],
-                     GLfloat lightNear, GLfloat lightFar)
-{
-   GLfloat m, d;
-   GLfloat sPlane[4];
-   GLfloat nearPoint[3];
-
-   m = sqrt(lightDir[0] * lightDir[0] +
-            lightDir[1] * lightDir[1] +
-            lightDir[2] * lightDir[2]);
-
-   d = lightFar - lightNear;
-
-   /* nearPoint = point on light direction vector which intersects the
-    * near plane of the light frustum.
-    */
-   nearPoint[0] = lightPos[0] + lightDir[0] / m * lightNear;
-   nearPoint[1] = lightPos[1] + lightDir[1] / m * lightNear;
-   nearPoint[2] = lightPos[2] + lightDir[2] / m * lightNear;
-
-   sPlane[0] = lightDir[0] / d / m;
-   sPlane[1] = lightDir[1] / d / m;
-   sPlane[2] = lightDir[2] / d / m;
-   sPlane[3] = -(sPlane[0] * nearPoint[0]
-               + sPlane[1] * nearPoint[1]
-               + sPlane[2] * nearPoint[2]);
-
-   glTexGenfv(GL_S, GL_EYE_PLANE, sPlane);
-   glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
-   glEnable(GL_TEXTURE_GEN_S);
-}
-
-
-static void
-DisableTexgen(void)
-{
-   glDisable(GL_TEXTURE_GEN_S);
-   glDisable(GL_TEXTURE_GEN_T);
-   glDisable(GL_TEXTURE_GEN_R);
-   glDisable(GL_TEXTURE_GEN_Q);
-}
-
-
-static void
-ComputeLightPos(GLfloat dist, GLfloat latitude, GLfloat longitude,
-                GLfloat pos[4], GLfloat dir[3])
-{
-
-   pos[0] = dist * sin(longitude * DEG_TO_RAD);
-   pos[1] = dist * sin(latitude * DEG_TO_RAD);
-   pos[2] = dist * cos(latitude * DEG_TO_RAD) * cos(longitude * DEG_TO_RAD);
-   pos[3] = 1;
-   dir[0] = -pos[0];
-   dir[1] = -pos[1];
-   dir[2] = -pos[2];
-}
-
-
-/**
- * Render the shadow map / depth texture.
- * The result will be in the texture object named ShadowTexture.
- */
-static void
-RenderShadowMap(void)
-{
-   GLenum depthFormat; /* GL_DEPTH_COMPONENT or GL_DEPTH_STENCIL_EXT */
-   GLenum depthType; /* GL_UNSIGNED_INT_24_8_EXT or GL_UNSIGNED_INT */
-
-   if (WindowWidth >= 1024 && WindowHeight >= 1024) {
-      ShadowTexWidth = ShadowTexHeight = 1024;
-   }
-   else if (WindowWidth >= 512 && WindowHeight >= 512) {
-      ShadowTexWidth = ShadowTexHeight = 512;
-   }
-   else if (WindowWidth >= 256 && WindowHeight >= 256) {
-      ShadowTexWidth = ShadowTexHeight = 256;
-   }
-   else {
-      ShadowTexWidth = ShadowTexHeight = 128;
-   }
-   printf("Rendering %d x %d depth texture\n", ShadowTexWidth, ShadowTexHeight);
-
-   if (UsePackedDepthStencil) {
-      depthFormat = GL_DEPTH_STENCIL_EXT;
-      depthType = GL_UNSIGNED_INT_24_8_EXT;
-   }
-   else {
-      depthFormat = GL_DEPTH_COMPONENT;
-      depthType = GL_UNSIGNED_INT;
-   }
-
-   glMatrixMode(GL_PROJECTION);
-   glLoadMatrixf(lightProjection);
-
-   glMatrixMode(GL_MODELVIEW);
-   glLoadMatrixf(lightModelview);
-
-   if (UseFBO) {
-      GLenum fbo_status;
-
-      glTexImage2D(GL_TEXTURE_2D, 0, depthFormat,
-                   ShadowTexWidth, ShadowTexHeight, 0,
-                   depthFormat, depthType, NULL);
-
-      /* Set the filter mode so that the texture is texture-complete.
-       * Otherwise it will cause the framebuffer to fail the framebuffer
-       * completeness test.
-       */
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-
-      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ShadowFBO);
-      glDrawBuffer(GL_NONE);
-      glReadBuffer(GL_NONE);
-
-      fbo_status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
-      if (fbo_status != GL_FRAMEBUFFER_COMPLETE_EXT) {
-         fprintf(stderr, "FBO not complete!  status = 0x%04x\n", fbo_status);
-         assert(fbo_status == GL_FRAMEBUFFER_COMPLETE_EXT);
-      }
-   }
-
-   assert(!glIsEnabled(GL_TEXTURE_1D));
-   assert(!glIsEnabled(GL_TEXTURE_2D));
-
-   glViewport(0, 0, ShadowTexWidth, ShadowTexHeight);
-   glClear(GL_DEPTH_BUFFER_BIT);
-   glEnable(GL_DEPTH_TEST);
-   DrawScene();
-
-   if (UseFBO) {
-      /* all done! */
-      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-   }
-   else {
-      /*
-       * copy depth buffer into the texture map
-       */
-      if (DisplayMode == SHOW_DEPTH_MAPPING) {
-         /* load depth image as gray-scale luminance texture */
-         GLuint *depth = (GLuint *)
-            malloc(ShadowTexWidth * ShadowTexHeight * sizeof(GLuint));
-         assert(depth);
-         glReadPixels(0, 0, ShadowTexWidth, ShadowTexHeight,
-                      depthFormat, depthType, depth);
-         glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE,
-                      ShadowTexWidth, ShadowTexHeight, 0,
-                      GL_LUMINANCE, GL_UNSIGNED_INT, depth);
-         free(depth);
-      }
-      else {
-         /* The normal shadow case - a real depth texture */
-         glCopyTexImage2D(GL_TEXTURE_2D, 0, depthFormat,
-                          0, 0, ShadowTexWidth, ShadowTexHeight, 0);
-         if (UsePackedDepthStencil) {
-            /* debug check */
-            GLint intFormat;
-            glGetTexLevelParameteriv(GL_TEXTURE_2D, 0,
-                                     GL_TEXTURE_INTERNAL_FORMAT, &intFormat);
-            assert(intFormat == GL_DEPTH_STENCIL_EXT);
-         }
-      }
-   }
-}
-
-
-/**
- * Show the shadow map as a grayscale image.
- */
-static void
-ShowShadowMap(void)
-{
-   glClear(GL_COLOR_BUFFER_BIT);
-
-   glMatrixMode(GL_TEXTURE);
-   glLoadIdentity();
-
-   glMatrixMode(GL_PROJECTION);
-   glLoadIdentity();
-   glOrtho(0, WindowWidth, 0, WindowHeight, -1, 1);
-
-   glMatrixMode(GL_MODELVIEW);
-   glLoadIdentity();
-
-   glDisable(GL_DEPTH_TEST);
-   glDisable(GL_LIGHTING);
-
-   glEnable(GL_TEXTURE_2D);
-
-   DisableTexgen();
-
-   /* interpret texture's depth values as luminance values */
-   if (HaveShadow) {
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
-   }
-
-   glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);
-   glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-
-   glBegin(GL_POLYGON);
-   glTexCoord2f(0, 0);  glVertex2f(0, 0);
-   glTexCoord2f(1, 0);  glVertex2f(ShadowTexWidth, 0);
-   glTexCoord2f(1, 1);  glVertex2f(ShadowTexWidth, ShadowTexHeight);
-   glTexCoord2f(0, 1);  glVertex2f(0, ShadowTexHeight);
-   glEnd();
-
-   glDisable(GL_TEXTURE_2D);
-   glEnable(GL_DEPTH_TEST);
-   glEnable(GL_LIGHTING);
-}
-
-
-/**
- * Redraw window image
- */
-static void
-Display(void)
-{
-   GLenum error;
-
-   ComputeLightPos(LightDist, LightLatitude, LightLongitude,
-                   LightPos, SpotDir);
-
-   if (NeedNewShadowMap) {
-      MakeShadowMatrix(LightPos, SpotDir, SpotAngle, ShadowNear, ShadowFar);
-      RenderShadowMap();
-      NeedNewShadowMap = GL_FALSE;
-   }
-
-   glViewport(0, 0, WindowWidth, WindowHeight);
-   if (DisplayMode == SHOW_DEPTH_IMAGE) {
-      ShowShadowMap();
-   }
-   else {
-      /* prepare to draw scene from camera's view */
-      const GLfloat ar = (GLfloat) WindowWidth / (GLfloat) WindowHeight;
-
-      glMatrixMode(GL_PROJECTION);
-      glLoadIdentity();
-      glFrustum(-ar, ar, -1.0, 1.0, 4.0, 50.0);
-
-      glMatrixMode(GL_MODELVIEW);
-      glLoadIdentity();
-      glTranslatef(0.0, 0.0, -22.0);
-      glRotatef(Xrot, 1, 0, 0);
-      glRotatef(Yrot, 0, 1, 0);
-      glRotatef(Zrot, 0, 0, 1);
-
-      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
-
-      glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
-
-      if (LinearFilter) {
-         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-      }
-      else {
-         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
-         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-      }
-
-      if (DisplayMode == SHOW_DEPTH_MAPPING) {
-         if (HaveShadow) {
-            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
-         }
-         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-         glEnable(GL_TEXTURE_2D);
-
-         SetShadowTextureMatrix();
-         EnableIdentityTexgen();
-      }
-      else if (DisplayMode == SHOW_DISTANCE) {
-         glMatrixMode(GL_TEXTURE);
-         glLoadIdentity();
-         glMatrixMode(GL_MODELVIEW);
-         EnableDistanceTexgen(LightPos, SpotDir, ShadowNear+Bias, ShadowFar);
-         glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-         glEnable(GL_TEXTURE_1D);
-         assert(!glIsEnabled(GL_TEXTURE_2D));
-      }
-      else {
-         assert(DisplayMode == SHOW_SHADOWS);
-         if (HaveShadow) {
-            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
-                            GL_COMPARE_R_TO_TEXTURE_ARB);
-         }
-
-         if (curr_frag > 0) {
-            glEnable(GL_FRAGMENT_PROGRAM_ARB);
-         }
-         else {
-            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-         }
-         glEnable(GL_TEXTURE_2D);
-
-         SetShadowTextureMatrix();
-
-         if (UseVP) {
-            glEnable(GL_VERTEX_PROGRAM_ARB);
-         }
-         else {
-            glEnable(GL_LIGHTING);
-            EnableIdentityTexgen();
-         }
-      }
-
-      DrawScene();
-
-      if (UseVP) {
-         glDisable(GL_VERTEX_PROGRAM_ARB);
-      }
-      else {
-         DisableTexgen();
-         glDisable(GL_LIGHTING);
-      }
-
-      if (curr_frag > 0) {
-         glDisable(GL_FRAGMENT_PROGRAM_ARB);
-      }
-
-      glDisable(GL_TEXTURE_1D);
-      glDisable(GL_TEXTURE_2D);
-   }
-
-   glutSwapBuffers();
-
-   error = glGetError();
-   if (error) {
-      printf("GL Error: %s\n", (char *) gluErrorString(error));
-   }
-}
-
-
-static void
-Reshape(int width, int height)
-{
-   WindowWidth = width;
-   WindowHeight = height;
-   NeedNewShadowMap = GL_TRUE;
-}
-
-
-static void
-Idle(void)
-{
-   static double t0 = -1.;
-   double dt, t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
-   if (t0 < 0.0)
-      t0 = t;
-   dt = t - t0;
-   t0 = t;
-   Yrot += 75.0 * dt;
-   /*LightLongitude -= 5.0;*/
-   glutPostRedisplay();
-}
-
-
-static void
-Key(unsigned char key, int x, int y)
-{
-   const GLfloat step = 3.0;
-   (void) x;
-   (void) y;
-   switch (key) {
-      case 'a':
-         Anim = !Anim;
-         if (Anim)
-            glutIdleFunc(Idle);
-         else
-            glutIdleFunc(NULL);
-         break;
-      case 'b':
-         Bias -= 0.01;
-         printf("Bias %g\n", Bias);
-         break;
-      case 'B':
-         Bias += 0.01;
-         printf("Bias %g\n", Bias);
-         break;
-      case 'd':
-         DisplayMode = SHOW_DISTANCE;
-         break;
-      case 'f':
-         LinearFilter = !LinearFilter;
-         printf("%s filtering\n", LinearFilter ? "Bilinear" : "Nearest");
-         break;
-      case 'i':
-         DisplayMode = SHOW_DEPTH_IMAGE;
-         break;
-      case 'm':
-         DisplayMode = SHOW_DEPTH_MAPPING;
-         break;
-      case 'M':
-         curr_frag = (1 + curr_frag) % max_frag;
-         if (!HaveShadow && (curr_frag == 0)) {
-            curr_frag = 1;
-         }
-
-         printf("Using fragment %s\n", FragProgNames[curr_frag]);
-
-         if (HaveFP) {
-            glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, frag_progs[curr_frag]);
-         }
-         break;
-      case 'n':
-      case 's':
-      case ' ':
-         DisplayMode = SHOW_SHADOWS;
-         break;
-      case 'o':
-         if (HaveEXTshadowFuncs) {
-            Operator++;
-            if (Operator >= 8)
-               Operator = 0;
-            printf("Operator: %s\n", OperatorName[Operator]);
-            if (HaveShadow) {
-               glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB,
-                               OperatorFunc[Operator]);
-            }
-         }
-         break;
-      case 'p':
-         UsePackedDepthStencil = !UsePackedDepthStencil;
-         if (UsePackedDepthStencil && !HavePackedDepthStencil) {
-            printf("Sorry, GL_EXT_packed_depth_stencil not supported\n");
-            UsePackedDepthStencil = GL_FALSE;
-         }
-         else {
-            printf("Use GL_DEPTH_STENCIL_EXT: %d\n", UsePackedDepthStencil);
-            /* Don't really need to regenerate shadow map texture, but do so
-             * to exercise more code more often.
-             */
-            NeedNewShadowMap = GL_TRUE;
-         }
-         break;
-      case 'v':
-         UseVP = !UseVP && HaveVP;
-         printf("Using vertex %s mode.\n",
-                UseVP ? "program" : "fixed-function");
-         break;
-      case 'z':
-         Zrot -= step;
-         break;
-      case 'Z':
-         Zrot += step;
-         break;
-      case 27:
-         exit(0);
-         break;
-   }
-   fflush(stdout);
-   glutPostRedisplay();
-}
-
-
-static void
-SpecialKey(int key, int x, int y)
-{
-   const GLfloat step = 3.0;
-   const int mod = glutGetModifiers();
-   (void) x;
-   (void) y;
-   switch (key) {
-      case GLUT_KEY_UP:
-         if (mod)
-            LightLatitude += step;
-         else
-            Xrot += step;
-         break;
-      case GLUT_KEY_DOWN:
-         if (mod)
-            LightLatitude -= step;
-         else
-            Xrot -= step;
-         break;
-      case GLUT_KEY_LEFT:
-         if (mod)
-            LightLongitude += step;
-         else
-            Yrot += step;
-         break;
-      case GLUT_KEY_RIGHT:
-         if (mod)
-            LightLongitude -= step;
-         else
-            Yrot -= step;
-         break;
-   }
-   if (mod)
-      NeedNewShadowMap = GL_TRUE;
-
-   glutPostRedisplay();
-}
-
-
-/* A helper for finding errors in program strings */
-static int FindLine( const char *program, int position )
-{
-   int i, line = 1;
-   for (i = 0; i < position; i++) {
-      if (program[i] == '\n')
-         line++;
-   }
-   return line;
-}
-
-
-static GLuint
-compile_program(GLenum target, const char *code)
-{
-   GLuint p;
-   GLint errorPos;
-
-
-   glGenProgramsARB(1, & p);
-
-   glBindProgramARB(target, p);
-   glProgramStringARB(target, GL_PROGRAM_FORMAT_ASCII_ARB,
-                      strlen(code), code);
-   glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorPos);
-   if (glGetError() != GL_NO_ERROR || errorPos != -1) {
-      int l = FindLine(code, errorPos);
-      printf("Fragment Program Error (pos=%d line=%d): %s\n", errorPos, l,
-             (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
-      exit(0);
-   }
-
-   glBindProgramARB(target, 0);
-   return p;
-}
-
-static void
-Init(void)
-{
-   static const GLfloat borderColor[4] = {1.0, 0.0, 0.0, 0.0};
-
-   if (!glutExtensionSupported("GL_ARB_depth_texture")) {
-      printf("Sorry, this demo requires the GL_ARB_depth_texture extension\n");
-      exit(1);
-   }
-
-   HaveShadow = glutExtensionSupported("GL_ARB_shadow");
-   HaveVP = glutExtensionSupported("GL_ARB_vertex_program");
-   HaveFP = glutExtensionSupported("GL_ARB_fragment_program");
-   HaveFP_Shadow = glutExtensionSupported("GL_ARB_fragment_program_shadow");
-
-   if (!HaveShadow && !HaveFP) {
-      printf("Sorry, this demo requires either the GL_ARB_shadow extension "
-            "or the GL_ARB_fragment_program extension\n");
-      exit(1);
-   }
-
-   printf("Using GL_ARB_depth_texture\n");
-   if (HaveShadow) {
-      printf("and GL_ARB_shadow\n");
-   }
-
-   if (HaveFP) {
-      printf("and GL_ARB_fragment_program\n");
-   }
-
-   HaveShadowAmbient = glutExtensionSupported("GL_ARB_shadow_ambient");
-   if (HaveShadowAmbient) {
-      printf("and GL_ARB_shadow_ambient\n");
-   }
-
-   HaveEXTshadowFuncs = glutExtensionSupported("GL_EXT_shadow_funcs");
-
-   HavePackedDepthStencil = glutExtensionSupported("GL_EXT_packed_depth_stencil");
-   UsePackedDepthStencil = HavePackedDepthStencil;
-
-#if defined(GL_EXT_framebuffer_object)
-   HaveFBO = glutExtensionSupported("GL_EXT_framebuffer_object");
-   UseFBO = HaveFBO;
-   if (UseFBO) {
-      printf("Using GL_EXT_framebuffer_object\n");
-   }
-#endif
-
-   /*
-    * Set up the 2D shadow map texture
-    */
-   glGenTextures(1, &ShadowTexture);
-   glBindTexture(GL_TEXTURE_2D, ShadowTexture);
-   glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
-   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-
-   if (HaveShadow) {
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB,
-                      GL_COMPARE_R_TO_TEXTURE_ARB);
-      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
-   }
-
-   if (HaveShadowAmbient) {
-      glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FAIL_VALUE_ARB, 0.3);
-   }
-
-#if defined(GL_EXT_framebuffer_object)
-   if (UseFBO) {
-      glGenFramebuffersEXT(1, &ShadowFBO);
-      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, ShadowFBO);
-      glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
-                                   GL_COLOR_ATTACHMENT0_EXT,
-                                   GL_RENDERBUFFER_EXT, 0);
-      glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT,
-                                GL_TEXTURE_2D, ShadowTexture, 0);
-
-      glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
-   }
-#endif
-
-   /*
-    * Setup 1-D grayscale texture image for SHOW_DISTANCE mode
-    */
-   glGenTextures(1, &GrayTexture);
-   glBindTexture(GL_TEXTURE_1D, GrayTexture);
-   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP);
-   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-   glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-   {
-      GLuint i;
-      GLubyte image[256];
-      for (i = 0; i < 256; i++)
-         image[i] = i;
-      glTexImage1D(GL_TEXTURE_1D, 0, GL_LUMINANCE,
-                   256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image);
-   }
-
-   if (HaveVP) {
-      vert_prog = compile_program(GL_VERTEX_PROGRAM_ARB, vert_code);
-      glBindProgramARB(GL_VERTEX_PROGRAM_ARB, vert_prog);
-   }
-
-   max_frag = 1;
-   frag_progs[0] = 0;
-
-   if (HaveFP) {
-      frag_progs[1] = compile_program(GL_FRAGMENT_PROGRAM_ARB, frag_code);
-      max_frag = 2;
-   }
-   
-   if (HaveFP && HaveFP_Shadow) {
-      frag_progs[2] = compile_program(GL_FRAGMENT_PROGRAM_ARB, 
-                                      frag_shadow_code);
-      max_frag = 3;
-   }
-
-   if (!HaveShadow) {
-      curr_frag = 1;
-      glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, frag_progs[curr_frag]);
-   }
-
-   glEnable(GL_DEPTH_TEST);
-   glEnable(GL_LIGHTING);
-   glEnable(GL_LIGHT0);
-}
-
-
-static void
-PrintHelp(void)
-{
-   printf("Keys:\n");
-   printf("  a = toggle animation\n");
-   printf("  i = show depth texture image\n");
-   printf("  m = show depth texture mapping\n");
-   printf("  d = show fragment distance from light source\n");
-   printf("  n = show normal, shadowed image\n");
-   printf("  f = toggle nearest/bilinear texture filtering\n");
-   printf("  b/B = decrease/increase shadow map Z bias\n");
-   printf("  p = toggle use of packed depth/stencil\n");
-   printf("  M = cycle through fragment program modes\n");
-   printf("  v = toggle vertex program modes\n");
-   printf("  cursor keys = rotate scene\n");
-   printf("  <shift> + cursor keys = rotate light source\n");
-   if (HaveEXTshadowFuncs)
-      printf("  o = cycle through comparison modes\n");
-   fflush(stdout);
-}
-
-
-int
-main(int argc, char *argv[])
-{
-   glutInitWindowSize(WindowWidth, WindowHeight);
-   glutInit(&argc, argv);
-   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
-   glutCreateWindow(argv[0]);
-   glewInit();
-   glutReshapeFunc(Reshape);
-   glutKeyboardFunc(Key);
-   glutSpecialFunc(SpecialKey);
-   glutDisplayFunc(Display);
-   if (Anim)
-      glutIdleFunc(Idle);
-   Init();
-   PrintHelp();
-   glutMainLoop();
-   return 0;
-}