132001f49Smrg/*
232001f49Smrg * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
332001f49Smrg *
432001f49Smrg * Permission to use, copy, modify, distribute, and sell this software and
532001f49Smrg * its documentation for any purpose is hereby granted without fee, provided
632001f49Smrg * that (i) the above copyright notices and this permission notice appear in
732001f49Smrg * all copies of the software and related documentation, and (ii) the name of
832001f49Smrg * Silicon Graphics may not be used in any advertising or
932001f49Smrg * publicity relating to the software without the specific, prior written
1032001f49Smrg * permission of Silicon Graphics.
1132001f49Smrg *
1232001f49Smrg * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
1332001f49Smrg * ANY KIND,
1432001f49Smrg * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
1532001f49Smrg * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
1632001f49Smrg *
1732001f49Smrg * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
1832001f49Smrg * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
1932001f49Smrg * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
2032001f49Smrg * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
2132001f49Smrg * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
2232001f49Smrg * OF THIS SOFTWARE.
2332001f49Smrg */
2432001f49Smrg
2532001f49Smrg#include <stdio.h>
2632001f49Smrg#include <string.h>
2732001f49Smrg#include <stdlib.h>
2832001f49Smrg#include <math.h>
2932001f49Smrg#include "glut_wrap.h"
3032001f49Smrg
3132001f49Smrg#ifndef PI
3232001f49Smrg#define PI 3.14159265358979323846
3332001f49Smrg#endif
3432001f49Smrg
3532001f49Smrg#define GETCOORD(frame, x, y) (&(theMesh.coords[frame*theMesh.numCoords+(x)+(y)*(theMesh.widthX+1)]))
3632001f49Smrg#define GETFACET(frame, x, y) (&(theMesh.facets[frame*theMesh.numFacets+(x)+(y)*theMesh.widthX]))
3732001f49Smrg
3832001f49Smrg
3932001f49SmrgGLenum rgb, doubleBuffer;
4032001f49Smrg
4132001f49Smrg#include "tkmap.c"
4232001f49Smrg
4332001f49SmrgGLint colorIndexes1[3];
4432001f49SmrgGLint colorIndexes2[3];
4532001f49SmrgGLenum clearMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
4632001f49Smrg
4732001f49SmrgGLenum smooth = GL_FALSE;
4832001f49SmrgGLenum lighting = GL_TRUE;
4932001f49SmrgGLenum depth = GL_TRUE;
5032001f49SmrgGLenum stepMode = GL_FALSE;
5132001f49SmrgGLenum spinMode = GL_FALSE;
5232001f49SmrgGLint contouring = 0;
5332001f49Smrg
5432001f49SmrgGLint widthX, widthY;
5532001f49SmrgGLint checkerSize;
5632001f49Smrgfloat height;
5732001f49Smrg
5832001f49SmrgGLint frames, curFrame = 0, nextFrame = 0;
5932001f49Smrg
6032001f49Smrgstruct facet {
6132001f49Smrg    float color[3];
6232001f49Smrg    float normal[3];
6332001f49Smrg};
6432001f49Smrgstruct coord {
6532001f49Smrg    float vertex[3];
6632001f49Smrg    float normal[3];
6732001f49Smrg};
6832001f49Smrgstruct mesh {
6932001f49Smrg    GLint widthX, widthY;
7032001f49Smrg    GLint numFacets;
7132001f49Smrg    GLint numCoords;
7232001f49Smrg    GLint frames;
7332001f49Smrg    struct coord *coords;
7432001f49Smrg    struct facet *facets;
7532001f49Smrg} theMesh;
7632001f49Smrg
7732001f49SmrgGLubyte contourTexture1[] = {
7832001f49Smrg    255, 255, 255, 255,
7932001f49Smrg    255, 255, 255, 255,
8032001f49Smrg    255, 255, 255, 255,
8132001f49Smrg    127, 127, 127, 127,
8232001f49Smrg};
8332001f49SmrgGLubyte contourTexture2[] = {
8432001f49Smrg    255, 255, 255, 255,
8532001f49Smrg    255, 127, 127, 127,
8632001f49Smrg    255, 127, 127, 127,
8732001f49Smrg    255, 127, 127, 127,
8832001f49Smrg};
8932001f49Smrg
9032001f49Smrg#if !defined(GLUTCALLBACK)
9132001f49Smrg#define GLUTCALLBACK
9232001f49Smrg#endif
9332001f49Smrg
9432001f49Smrg
9532001f49Smrgstatic void GLUTCALLBACK glut_post_redisplay_p(void)
9632001f49Smrg{
9732001f49Smrg    static double t0 = -1.;
9832001f49Smrg    double t, dt;
9932001f49Smrg    t = glutGet(GLUT_ELAPSED_TIME) / 1000.;
10032001f49Smrg    if (t0 < 0.)
10132001f49Smrg       t0 = t;
10232001f49Smrg    dt = t - t0;
10332001f49Smrg
10432001f49Smrg    if (dt < 1./30.)
10532001f49Smrg        return;
10632001f49Smrg
10732001f49Smrg    t0 = t;
10832001f49Smrg
10932001f49Smrg    glutPostRedisplay();
11032001f49Smrg}
11132001f49Smrg
11232001f49Smrgstatic void Animate(void)
11332001f49Smrg{
11432001f49Smrg    struct coord *coord;
11532001f49Smrg    struct facet *facet;
11632001f49Smrg    float *lastColor;
11732001f49Smrg    float *thisColor;
11832001f49Smrg    GLint i, j;
11932001f49Smrg
12032001f49Smrg    glClear(clearMask);
12132001f49Smrg
12232001f49Smrg    if (nextFrame || !stepMode) {
12332001f49Smrg	curFrame++;
12432001f49Smrg    }
12532001f49Smrg    if (curFrame >= theMesh.frames) {
12632001f49Smrg	curFrame = 0;
12732001f49Smrg    }
12832001f49Smrg
12932001f49Smrg    if ((nextFrame || !stepMode) && spinMode) {
13032001f49Smrg	glRotatef(5.0, 0.0, 0.0, 1.0);
13132001f49Smrg    }
13232001f49Smrg    nextFrame = 0;
13332001f49Smrg
13432001f49Smrg    for (i = 0; i < theMesh.widthX; i++) {
13532001f49Smrg	glBegin(GL_QUAD_STRIP);
13632001f49Smrg	lastColor = NULL;
13732001f49Smrg	for (j = 0; j < theMesh.widthY; j++) {
13832001f49Smrg	    facet = GETFACET(curFrame, i, j);
13932001f49Smrg	    if (!smooth && lighting) {
14032001f49Smrg		glNormal3fv(facet->normal);
14132001f49Smrg	    }
14232001f49Smrg	    if (lighting) {
14332001f49Smrg		if (rgb) {
14432001f49Smrg		    thisColor = facet->color;
14532001f49Smrg		    glColor3fv(facet->color);
14632001f49Smrg		} else {
14732001f49Smrg		    thisColor = facet->color;
14832001f49Smrg		    glMaterialfv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES,
14932001f49Smrg				 facet->color);
15032001f49Smrg		}
15132001f49Smrg	    } else {
15232001f49Smrg		if (rgb) {
15332001f49Smrg		    thisColor = facet->color;
15432001f49Smrg		    glColor3fv(facet->color);
15532001f49Smrg		} else {
15632001f49Smrg		    thisColor = facet->color;
15732001f49Smrg		    glIndexf(facet->color[1]);
15832001f49Smrg		}
15932001f49Smrg	    }
16032001f49Smrg
16132001f49Smrg	    if (!lastColor || (thisColor[0] != lastColor[0] && smooth)) {
16232001f49Smrg		if (lastColor) {
16332001f49Smrg		    glEnd();
16432001f49Smrg		    glBegin(GL_QUAD_STRIP);
16532001f49Smrg		}
16632001f49Smrg		coord = GETCOORD(curFrame, i, j);
16732001f49Smrg		if (smooth && lighting) {
16832001f49Smrg		    glNormal3fv(coord->normal);
16932001f49Smrg		}
17032001f49Smrg		glVertex3fv(coord->vertex);
17132001f49Smrg
17232001f49Smrg		coord = GETCOORD(curFrame, i+1, j);
17332001f49Smrg		if (smooth && lighting) {
17432001f49Smrg		    glNormal3fv(coord->normal);
17532001f49Smrg		}
17632001f49Smrg		glVertex3fv(coord->vertex);
17732001f49Smrg	    }
17832001f49Smrg
17932001f49Smrg	    coord = GETCOORD(curFrame, i, j+1);
18032001f49Smrg	    if (smooth && lighting) {
18132001f49Smrg		glNormal3fv(coord->normal);
18232001f49Smrg	    }
18332001f49Smrg	    glVertex3fv(coord->vertex);
18432001f49Smrg
18532001f49Smrg	    coord = GETCOORD(curFrame, i+1, j+1);
18632001f49Smrg	    if (smooth && lighting) {
18732001f49Smrg		glNormal3fv(coord->normal);
18832001f49Smrg	    }
18932001f49Smrg	    glVertex3fv(coord->vertex);
19032001f49Smrg
19132001f49Smrg	    lastColor = thisColor;
19232001f49Smrg	}
19332001f49Smrg	glEnd();
19432001f49Smrg    }
19532001f49Smrg
19632001f49Smrg    glFlush();
19732001f49Smrg    if (doubleBuffer) {
19832001f49Smrg	glutSwapBuffers();
19932001f49Smrg    }
20032001f49Smrg}
20132001f49Smrg
20232001f49Smrgstatic void SetColorMap(void)
20332001f49Smrg{
20432001f49Smrg    static float green[3] = {0.2, 1.0, 0.2};
20532001f49Smrg    static float red[3] = {1.0, 0.2, 0.2};
20632001f49Smrg    float *color = 0, percent;
20732001f49Smrg    GLint *indexes = 0, entries, i, j;
20832001f49Smrg
20932001f49Smrg    entries = glutGet(GLUT_WINDOW_COLORMAP_SIZE);
21032001f49Smrg
21132001f49Smrg    colorIndexes1[0] = 1;
21232001f49Smrg    colorIndexes1[1] = 1 + (GLint)((entries - 1) * 0.3);
21332001f49Smrg    colorIndexes1[2] = (GLint)((entries - 1) * 0.5);
21432001f49Smrg    colorIndexes2[0] = 1 + (GLint)((entries - 1) * 0.5);
21532001f49Smrg    colorIndexes2[1] = 1 + (GLint)((entries - 1) * 0.8);
21632001f49Smrg    colorIndexes2[2] = entries - 1;
21732001f49Smrg
21832001f49Smrg    for (i = 0; i < 2; i++) {
21932001f49Smrg	switch (i) {
22032001f49Smrg	  case 0:
22132001f49Smrg	    color = green;
22232001f49Smrg	    indexes = colorIndexes1;
22332001f49Smrg	    break;
22432001f49Smrg	  case 1:
22532001f49Smrg	    color = red;
22632001f49Smrg	    indexes = colorIndexes2;
22732001f49Smrg	    break;
22832001f49Smrg	}
22932001f49Smrg
23032001f49Smrg	for (j = indexes[0]; j < indexes[1]; j++) {
23132001f49Smrg	    percent = 0.2 + 0.8 * (j - indexes[0]) /
23232001f49Smrg		      (float)(indexes[1] - indexes[0]);
23332001f49Smrg	    glutSetColor(j, percent*color[0], percent*color[1],
23432001f49Smrg			   percent*color[2]);
23532001f49Smrg	}
23632001f49Smrg	for (j=indexes[1]; j<=indexes[2]; j++) {
23732001f49Smrg	    percent = (j - indexes[1]) / (float)(indexes[2] - indexes[1]);
23832001f49Smrg	    glutSetColor(j, percent*(1-color[0])+color[0],
23932001f49Smrg			   percent*(1-color[1])+color[1],
24032001f49Smrg			   percent*(1-color[2])+color[2]);
24132001f49Smrg	}
24232001f49Smrg    }
24332001f49Smrg}
24432001f49Smrg
24532001f49Smrgstatic void InitMesh(void)
24632001f49Smrg{
24732001f49Smrg    struct coord *coord;
24832001f49Smrg    struct facet *facet;
24932001f49Smrg    float dp1[3], dp2[3];
25032001f49Smrg    float *pt1, *pt2, *pt3;
25132001f49Smrg    float angle, d, x, y;
25232001f49Smrg    GLint numFacets, numCoords, frameNum, i, j;
25332001f49Smrg
25432001f49Smrg    theMesh.widthX = widthX;
25532001f49Smrg    theMesh.widthY = widthY;
25632001f49Smrg    theMesh.frames = frames;
25732001f49Smrg
25832001f49Smrg    numFacets = widthX * widthY;
25932001f49Smrg    numCoords = (widthX + 1) * (widthY + 1);
26032001f49Smrg
26132001f49Smrg    theMesh.numCoords = numCoords;
26232001f49Smrg    theMesh.numFacets = numFacets;
26332001f49Smrg
26432001f49Smrg    theMesh.coords = (struct coord *)malloc(frames*numCoords*
26532001f49Smrg					    sizeof(struct coord));
26632001f49Smrg    theMesh.facets = (struct facet *)malloc(frames*numFacets*
26732001f49Smrg					    sizeof(struct facet));
26832001f49Smrg    if (theMesh.coords == NULL || theMesh.facets == NULL) {
26932001f49Smrg	printf("Out of memory.\n");
27032001f49Smrg	exit(1);
27132001f49Smrg    }
27232001f49Smrg
27332001f49Smrg    for (frameNum = 0; frameNum < frames; frameNum++) {
27432001f49Smrg	for (i = 0; i <= widthX; i++) {
27532001f49Smrg	    x = i / (float)widthX;
27632001f49Smrg	    for (j = 0; j <= widthY; j++) {
27732001f49Smrg		y = j / (float)widthY;
27832001f49Smrg
27932001f49Smrg		d = sqrt(x*x+y*y);
28032001f49Smrg		if (d == 0.0) {
28132001f49Smrg		    d = 0.0001;
28232001f49Smrg		}
28332001f49Smrg		angle = 2 * PI * d + (2 * PI / frames * frameNum);
28432001f49Smrg
28532001f49Smrg		coord = GETCOORD(frameNum, i, j);
28632001f49Smrg
28732001f49Smrg		coord->vertex[0] = x - 0.5;
28832001f49Smrg		coord->vertex[1] = y - 0.5;
28932001f49Smrg		coord->vertex[2] = (height - height * d) * cos(angle);
29032001f49Smrg
29132001f49Smrg		coord->normal[0] = -(height / d) * x * ((1 - d) * 2 * PI *
29232001f49Smrg				   sin(angle) + cos(angle));
29332001f49Smrg		coord->normal[1] = -(height / d) * y * ((1 - d) * 2 * PI *
29432001f49Smrg				   sin(angle) + cos(angle));
29532001f49Smrg		coord->normal[2] = -1;
29632001f49Smrg
29732001f49Smrg		d = 1.0 / sqrt(coord->normal[0]*coord->normal[0]+
29832001f49Smrg			       coord->normal[1]*coord->normal[1]+1);
29932001f49Smrg		coord->normal[0] *= d;
30032001f49Smrg		coord->normal[1] *= d;
30132001f49Smrg		coord->normal[2] *= d;
30232001f49Smrg	    }
30332001f49Smrg	}
30432001f49Smrg	for (i = 0; i < widthX; i++) {
30532001f49Smrg	    for (j = 0; j < widthY; j++) {
30632001f49Smrg		facet = GETFACET(frameNum, i, j);
30732001f49Smrg		if (((i/checkerSize)%2)^(j/checkerSize)%2) {
30832001f49Smrg		    if (rgb) {
30932001f49Smrg			facet->color[0] = 1.0;
31032001f49Smrg			facet->color[1] = 0.2;
31132001f49Smrg			facet->color[2] = 0.2;
31232001f49Smrg		    } else {
31332001f49Smrg			facet->color[0] = colorIndexes1[0];
31432001f49Smrg			facet->color[1] = colorIndexes1[1];
31532001f49Smrg			facet->color[2] = colorIndexes1[2];
31632001f49Smrg		    }
31732001f49Smrg		} else {
31832001f49Smrg		    if (rgb) {
31932001f49Smrg			facet->color[0] = 0.2;
32032001f49Smrg			facet->color[1] = 1.0;
32132001f49Smrg			facet->color[2] = 0.2;
32232001f49Smrg		    } else {
32332001f49Smrg			facet->color[0] = colorIndexes2[0];
32432001f49Smrg			facet->color[1] = colorIndexes2[1];
32532001f49Smrg			facet->color[2] = colorIndexes2[2];
32632001f49Smrg		    }
32732001f49Smrg		}
32832001f49Smrg		pt1 = GETCOORD(frameNum, i, j)->vertex;
32932001f49Smrg		pt2 = GETCOORD(frameNum, i, j+1)->vertex;
33032001f49Smrg		pt3 = GETCOORD(frameNum, i+1, j+1)->vertex;
33132001f49Smrg
33232001f49Smrg		dp1[0] = pt2[0] - pt1[0];
33332001f49Smrg		dp1[1] = pt2[1] - pt1[1];
33432001f49Smrg		dp1[2] = pt2[2] - pt1[2];
33532001f49Smrg
33632001f49Smrg		dp2[0] = pt3[0] - pt2[0];
33732001f49Smrg		dp2[1] = pt3[1] - pt2[1];
33832001f49Smrg		dp2[2] = pt3[2] - pt2[2];
33932001f49Smrg
34032001f49Smrg		facet->normal[0] = dp1[1] * dp2[2] - dp1[2] * dp2[1];
34132001f49Smrg		facet->normal[1] = dp1[2] * dp2[0] - dp1[0] * dp2[2];
34232001f49Smrg		facet->normal[2] = dp1[0] * dp2[1] - dp1[1] * dp2[0];
34332001f49Smrg
34432001f49Smrg		d = 1.0 / sqrt(facet->normal[0]*facet->normal[0]+
34532001f49Smrg			       facet->normal[1]*facet->normal[1]+
34632001f49Smrg			       facet->normal[2]*facet->normal[2]);
34732001f49Smrg
34832001f49Smrg		facet->normal[0] *= d;
34932001f49Smrg		facet->normal[1] *= d;
35032001f49Smrg		facet->normal[2] *= d;
35132001f49Smrg	    }
35232001f49Smrg	}
35332001f49Smrg    }
35432001f49Smrg}
35532001f49Smrg
35632001f49Smrgstatic void InitMaterials(void)
35732001f49Smrg{
35832001f49Smrg    static float ambient[] = {0.1, 0.1, 0.1, 1.0};
35932001f49Smrg    static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
36032001f49Smrg    static float position[] = {90.0, 90.0, 150.0, 0.0};
36132001f49Smrg    static float front_mat_shininess[] = {60.0};
36232001f49Smrg    static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
36332001f49Smrg    static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
36432001f49Smrg    static float back_mat_shininess[] = {60.0};
36532001f49Smrg    static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
36632001f49Smrg    static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
36732001f49Smrg    static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
36832001f49Smrg    static float lmodel_twoside[] = {GL_TRUE};
36932001f49Smrg
37032001f49Smrg    glMatrixMode(GL_PROJECTION);
37132001f49Smrg    gluPerspective(90.0, 1.0, 0.5, 10.0);
37232001f49Smrg
37332001f49Smrg    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
37432001f49Smrg    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
37532001f49Smrg    glLightfv(GL_LIGHT0, GL_POSITION, position);
37632001f49Smrg    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
37732001f49Smrg    glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
37832001f49Smrg    glEnable(GL_LIGHTING);
37932001f49Smrg    glEnable(GL_LIGHT0);
38032001f49Smrg
38132001f49Smrg    glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
38232001f49Smrg    glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
38332001f49Smrg    glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
38432001f49Smrg    glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
38532001f49Smrg    glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
38632001f49Smrg    glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
38732001f49Smrg    if (rgb) {
38832001f49Smrg	glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
38932001f49Smrg    }
39032001f49Smrg
39132001f49Smrg    if (rgb) {
39232001f49Smrg	glEnable(GL_COLOR_MATERIAL);
39332001f49Smrg    } else {
39432001f49Smrg	SetColorMap();
39532001f49Smrg    }
39632001f49Smrg}
39732001f49Smrg
39832001f49Smrgstatic void InitTexture(void)
39932001f49Smrg{
40032001f49Smrg
40132001f49Smrg    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
40232001f49Smrg    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
40332001f49Smrg    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
40432001f49Smrg    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
40532001f49Smrg    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
40632001f49Smrg}
40732001f49Smrg
40832001f49Smrgstatic void Init(void)
40932001f49Smrg{
41032001f49Smrg
41132001f49Smrg    glClearColor(0.0, 0.0, 0.0, 0.0);
41232001f49Smrg
41332001f49Smrg    glShadeModel(GL_FLAT);
41432001f49Smrg
41532001f49Smrg    glFrontFace(GL_CW);
41632001f49Smrg
41732001f49Smrg    glEnable(GL_DEPTH_TEST);
41832001f49Smrg
41932001f49Smrg    InitMaterials();
42032001f49Smrg    InitTexture();
42132001f49Smrg    InitMesh();
42232001f49Smrg
42332001f49Smrg    glMatrixMode(GL_MODELVIEW);
42432001f49Smrg    glTranslatef(0.0, 0.4, -1.8);
42532001f49Smrg    glScalef(2.0, 2.0, 2.0);
42632001f49Smrg    glRotatef(-35.0, 1.0, 0.0, 0.0);
42732001f49Smrg    glRotatef(35.0, 0.0, 0.0, 1.0);
42832001f49Smrg}
42932001f49Smrg
43032001f49Smrgstatic void Reshape(int width, int height)
43132001f49Smrg{
43232001f49Smrg
43332001f49Smrg    glViewport(0, 0, (GLint)width, (GLint)height);
43432001f49Smrg}
43532001f49Smrg
43632001f49Smrgstatic void Key(unsigned char key, int x, int y)
43732001f49Smrg{
43832001f49Smrg
43932001f49Smrg    switch (key) {
44032001f49Smrg      case 27:
44132001f49Smrg	exit(1);
44232001f49Smrg      case 'c':
44332001f49Smrg	contouring++;
44432001f49Smrg	if (contouring == 1) {
44532001f49Smrg	    static GLfloat map[4] = {0, 0, 20, 0};
44632001f49Smrg
44732001f49Smrg	    glTexImage2D(GL_TEXTURE_2D, 0, 3, 4, 4, 0, GL_LUMINANCE,
44832001f49Smrg			 GL_UNSIGNED_BYTE, (GLvoid *)contourTexture1);
44932001f49Smrg	    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
45032001f49Smrg	    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
45132001f49Smrg	    glTexGenfv(GL_S, GL_OBJECT_PLANE, map);
45232001f49Smrg	    glTexGenfv(GL_T, GL_OBJECT_PLANE, map);
45332001f49Smrg	    glEnable(GL_TEXTURE_2D);
45432001f49Smrg	    glEnable(GL_TEXTURE_GEN_S);
45532001f49Smrg	    glEnable(GL_TEXTURE_GEN_T);
45632001f49Smrg	} else if (contouring == 2) {
45732001f49Smrg	    static GLfloat map[4] = {0, 0, 20, 0};
45832001f49Smrg
45932001f49Smrg	    glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
46032001f49Smrg	    glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
46132001f49Smrg	    glPushMatrix();
46232001f49Smrg	    glMatrixMode(GL_MODELVIEW);
46332001f49Smrg	    glLoadIdentity();
46432001f49Smrg	    glTexGenfv(GL_S, GL_EYE_PLANE, map);
46532001f49Smrg	    glTexGenfv(GL_T, GL_EYE_PLANE, map);
46632001f49Smrg	    glPopMatrix();
46732001f49Smrg	} else {
46832001f49Smrg	    contouring = 0;
46932001f49Smrg	    glDisable(GL_TEXTURE_GEN_S);
47032001f49Smrg	    glDisable(GL_TEXTURE_GEN_T);
47132001f49Smrg	    glDisable(GL_TEXTURE_2D);
47232001f49Smrg	}
47332001f49Smrg	break;
47432001f49Smrg      case 's':
47532001f49Smrg	smooth = !smooth;
47632001f49Smrg	if (smooth) {
47732001f49Smrg	    glShadeModel(GL_SMOOTH);
47832001f49Smrg	} else {
47932001f49Smrg	    glShadeModel(GL_FLAT);
48032001f49Smrg	}
48132001f49Smrg	break;
48232001f49Smrg      case 'l':
48332001f49Smrg	lighting = !lighting;
48432001f49Smrg	if (lighting) {
48532001f49Smrg	    glEnable(GL_LIGHTING);
48632001f49Smrg	    glEnable(GL_LIGHT0);
48732001f49Smrg	    if (rgb) {
48832001f49Smrg		glEnable(GL_COLOR_MATERIAL);
48932001f49Smrg	    }
49032001f49Smrg	} else {
49132001f49Smrg	    glDisable(GL_LIGHTING);
49232001f49Smrg	    glDisable(GL_LIGHT0);
49332001f49Smrg	    if (rgb) {
49432001f49Smrg		glDisable(GL_COLOR_MATERIAL);
49532001f49Smrg	    }
49632001f49Smrg	}
49732001f49Smrg	break;
49832001f49Smrg      case 'd':
49932001f49Smrg	depth = !depth;
50032001f49Smrg	if (depth) {
50132001f49Smrg	    glEnable(GL_DEPTH_TEST);
50232001f49Smrg	    clearMask |= GL_DEPTH_BUFFER_BIT;
50332001f49Smrg	} else {
50432001f49Smrg	    glDisable(GL_DEPTH_TEST);
50532001f49Smrg	    clearMask &= ~GL_DEPTH_BUFFER_BIT;
50632001f49Smrg	}
50732001f49Smrg	break;
50832001f49Smrg      case 32:
50932001f49Smrg	stepMode = !stepMode;
51032001f49Smrg	if (stepMode) {
51132001f49Smrg	    glutIdleFunc(0);
51232001f49Smrg	} else {
51332001f49Smrg	    glutIdleFunc(glut_post_redisplay_p);
51432001f49Smrg	}
51532001f49Smrg	break;
51632001f49Smrg      case 'n':
51732001f49Smrg	if (stepMode) {
51832001f49Smrg	    nextFrame = 1;
51932001f49Smrg	}
52032001f49Smrg	break;
52132001f49Smrg      case 'a':
52232001f49Smrg	spinMode = !spinMode;
52332001f49Smrg	break;
52432001f49Smrg      default:
52532001f49Smrg	return;
52632001f49Smrg    }
52732001f49Smrg    glutPostRedisplay();
52832001f49Smrg}
52932001f49Smrg
53032001f49Smrgstatic GLenum Args(int argc, char **argv)
53132001f49Smrg{
53232001f49Smrg    GLint i;
53332001f49Smrg
53432001f49Smrg    rgb = GL_TRUE;
53532001f49Smrg    doubleBuffer = GL_TRUE;
53632001f49Smrg    frames = 10;
53732001f49Smrg    widthX = 10;
53832001f49Smrg    widthY = 10;
53932001f49Smrg    checkerSize = 2;
54032001f49Smrg    height = 0.2;
54132001f49Smrg
54232001f49Smrg    for (i = 1; i < argc; i++) {
54332001f49Smrg	if (strcmp(argv[i], "-ci") == 0) {
54432001f49Smrg	    rgb = GL_FALSE;
54532001f49Smrg	} else if (strcmp(argv[i], "-rgb") == 0) {
54632001f49Smrg	    rgb = GL_TRUE;
54732001f49Smrg	} else if (strcmp(argv[i], "-sb") == 0) {
54832001f49Smrg	    doubleBuffer = GL_FALSE;
54932001f49Smrg	} else if (strcmp(argv[i], "-db") == 0) {
55032001f49Smrg	    doubleBuffer = GL_TRUE;
55132001f49Smrg	} else if (strcmp(argv[i], "-grid") == 0) {
55232001f49Smrg	    if (i+2 >= argc || argv[i+1][0] == '-' || argv[i+2][0] == '-') {
55332001f49Smrg		printf("-grid (No numbers).\n");
55432001f49Smrg		return GL_FALSE;
55532001f49Smrg	    } else {
55632001f49Smrg		widthX = atoi(argv[++i]);
55732001f49Smrg		widthY = atoi(argv[++i]);
55832001f49Smrg	    }
55932001f49Smrg	} else if (strcmp(argv[i], "-size") == 0) {
56032001f49Smrg	    if (i+1 >= argc || argv[i+1][0] == '-') {
56132001f49Smrg		printf("-checker (No number).\n");
56232001f49Smrg		return GL_FALSE;
56332001f49Smrg	    } else {
56432001f49Smrg		checkerSize = atoi(argv[++i]);
56532001f49Smrg	    }
56632001f49Smrg	} else if (strcmp(argv[i], "-wave") == 0) {
56732001f49Smrg	    if (i+1 >= argc || argv[i+1][0] == '-') {
56832001f49Smrg		printf("-wave (No number).\n");
56932001f49Smrg		return GL_FALSE;
57032001f49Smrg	    } else {
57132001f49Smrg		height = atof(argv[++i]);
57232001f49Smrg	    }
57332001f49Smrg	} else if (strcmp(argv[i], "-frames") == 0) {
57432001f49Smrg	    if (i+1 >= argc || argv[i+1][0] == '-') {
57532001f49Smrg		printf("-frames (No number).\n");
57632001f49Smrg		return GL_FALSE;
57732001f49Smrg	    } else {
57832001f49Smrg		frames = atoi(argv[++i]);
57932001f49Smrg	    }
58032001f49Smrg	} else {
58132001f49Smrg	    printf("%s (Bad option).\n", argv[i]);
58232001f49Smrg	    return GL_FALSE;
58332001f49Smrg	}
58432001f49Smrg    }
58532001f49Smrg    return GL_TRUE;
58632001f49Smrg}
58732001f49Smrg
58832001f49Smrgint main(int argc, char **argv)
58932001f49Smrg{
59032001f49Smrg    GLenum type;
59132001f49Smrg
59232001f49Smrg    glutInit(&argc, argv);
59332001f49Smrg
59432001f49Smrg    if (Args(argc, argv) == GL_FALSE) {
59532001f49Smrg	exit(1);
59632001f49Smrg    }
59732001f49Smrg
59832001f49Smrg    glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
59932001f49Smrg
60032001f49Smrg    type = GLUT_DEPTH;
60132001f49Smrg    type |= (rgb) ? GLUT_RGB : GLUT_INDEX;
60232001f49Smrg    type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
60332001f49Smrg    glutInitDisplayMode(type);
60432001f49Smrg
60532001f49Smrg    if (glutCreateWindow("Wave Demo") == GL_FALSE) {
60632001f49Smrg	exit(1);
60732001f49Smrg    }
60832001f49Smrg
60932001f49Smrg    InitMap();
61032001f49Smrg
61132001f49Smrg    Init();
61232001f49Smrg
61332001f49Smrg    glutReshapeFunc(Reshape);
61432001f49Smrg    glutKeyboardFunc(Key);
61532001f49Smrg    glutDisplayFunc(Animate);
61632001f49Smrg    glutIdleFunc(glut_post_redisplay_p);
61732001f49Smrg    glutMainLoop();
61832001f49Smrg	return 0;
61932001f49Smrg}
620