This is G o o g l e's cache of http://ironbark.bendigo.latrobe.edu.au/~fran/int32gp/wk12/normal.
G o o g l e's cache is the snapshot that we took of the page as we crawled the web.
The page may have changed since that time. Click here for the current page without highlighting.
To link to or bookmark this page, use the following url: http://www.google.com/search?q=cache:Zd9GGOfCWtIJ:ironbark.bendigo.latrobe.edu.au/~fran/int32gp/wk12/normal+&hl=en&ie=UTF-8


Google is not affiliated with the authors of this page nor responsible for its content.

<html>
<head>
</head><body><pre>&lt;html&gt;
&lt;head&gt;
&lt;/head&gt;&lt;body&gt;&lt;pre&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;pre&amp;gt;/*
** File:          normal2.c
** Description:   Renders a 3D image of x, y, z axes.
** Rev:           1.0
** Created:       06 August 2001
** Last Update:   11 October 2002
** Author:        Fran Soddell
** Email:         F.Soddell@bendigo.latrobe.edu.au
**/
#include &amp;amp;lt;GL/glut.h&amp;amp;gt;
#include &amp;amp;lt;stdio.h&amp;amp;gt;
#include &amp;amp;lt;math.h&amp;amp;gt;
#define TRUE 1
#define FALSE 0
/*
** manage 3D
*/
enum {x,y,z};
/*
** window management
*/
int width=800;
int height=650;
int xPosition=50;
int yPosition=70;
/*
** manage view
*/
GLint xOrigin;
GLint yOrigin;
/*
** manage world projection
*/
enum {xLeft,xRight,yBottom,yTop,zNear,zFar};
GLdouble world[]={
   -2.0,2.0,-2.0,2.0,0.1,1000
};
GLdouble fovy   =90.0;
GLdouble aspect =1.0;
int perspective =FALSE;
/*
** manage camera
*/
GLdouble eye[]={
   2.0,2.0,2.0
};
GLdouble centre[]={
   0,0,0
};
GLdouble up[]={
   0.0,1.0,0.0
};
/*
** manage colour
*/
#define NUM_COLOURS 8
#define ALPHA 0.0
enum {red,green,blue,
      yellow,magenta,cyan,
      white,black};
typedef GLfloat colourType[3];
colourType colour[NUM_COLOURS]={
   {1.0,0.0,0.0},{0.0,1.0,0.0},{0.0,0.0,1.0},
   {1.0,1.0,0.0},{1.0,0.0,1.0},{0.0,1.0,1.0},
   {1.0,1.0,1.0},{0.0,0.0,0.0}
};
/*
**  manage polygonal mesh
*/
#define EDGES 12
#define FACES 6
typedef GLfloat vertexType[3];
vertexType box[8]={
   {-0.5,-0.5,-0.5},{-0.5, 0.5,-0.5},{0.5,0.5,-0.5},{ 0.5,-0.5,-0.5},
   {-0.5,-0.5, 0.5},{ 0.5,-0.5, 0.5},{0.5,0.5, 0.5},{-0.5, 0.5, 0.5}
};
enum {back,front,right,left,top,bottom};
GLint boxFace[FACES][4]={
   {0,1,2,3},{4,5,6,7},
   {3,2,6,5},{4,7,1,0},
   {2,1,7,6},{4,0,3,5}
};
vertexType faceNormal[FACES]={
   {0, 0,-1},{ 0, 0, 1},
   {1, 0, 0},{-1, 0, 0},
   {0, 1, 0},{ 0,-1, 0}
};
vertexType calculatedNormal[FACES];
int calculated = TRUE;
enum {begin,end};
GLint boxEdge[EDGES][2]={
   {0,1},{1,2},{2,3},{3,0},
   {4,5},{5,6},{6,7},{7,4},
   {5,3},{6,2},
   {4,0},{7,1}
};
/*
** manage model transforms
*/
enum {boxMesh,cube};
GLdouble t[][3]={
   {0,0,0},{0,0,0}
};
GLdouble ra[]={
   0,0
};
GLdouble r[3]={
   0,1,0
};
/*
** manage materials
*/
enum {blackPlastic,brass,bronze,
      chrome,copper,gold,
      pewter,silver,polishedSilver};
int currentMaterial=brass;
GLfloat ambient[][3]={
   {0.0,0.0,0.0},
   {0.329412,0.223529,0.027451},
   {0.2125,0.1275,0.054},
   {0.25,0.25,0.25},
   {0.19125,0.0735,0.0225},
   {0.24725,0.1995,0.0745},
   {0.10588,0.058824,0.113725},
   {0.19225,0.19225,0.19225},
   {0.23125,0.23125,0.23125}
   };
GLfloat diffuse[][3]={
   {0.01,0.01,0.01},
   {0.780392,0.568627,0.113725},
   {0.714,0.4284,0.18144},
   {0.4,0.4,0.4},
   {0.7038,0.27048,0.0828},
   {0.75164,0.60648,0.22648},
   {0.427451,0.470588,0.541176},
   {0.50754,0.50754,0.50754},
   {0.2775,0.2775,0.2775}
   };
GLfloat specular[][3]={
   {0.50,0.50,0.50},
   {0.992157,0.941176,0.807843},
   {0.393548,0.271905,0.166721},
   {0.774597,0.774597,0.774597},
   {0.256777,0.137622,0.086014},
   {0.628281,0.555802,0.366065},
   {0.3333,0.3333,0.521569},
   {0.508273,0.508273,0.508273},
   {0.773911,0.773911,0.773911}
   };
GLfloat exponent[]={
   32,27.8974,25.6,
   76.8,12.8,51.2,
   9.84615,51.2,89.6
   };
/*
** manage lighting
*/
GLfloat position[][4]={
   {3, 1, 0, 1.0},
   {0, 2, 0, 1.0},
   {0,-2, 0, 1.0}
   };
enum {ambientLight,diffuseLight,specularLight};
GLfloat light[][3][4]={
   {{1.0,1.0,1.0,1.0},{1.0,1.0,1.0,1.0},{1.0,1.0,1.0,1.0}},
   {{0.9,0.0,0.0,1.0},{0.0,0.0,0.9,1.0},{0.9,0.9,0.0,1.0}},
   {{0.9,0.0,0.0,1.0},{0.0,0.0,0.9,1.0},{0.9,0.9,0.0,1.0}}
   };
/*
**  ***********************************************************
*/
void setMaterial(){
   glMaterialfv(GL_FRONT,GL_SPECULAR,specular[currentMaterial]);
   glMaterialfv(GL_FRONT,GL_AMBIENT,ambient[currentMaterial]);
   glMaterialfv(GL_FRONT,GL_DIFFUSE,diffuse[currentMaterial]);
   glMaterialf(GL_FRONT,GL_SHININESS,exponent[currentMaterial]);
}
void renderAxis(double length){
   glPushMatrix();
   glBegin(GL_LINES);
      glVertex3d(0,0,0);
      glVertex3d(0,0,length);
   glEnd();
   glTranslated(0,0,length-0.2);
   glutWireCone(0.04,0.2,12,9);
   glPopMatrix();
}
void axes(){
   glLineWidth(1);
   glColor3fv(colour[red]);
   /* z-axis */
   renderAxis(1.5);
   glPushMatrix();
   /* y-axis */
   glRotated(90,0,1.0,0);
   glColor3fv(colour[green]);
   renderAxis(1.5);
   /* x-axis */
   glRotated(-90,1,0,0);
   glColor3fv(colour[blue]);
   renderAxis(1.5);
   glPopMatrix();
}
void setCamera(){
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   gluLookAt(eye[x],eye[y],eye[z],
             centre[x],centre[y],centre[z],
             up[x],up[y],up[z]);
}
void setProjection(){
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   if(!perspective)
      glOrtho(world[xLeft],  world[xRight],
              world[yBottom],world[yTop],
              world[zNear],  world[zFar]);
   else
      gluPerspective(fovy,1,world[zNear],world[zFar]);
}
void wireBox(){
   int i;
   glLineWidth(3);
   for (i=0;i&amp;amp;lt;EDGES;i++){
      glBegin(GL_LINES);
         glVertex3fv(box[boxEdge[i][begin]]);
         glVertex3fv(box[boxEdge[i][end]]);
      glEnd();
   }
}
void solidBox(){
  int face,vertex;
  for(face=0;face&amp;amp;lt;FACES;face++){
     if(calculated) glNormal3fv(calculatedNormal[face]);
     else glNormal3fv(faceNormal[face]);
     glBegin(GL_POLYGON);
       for(vertex=0;vertex&amp;amp;lt;4;vertex++){
         glVertex3fv(box[boxFace[face][vertex]]);
       }
     glEnd();
 }
}
void innerBox(){
   int i,j;
   for(i=0;i&amp;amp;lt;FACES;i++){
      glBegin(GL_POLYGON);
      for(j=3;j&amp;amp;gt;=0;j--)
         glVertex3fv(box[boxFace[i][j]]);
      glEnd();
   }
}
void display(){
   /*
   ** Clear the window with the background colour before
   ** (re)rendering.
   */
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   setCamera();
   axes();
   glPushMatrix();
   glTranslated(t[boxMesh][x],t[boxMesh][y],t[boxMesh][z]);
   glRotated(ra[boxMesh],r[x],r[y],r[z]);
   glColor3fv(colour[cyan]);
   setMaterial();
   solidBox();
   glColor3fv(colour[red]);
   innerBox();
   glColor3fv(colour[magenta]);
   wireBox();
   glPopMatrix();
   glPushMatrix();
   glTranslated(t[cube][x],t[cube][y],t[cube][z]);
   glRotated(ra[boxMesh],r[x],r[y],r[z]);
   glutSolidCube(1.0);
   glPopMatrix();
   glutSwapBuffers();
}
void reshapeWindow(int w, int h){
   int yOrigin=0, xOrigin=0;
   /*
   ** When window is resized, retain
   ** image proportions AND ensure
   ** origin remains centred.
   */
   if(w&amp;amp;gt;h){
      yOrigin=(h-w)/2;
      h=w;
   }
   else{
      xOrigin=(w-h)/2;
      w=h;
   }
   glViewport(xOrigin,yOrigin,(GLsizei)w,(GLsizei)h);
   setProjection();
}
void specialKeys(int key,int xMouse,int yMouse){
   int i;
   switch(key){
      case GLUT_KEY_PAGE_UP:   t[boxMesh][z]+=0.1; break;
      case GLUT_KEY_PAGE_DOWN: t[boxMesh][z]-=0.1; break;
      case GLUT_KEY_RIGHT:     t[boxMesh][x]+=0.1; break;
      case GLUT_KEY_LEFT:      t[boxMesh][x]-=0.1; break;
      case GLUT_KEY_UP:        t[boxMesh][y]+=0.1; break;
      case GLUT_KEY_DOWN:      t[boxMesh][y]-=0.1; break;
      case GLUT_KEY_F1:        t[cube][z]+=0.1; break;
      case GLUT_KEY_F2:        t[cube][z]-=0.1; break;
      case GLUT_KEY_F3:        t[cube][x]+=0.1; break;
      case GLUT_KEY_F4:        t[cube][x]-=0.1; break;
      case GLUT_KEY_F5:        t[cube][y]+=0.1; break;
      case GLUT_KEY_F6:        t[cube][y]-=0.1; break;
   }
   glutPostRedisplay();
}
void toggleLight(int light,int index){
  static int on[]={TRUE,TRUE,TRUE};
  if(on[index]==TRUE){
     on[index]=FALSE;
     glDisable(light);
  }
  else{
     on[index]=TRUE;
     glEnable(light);
  }
}
void keyboard(unsigned char key,int xMouse,int yMouse){
   static int depth=TRUE;
   static int cull=TRUE;
   static int lights=TRUE;
   static int flat=TRUE;
   switch(key){
      case 27 : exit(0);
      case &amp;amp;#39;0&amp;amp;#39;: toggleLight(GL_LIGHT0,0);
                break;
      case &amp;amp;#39;1&amp;amp;#39;: toggleLight(GL_LIGHT1,1);
                break;
      case &amp;amp;#39;2&amp;amp;#39;: toggleLight(GL_LIGHT2,2);
                break;
      case &amp;amp;#39;n&amp;amp;#39;: calculated = !calculated;
                break;
      case &amp;amp;#39;m&amp;amp;#39;: currentMaterial++;
                if(currentMaterial&amp;amp;gt;polishedSilver)
                   currentMaterial=blackPlastic;
                break;
      case &amp;amp;#39;p&amp;amp;#39;: perspective=!perspective;
                setProjection();
                break;
      case &amp;amp;#39;f&amp;amp;#39;: if(fovy&amp;amp;lt;180) fovy+=0.5;
                setProjection();
                break;
      case &amp;amp;#39;F&amp;amp;#39;: if(fovy&amp;amp;gt;0) fovy-=0.5;
                setProjection();
                break;
      case &amp;amp;#39;d&amp;amp;#39;: depth=!depth;
                if(depth)
                   glEnable(GL_DEPTH_TEST);
                else
                   glDisable(GL_DEPTH_TEST);
                break;
      case &amp;amp;#39;c&amp;amp;#39;: cull=!cull;
                if(cull)
                   glEnable(GL_CULL_FACE);
                else
                   glDisable(GL_CULL_FACE);
                break;
      case &amp;amp;#39;y&amp;amp;#39;: r[x]=0;r[y]=1;r[z]=0;
                ra[boxMesh]+=1.0;
                if(ra[boxMesh]&amp;amp;gt;=360)ra[boxMesh]=0;
                break;
      case &amp;amp;#39;Y&amp;amp;#39;: r[y]=1;r[x]=0;r[z]=0;
                ra[boxMesh]-=1.0;
                if(ra[boxMesh]&amp;amp;lt;=0)ra[boxMesh]=360;
                break;
      case &amp;amp;#39;x&amp;amp;#39;: r[x]=1;r[y]=0;r[z]=0;
                ra[boxMesh]+=1.0;
                if(ra[boxMesh]&amp;amp;gt;=360)ra[boxMesh]=0;
                break;
      case &amp;amp;#39;X&amp;amp;#39;: r[x]=1;r[y]=0;r[z]=0;
                ra[boxMesh]-=1.0;
                if(ra[boxMesh]&amp;amp;lt;=0)ra[boxMesh]=360;
                break;
      case &amp;amp;#39;z&amp;amp;#39;: r[z]=1;r[x]=0;r[y]=0;
                ra[boxMesh]+=1.0;
                if(ra[boxMesh]&amp;amp;gt;=360)ra[boxMesh]=0;
                break;
      case &amp;amp;#39;Z&amp;amp;#39;: r[z]=1;r[y]=0;r[x]=0;
                ra[boxMesh]-=1.0;
                if(ra[boxMesh]&amp;amp;lt;=0)ra[boxMesh]=360;
                break;

   }
   glutPostRedisplay();
}
void setUpGLUT(int argc,char ** argv){
   glutInit(&amp;amp;amp;argc,argv);
   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
   glutInitWindowSize(width,height);
   glutInitWindowPosition(xPosition,yPosition);
   glutCreateWindow(&amp;amp;quot;Box - Polygonal Mesh&amp;amp;quot;);
   /*
   ** Register callbacks.
   */
   glutDisplayFunc(display);
   glutReshapeFunc(reshapeWindow);
   glutKeyboardFunc(keyboard);
   glutSpecialFunc(specialKeys);
}
void setUpLights(){
   int i,j;
   j=GL_LIGHT0;
   for(i=0;i&amp;amp;lt;3;i++,j++){
      glLightfv(j,GL_POSITION,position[i]);
	   glLightfv(j,GL_AMBIENT,light[i][ambientLight]);
	   glLightfv(j,GL_DIFFUSE,light[i][diffuseLight]);
	   glLightfv(j,GL_SPECULAR,light[i][specularLight]);
      glEnable(j);
   }
}
void initialiseGL(){
   glClearColor(1,1,1,ALPHA);

   glShadeModel(GL_FLAT);
   glCullFace(GL_BACK);
   
   setUpLights();
   glEnable(GL_LIGHTING);
   glEnable(GL_LIGHT0);
   glEnable(GL_DEPTH_TEST);
   glEnable(GL_CULL_FACE);
}
void calculateNormal(vertexType * vertices, GLint * subscript,
                     vertexType * normal, int face){
   GLfloat v1[3],v2[3];
   int coordinate;
   for(coordinate=x;coordinate&amp;amp;lt;=z;coordinate++){
      v1[coordinate]= vertices[subscript[0]][coordinate]
                      - vertices[subscript[1]][coordinate];
      v2[coordinate]= vertices[subscript[1]][coordinate]
                      - vertices[subscript[2]][coordinate];
   }
   normal[face][x]= v1[y]*v2[z] - v1[z]*v2[y];
   normal[face][y]= v1[z]*v2[x] - v1[x]*v2[z];
   normal[face][z]= v1[x]*v2[y] - v1[y]*v2[x];
}
void unitVector(vertexType normal){
   float length;
   length = sqrt(normal[x]*normal[x] + normal[y]*normal[y]
                 + normal[z]*normal[z]);
   if(length==0) length=1;
   normal[x] = normal[x]/length;
   normal[y] = normal[y]/length;
   normal[z] = normal[z]/length;
}
void initialise(){
   int face;
   for(face=0;face&amp;amp;lt;FACES;face++){
      calculateNormal(box,boxFace[face],calculatedNormal,face);
      unitVector(calculatedNormal[face]);
   }
}
int main(int argc,char ** argv){
   initialise();
   setUpGLUT(argc,argv);
   initialiseGL();
   /*
   ** Display window and
   ** enter the GLUT event processing loop.
   */
   glutMainLoop();
   return 0;
}

&amp;lt;/pre&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;&lt;/body&gt;&lt;/html&gt;</pre></body></html>