summaryrefslogtreecommitdiffstats
path: root/progs/samples/wave.c
diff options
context:
space:
mode:
Diffstat (limited to 'progs/samples/wave.c')
-rw-r--r--progs/samples/wave.c619
1 files changed, 619 insertions, 0 deletions
diff --git a/progs/samples/wave.c b/progs/samples/wave.c
new file mode 100644
index 00000000000..d3c4687459e
--- /dev/null
+++ b/progs/samples/wave.c
@@ -0,0 +1,619 @@
+/*
+ * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, provided
+ * that (i) the above copyright notices and this permission notice appear in
+ * all copies of the software and related documentation, and (ii) the name of
+ * Silicon Graphics may not be used in any advertising or
+ * publicity relating to the software without the specific, prior written
+ * permission of Silicon Graphics.
+ *
+ * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
+ * ANY KIND,
+ * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
+ * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
+ * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
+ * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+ * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
+ * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+#include <GL/glut.h>
+
+#ifndef PI
+#define PI 3.14159265358979323846
+#endif
+
+#define GETCOORD(frame, x, y) (&(theMesh.coords[frame*theMesh.numCoords+(x)+(y)*(theMesh.widthX+1)]))
+#define GETFACET(frame, x, y) (&(theMesh.facets[frame*theMesh.numFacets+(x)+(y)*theMesh.widthX]))
+
+
+GLenum rgb, doubleBuffer;
+
+#include "tkmap.c"
+
+GLint colorIndexes1[3];
+GLint colorIndexes2[3];
+GLenum clearMask = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT;
+
+GLenum smooth = GL_FALSE;
+GLenum lighting = GL_TRUE;
+GLenum depth = GL_TRUE;
+GLenum stepMode = GL_FALSE;
+GLenum spinMode = GL_FALSE;
+GLint contouring = 0;
+
+GLint widthX, widthY;
+GLint checkerSize;
+float height;
+
+GLint frames, curFrame = 0, nextFrame = 0;
+
+struct facet {
+ float color[3];
+ float normal[3];
+};
+struct coord {
+ float vertex[3];
+ float normal[3];
+};
+struct mesh {
+ GLint widthX, widthY;
+ GLint numFacets;
+ GLint numCoords;
+ GLint frames;
+ struct coord *coords;
+ struct facet *facets;
+} theMesh;
+
+GLubyte contourTexture1[] = {
+ 255, 255, 255, 255,
+ 255, 255, 255, 255,
+ 255, 255, 255, 255,
+ 127, 127, 127, 127,
+};
+GLubyte contourTexture2[] = {
+ 255, 255, 255, 255,
+ 255, 127, 127, 127,
+ 255, 127, 127, 127,
+ 255, 127, 127, 127,
+};
+
+#if !defined(GLUTCALLBACK)
+#define GLUTCALLBACK
+#endif
+
+
+void GLUTCALLBACK glut_post_redisplay_p(void)
+{
+ static double t0 = -1.;
+ double t, dt;
+ t = glutGet(GLUT_ELAPSED_TIME) / 1000.;
+ if (t0 < 0.)
+ t0 = t;
+ dt = t - t0;
+
+ if (dt < 1./30.)
+ return;
+
+ t0 = t;
+
+ glutPostRedisplay();
+}
+
+static void Animate(void)
+{
+ struct coord *coord;
+ struct facet *facet;
+ float *lastColor;
+ float *thisColor;
+ GLint i, j;
+
+ glClear(clearMask);
+
+ if (nextFrame || !stepMode) {
+ curFrame++;
+ }
+ if (curFrame >= theMesh.frames) {
+ curFrame = 0;
+ }
+
+ if ((nextFrame || !stepMode) && spinMode) {
+ glRotatef(5.0, 0.0, 0.0, 1.0);
+ }
+ nextFrame = 0;
+
+ for (i = 0; i < theMesh.widthX; i++) {
+ glBegin(GL_QUAD_STRIP);
+ lastColor = NULL;
+ for (j = 0; j < theMesh.widthY; j++) {
+ facet = GETFACET(curFrame, i, j);
+ if (!smooth && lighting) {
+ glNormal3fv(facet->normal);
+ }
+ if (lighting) {
+ if (rgb) {
+ thisColor = facet->color;
+ glColor3fv(facet->color);
+ } else {
+ thisColor = facet->color;
+ glMaterialfv(GL_FRONT_AND_BACK, GL_COLOR_INDEXES,
+ facet->color);
+ }
+ } else {
+ if (rgb) {
+ thisColor = facet->color;
+ glColor3fv(facet->color);
+ } else {
+ thisColor = facet->color;
+ glIndexf(facet->color[1]);
+ }
+ }
+
+ if (!lastColor || (thisColor[0] != lastColor[0] && smooth)) {
+ if (lastColor) {
+ glEnd();
+ glBegin(GL_QUAD_STRIP);
+ }
+ coord = GETCOORD(curFrame, i, j);
+ if (smooth && lighting) {
+ glNormal3fv(coord->normal);
+ }
+ glVertex3fv(coord->vertex);
+
+ coord = GETCOORD(curFrame, i+1, j);
+ if (smooth && lighting) {
+ glNormal3fv(coord->normal);
+ }
+ glVertex3fv(coord->vertex);
+ }
+
+ coord = GETCOORD(curFrame, i, j+1);
+ if (smooth && lighting) {
+ glNormal3fv(coord->normal);
+ }
+ glVertex3fv(coord->vertex);
+
+ coord = GETCOORD(curFrame, i+1, j+1);
+ if (smooth && lighting) {
+ glNormal3fv(coord->normal);
+ }
+ glVertex3fv(coord->vertex);
+
+ lastColor = thisColor;
+ }
+ glEnd();
+ }
+
+ glFlush();
+ if (doubleBuffer) {
+ glutSwapBuffers();
+ }
+}
+
+static void SetColorMap(void)
+{
+ static float green[3] = {0.2, 1.0, 0.2};
+ static float red[3] = {1.0, 0.2, 0.2};
+ float *color = 0, percent;
+ GLint *indexes = 0, entries, i, j;
+
+ entries = glutGet(GLUT_WINDOW_COLORMAP_SIZE);
+
+ colorIndexes1[0] = 1;
+ colorIndexes1[1] = 1 + (GLint)((entries - 1) * 0.3);
+ colorIndexes1[2] = (GLint)((entries - 1) * 0.5);
+ colorIndexes2[0] = 1 + (GLint)((entries - 1) * 0.5);
+ colorIndexes2[1] = 1 + (GLint)((entries - 1) * 0.8);
+ colorIndexes2[2] = entries - 1;
+
+ for (i = 0; i < 2; i++) {
+ switch (i) {
+ case 0:
+ color = green;
+ indexes = colorIndexes1;
+ break;
+ case 1:
+ color = red;
+ indexes = colorIndexes2;
+ break;
+ }
+
+ for (j = indexes[0]; j < indexes[1]; j++) {
+ percent = 0.2 + 0.8 * (j - indexes[0]) /
+ (float)(indexes[1] - indexes[0]);
+ glutSetColor(j, percent*color[0], percent*color[1],
+ percent*color[2]);
+ }
+ for (j=indexes[1]; j<=indexes[2]; j++) {
+ percent = (j - indexes[1]) / (float)(indexes[2] - indexes[1]);
+ glutSetColor(j, percent*(1-color[0])+color[0],
+ percent*(1-color[1])+color[1],
+ percent*(1-color[2])+color[2]);
+ }
+ }
+}
+
+static void InitMesh(void)
+{
+ struct coord *coord;
+ struct facet *facet;
+ float dp1[3], dp2[3];
+ float *pt1, *pt2, *pt3;
+ float angle, d, x, y;
+ GLint numFacets, numCoords, frameNum, i, j;
+
+ theMesh.widthX = widthX;
+ theMesh.widthY = widthY;
+ theMesh.frames = frames;
+
+ numFacets = widthX * widthY;
+ numCoords = (widthX + 1) * (widthY + 1);
+
+ theMesh.numCoords = numCoords;
+ theMesh.numFacets = numFacets;
+
+ theMesh.coords = (struct coord *)malloc(frames*numCoords*
+ sizeof(struct coord));
+ theMesh.facets = (struct facet *)malloc(frames*numFacets*
+ sizeof(struct facet));
+ if (theMesh.coords == NULL || theMesh.facets == NULL) {
+ printf("Out of memory.\n");
+ exit(1);
+ }
+
+ for (frameNum = 0; frameNum < frames; frameNum++) {
+ for (i = 0; i <= widthX; i++) {
+ x = i / (float)widthX;
+ for (j = 0; j <= widthY; j++) {
+ y = j / (float)widthY;
+
+ d = sqrt(x*x+y*y);
+ if (d == 0.0) {
+ d = 0.0001;
+ }
+ angle = 2 * PI * d + (2 * PI / frames * frameNum);
+
+ coord = GETCOORD(frameNum, i, j);
+
+ coord->vertex[0] = x - 0.5;
+ coord->vertex[1] = y - 0.5;
+ coord->vertex[2] = (height - height * d) * cos(angle);
+
+ coord->normal[0] = -(height / d) * x * ((1 - d) * 2 * PI *
+ sin(angle) + cos(angle));
+ coord->normal[1] = -(height / d) * y * ((1 - d) * 2 * PI *
+ sin(angle) + cos(angle));
+ coord->normal[2] = -1;
+
+ d = 1.0 / sqrt(coord->normal[0]*coord->normal[0]+
+ coord->normal[1]*coord->normal[1]+1);
+ coord->normal[0] *= d;
+ coord->normal[1] *= d;
+ coord->normal[2] *= d;
+ }
+ }
+ for (i = 0; i < widthX; i++) {
+ for (j = 0; j < widthY; j++) {
+ facet = GETFACET(frameNum, i, j);
+ if (((i/checkerSize)%2)^(j/checkerSize)%2) {
+ if (rgb) {
+ facet->color[0] = 1.0;
+ facet->color[1] = 0.2;
+ facet->color[2] = 0.2;
+ } else {
+ facet->color[0] = colorIndexes1[0];
+ facet->color[1] = colorIndexes1[1];
+ facet->color[2] = colorIndexes1[2];
+ }
+ } else {
+ if (rgb) {
+ facet->color[0] = 0.2;
+ facet->color[1] = 1.0;
+ facet->color[2] = 0.2;
+ } else {
+ facet->color[0] = colorIndexes2[0];
+ facet->color[1] = colorIndexes2[1];
+ facet->color[2] = colorIndexes2[2];
+ }
+ }
+ pt1 = GETCOORD(frameNum, i, j)->vertex;
+ pt2 = GETCOORD(frameNum, i, j+1)->vertex;
+ pt3 = GETCOORD(frameNum, i+1, j+1)->vertex;
+
+ dp1[0] = pt2[0] - pt1[0];
+ dp1[1] = pt2[1] - pt1[1];
+ dp1[2] = pt2[2] - pt1[2];
+
+ dp2[0] = pt3[0] - pt2[0];
+ dp2[1] = pt3[1] - pt2[1];
+ dp2[2] = pt3[2] - pt2[2];
+
+ facet->normal[0] = dp1[1] * dp2[2] - dp1[2] * dp2[1];
+ facet->normal[1] = dp1[2] * dp2[0] - dp1[0] * dp2[2];
+ facet->normal[2] = dp1[0] * dp2[1] - dp1[1] * dp2[0];
+
+ d = 1.0 / sqrt(facet->normal[0]*facet->normal[0]+
+ facet->normal[1]*facet->normal[1]+
+ facet->normal[2]*facet->normal[2]);
+
+ facet->normal[0] *= d;
+ facet->normal[1] *= d;
+ facet->normal[2] *= d;
+ }
+ }
+ }
+}
+
+static void InitMaterials(void)
+{
+ static float ambient[] = {0.1, 0.1, 0.1, 1.0};
+ static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
+ static float position[] = {90.0, 90.0, 150.0, 0.0};
+ static float front_mat_shininess[] = {60.0};
+ static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
+ static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
+ static float back_mat_shininess[] = {60.0};
+ static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
+ static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
+ static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
+ static float lmodel_twoside[] = {GL_TRUE};
+
+ glMatrixMode(GL_PROJECTION);
+ gluPerspective(90.0, 1.0, 0.5, 10.0);
+
+ glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
+ glLightfv(GL_LIGHT0, GL_POSITION, position);
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
+ glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+
+ glMaterialfv(GL_FRONT, GL_SHININESS, front_mat_shininess);
+ glMaterialfv(GL_FRONT, GL_SPECULAR, front_mat_specular);
+ glMaterialfv(GL_FRONT, GL_DIFFUSE, front_mat_diffuse);
+ glMaterialfv(GL_BACK, GL_SHININESS, back_mat_shininess);
+ glMaterialfv(GL_BACK, GL_SPECULAR, back_mat_specular);
+ glMaterialfv(GL_BACK, GL_DIFFUSE, back_mat_diffuse);
+ if (rgb) {
+ glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
+ }
+
+ if (rgb) {
+ glEnable(GL_COLOR_MATERIAL);
+ } else {
+ SetColorMap();
+ }
+}
+
+static void InitTexture(void)
+{
+
+ 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_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+}
+
+static void Init(void)
+{
+
+ glClearColor(0.0, 0.0, 0.0, 0.0);
+
+ glShadeModel(GL_FLAT);
+
+ glFrontFace(GL_CW);
+
+ glEnable(GL_DEPTH_TEST);
+
+ InitMaterials();
+ InitTexture();
+ InitMesh();
+
+ glMatrixMode(GL_MODELVIEW);
+ glTranslatef(0.0, 0.4, -1.8);
+ glScalef(2.0, 2.0, 2.0);
+ glRotatef(-35.0, 1.0, 0.0, 0.0);
+ glRotatef(35.0, 0.0, 0.0, 1.0);
+}
+
+static void Reshape(int width, int height)
+{
+
+ glViewport(0, 0, (GLint)width, (GLint)height);
+}
+
+static void Key(unsigned char key, int x, int y)
+{
+
+ switch (key) {
+ case 27:
+ exit(1);
+ case 'c':
+ contouring++;
+ if (contouring == 1) {
+ static GLfloat map[4] = {0, 0, 20, 0};
+
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, 4, 4, 0, GL_LUMINANCE,
+ GL_UNSIGNED_BYTE, (GLvoid *)contourTexture1);
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+ glTexGenfv(GL_S, GL_OBJECT_PLANE, map);
+ glTexGenfv(GL_T, GL_OBJECT_PLANE, map);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ } else if (contouring == 2) {
+ static GLfloat map[4] = {0, 0, 20, 0};
+
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
+ glPushMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTexGenfv(GL_S, GL_EYE_PLANE, map);
+ glTexGenfv(GL_T, GL_EYE_PLANE, map);
+ glPopMatrix();
+ } else {
+ contouring = 0;
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
+ glDisable(GL_TEXTURE_2D);
+ }
+ break;
+ case 's':
+ smooth = !smooth;
+ if (smooth) {
+ glShadeModel(GL_SMOOTH);
+ } else {
+ glShadeModel(GL_FLAT);
+ }
+ break;
+ case 'l':
+ lighting = !lighting;
+ if (lighting) {
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ if (rgb) {
+ glEnable(GL_COLOR_MATERIAL);
+ }
+ } else {
+ glDisable(GL_LIGHTING);
+ glDisable(GL_LIGHT0);
+ if (rgb) {
+ glDisable(GL_COLOR_MATERIAL);
+ }
+ }
+ break;
+ case 'd':
+ depth = !depth;
+ if (depth) {
+ glEnable(GL_DEPTH_TEST);
+ clearMask |= GL_DEPTH_BUFFER_BIT;
+ } else {
+ glDisable(GL_DEPTH_TEST);
+ clearMask &= ~GL_DEPTH_BUFFER_BIT;
+ }
+ break;
+ case 32:
+ stepMode = !stepMode;
+ if (stepMode) {
+ glutIdleFunc(0);
+ } else {
+ glutIdleFunc(glut_post_redisplay_p);
+ }
+ break;
+ case 'n':
+ if (stepMode) {
+ nextFrame = 1;
+ }
+ break;
+ case 'a':
+ spinMode = !spinMode;
+ break;
+ default:
+ return;
+ }
+ glutPostRedisplay();
+}
+
+static GLenum Args(int argc, char **argv)
+{
+ GLint i;
+
+ rgb = GL_TRUE;
+ doubleBuffer = GL_TRUE;
+ frames = 10;
+ widthX = 10;
+ widthY = 10;
+ checkerSize = 2;
+ height = 0.2;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-ci") == 0) {
+ rgb = GL_FALSE;
+ } else if (strcmp(argv[i], "-rgb") == 0) {
+ rgb = GL_TRUE;
+ } else if (strcmp(argv[i], "-sb") == 0) {
+ doubleBuffer = GL_FALSE;
+ } else if (strcmp(argv[i], "-db") == 0) {
+ doubleBuffer = GL_TRUE;
+ } else if (strcmp(argv[i], "-grid") == 0) {
+ if (i+2 >= argc || argv[i+1][0] == '-' || argv[i+2][0] == '-') {
+ printf("-grid (No numbers).\n");
+ return GL_FALSE;
+ } else {
+ widthX = atoi(argv[++i]);
+ widthY = atoi(argv[++i]);
+ }
+ } else if (strcmp(argv[i], "-size") == 0) {
+ if (i+1 >= argc || argv[i+1][0] == '-') {
+ printf("-checker (No number).\n");
+ return GL_FALSE;
+ } else {
+ checkerSize = atoi(argv[++i]);
+ }
+ } else if (strcmp(argv[i], "-wave") == 0) {
+ if (i+1 >= argc || argv[i+1][0] == '-') {
+ printf("-wave (No number).\n");
+ return GL_FALSE;
+ } else {
+ height = atof(argv[++i]);
+ }
+ } else if (strcmp(argv[i], "-frames") == 0) {
+ if (i+1 >= argc || argv[i+1][0] == '-') {
+ printf("-frames (No number).\n");
+ return GL_FALSE;
+ } else {
+ frames = atoi(argv[++i]);
+ }
+ } else {
+ printf("%s (Bad option).\n", argv[i]);
+ return GL_FALSE;
+ }
+ }
+ return GL_TRUE;
+}
+
+int main(int argc, char **argv)
+{
+ GLenum type;
+
+ glutInit(&argc, argv);
+
+ if (Args(argc, argv) == GL_FALSE) {
+ exit(1);
+ }
+
+ glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
+
+ type = GLUT_DEPTH;
+ type |= (rgb) ? GLUT_RGB : GLUT_INDEX;
+ type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+ glutInitDisplayMode(type);
+
+ if (glutCreateWindow("Wave Demo") == GL_FALSE) {
+ exit(1);
+ }
+
+ InitMap();
+
+ Init();
+
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutDisplayFunc(Animate);
+ glutIdleFunc(glut_post_redisplay_p);
+ glutMainLoop();
+ return 0;
+}