2 * Copyright (c) 1991, 1992, 1993 Silicon Graphics, Inc.
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that (i) the above copyright notices and this permission notice appear in
7 * all copies of the software and related documentation, and (ii) the name of
8 * Silicon Graphics may not be used in any advertising or
9 * publicity relating to the software without the specific, prior written
10 * permission of Silicon Graphics.
12 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF
14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
17 * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR
18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
32 #define PI 3.14159265358979323846
35 #define GETCOORD(frame, x, y) (&(theMesh.coords[frame*theMesh.numCoords+(x)+(y)*(theMesh.widthX+1)]))
36 #define GETFACET(frame, x, y) (&(theMesh.facets[frame*theMesh.numFacets+(x)+(y)*theMesh.widthX]))
39 GLenum rgb
, doubleBuffer
;
43 GLint colorIndexes1
[3];
44 GLint colorIndexes2
[3];
45 GLenum clearMask
= GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
;
47 GLenum smooth
= GL_FALSE
;
48 GLenum lighting
= GL_TRUE
;
49 GLenum depth
= GL_TRUE
;
50 GLenum stepMode
= GL_FALSE
;
51 GLenum spinMode
= GL_FALSE
;
58 GLint frames
, curFrame
= 0, nextFrame
= 0;
77 GLubyte contourTexture1
[] = {
83 GLubyte contourTexture2
[] = {
90 #if !defined(GLUTCALLBACK)
95 void GLUTCALLBACK
glut_post_redisplay_p(void)
97 static double t0
= -1.;
99 t
= glutGet(GLUT_ELAPSED_TIME
) / 1000.;
112 static void Animate(void)
122 if (nextFrame
|| !stepMode
) {
125 if (curFrame
>= theMesh
.frames
) {
129 if ((nextFrame
|| !stepMode
) && spinMode
) {
130 glRotatef(5.0, 0.0, 0.0, 1.0);
134 for (i
= 0; i
< theMesh
.widthX
; i
++) {
135 glBegin(GL_QUAD_STRIP
);
137 for (j
= 0; j
< theMesh
.widthY
; j
++) {
138 facet
= GETFACET(curFrame
, i
, j
);
139 if (!smooth
&& lighting
) {
140 glNormal3fv(facet
->normal
);
144 thisColor
= facet
->color
;
145 glColor3fv(facet
->color
);
147 thisColor
= facet
->color
;
148 glMaterialfv(GL_FRONT_AND_BACK
, GL_COLOR_INDEXES
,
153 thisColor
= facet
->color
;
154 glColor3fv(facet
->color
);
156 thisColor
= facet
->color
;
157 glIndexf(facet
->color
[1]);
161 if (!lastColor
|| (thisColor
[0] != lastColor
[0] && smooth
)) {
164 glBegin(GL_QUAD_STRIP
);
166 coord
= GETCOORD(curFrame
, i
, j
);
167 if (smooth
&& lighting
) {
168 glNormal3fv(coord
->normal
);
170 glVertex3fv(coord
->vertex
);
172 coord
= GETCOORD(curFrame
, i
+1, j
);
173 if (smooth
&& lighting
) {
174 glNormal3fv(coord
->normal
);
176 glVertex3fv(coord
->vertex
);
179 coord
= GETCOORD(curFrame
, i
, j
+1);
180 if (smooth
&& lighting
) {
181 glNormal3fv(coord
->normal
);
183 glVertex3fv(coord
->vertex
);
185 coord
= GETCOORD(curFrame
, i
+1, j
+1);
186 if (smooth
&& lighting
) {
187 glNormal3fv(coord
->normal
);
189 glVertex3fv(coord
->vertex
);
191 lastColor
= thisColor
;
202 static void SetColorMap(void)
204 static float green
[3] = {0.2, 1.0, 0.2};
205 static float red
[3] = {1.0, 0.2, 0.2};
206 float *color
= 0, percent
;
207 GLint
*indexes
= 0, entries
, i
, j
;
209 entries
= glutGet(GLUT_WINDOW_COLORMAP_SIZE
);
211 colorIndexes1
[0] = 1;
212 colorIndexes1
[1] = 1 + (GLint
)((entries
- 1) * 0.3);
213 colorIndexes1
[2] = (GLint
)((entries
- 1) * 0.5);
214 colorIndexes2
[0] = 1 + (GLint
)((entries
- 1) * 0.5);
215 colorIndexes2
[1] = 1 + (GLint
)((entries
- 1) * 0.8);
216 colorIndexes2
[2] = entries
- 1;
218 for (i
= 0; i
< 2; i
++) {
222 indexes
= colorIndexes1
;
226 indexes
= colorIndexes2
;
230 for (j
= indexes
[0]; j
< indexes
[1]; j
++) {
231 percent
= 0.2 + 0.8 * (j
- indexes
[0]) /
232 (float)(indexes
[1] - indexes
[0]);
233 glutSetColor(j
, percent
*color
[0], percent
*color
[1],
236 for (j
=indexes
[1]; j
<=indexes
[2]; j
++) {
237 percent
= (j
- indexes
[1]) / (float)(indexes
[2] - indexes
[1]);
238 glutSetColor(j
, percent
*(1-color
[0])+color
[0],
239 percent
*(1-color
[1])+color
[1],
240 percent
*(1-color
[2])+color
[2]);
245 static void InitMesh(void)
249 float dp1
[3], dp2
[3];
250 float *pt1
, *pt2
, *pt3
;
251 float angle
, d
, x
, y
;
252 GLint numFacets
, numCoords
, frameNum
, i
, j
;
254 theMesh
.widthX
= widthX
;
255 theMesh
.widthY
= widthY
;
256 theMesh
.frames
= frames
;
258 numFacets
= widthX
* widthY
;
259 numCoords
= (widthX
+ 1) * (widthY
+ 1);
261 theMesh
.numCoords
= numCoords
;
262 theMesh
.numFacets
= numFacets
;
264 theMesh
.coords
= (struct coord
*)malloc(frames
*numCoords
*
265 sizeof(struct coord
));
266 theMesh
.facets
= (struct facet
*)malloc(frames
*numFacets
*
267 sizeof(struct facet
));
268 if (theMesh
.coords
== NULL
|| theMesh
.facets
== NULL
) {
269 printf("Out of memory.\n");
273 for (frameNum
= 0; frameNum
< frames
; frameNum
++) {
274 for (i
= 0; i
<= widthX
; i
++) {
275 x
= i
/ (float)widthX
;
276 for (j
= 0; j
<= widthY
; j
++) {
277 y
= j
/ (float)widthY
;
283 angle
= 2 * PI
* d
+ (2 * PI
/ frames
* frameNum
);
285 coord
= GETCOORD(frameNum
, i
, j
);
287 coord
->vertex
[0] = x
- 0.5;
288 coord
->vertex
[1] = y
- 0.5;
289 coord
->vertex
[2] = (height
- height
* d
) * cos(angle
);
291 coord
->normal
[0] = -(height
/ d
) * x
* ((1 - d
) * 2 * PI
*
292 sin(angle
) + cos(angle
));
293 coord
->normal
[1] = -(height
/ d
) * y
* ((1 - d
) * 2 * PI
*
294 sin(angle
) + cos(angle
));
295 coord
->normal
[2] = -1;
297 d
= 1.0 / sqrt(coord
->normal
[0]*coord
->normal
[0]+
298 coord
->normal
[1]*coord
->normal
[1]+1);
299 coord
->normal
[0] *= d
;
300 coord
->normal
[1] *= d
;
301 coord
->normal
[2] *= d
;
304 for (i
= 0; i
< widthX
; i
++) {
305 for (j
= 0; j
< widthY
; j
++) {
306 facet
= GETFACET(frameNum
, i
, j
);
307 if (((i
/checkerSize
)%2)^(j
/checkerSize
)%2) {
309 facet
->color
[0] = 1.0;
310 facet
->color
[1] = 0.2;
311 facet
->color
[2] = 0.2;
313 facet
->color
[0] = colorIndexes1
[0];
314 facet
->color
[1] = colorIndexes1
[1];
315 facet
->color
[2] = colorIndexes1
[2];
319 facet
->color
[0] = 0.2;
320 facet
->color
[1] = 1.0;
321 facet
->color
[2] = 0.2;
323 facet
->color
[0] = colorIndexes2
[0];
324 facet
->color
[1] = colorIndexes2
[1];
325 facet
->color
[2] = colorIndexes2
[2];
328 pt1
= GETCOORD(frameNum
, i
, j
)->vertex
;
329 pt2
= GETCOORD(frameNum
, i
, j
+1)->vertex
;
330 pt3
= GETCOORD(frameNum
, i
+1, j
+1)->vertex
;
332 dp1
[0] = pt2
[0] - pt1
[0];
333 dp1
[1] = pt2
[1] - pt1
[1];
334 dp1
[2] = pt2
[2] - pt1
[2];
336 dp2
[0] = pt3
[0] - pt2
[0];
337 dp2
[1] = pt3
[1] - pt2
[1];
338 dp2
[2] = pt3
[2] - pt2
[2];
340 facet
->normal
[0] = dp1
[1] * dp2
[2] - dp1
[2] * dp2
[1];
341 facet
->normal
[1] = dp1
[2] * dp2
[0] - dp1
[0] * dp2
[2];
342 facet
->normal
[2] = dp1
[0] * dp2
[1] - dp1
[1] * dp2
[0];
344 d
= 1.0 / sqrt(facet
->normal
[0]*facet
->normal
[0]+
345 facet
->normal
[1]*facet
->normal
[1]+
346 facet
->normal
[2]*facet
->normal
[2]);
348 facet
->normal
[0] *= d
;
349 facet
->normal
[1] *= d
;
350 facet
->normal
[2] *= d
;
356 static void InitMaterials(void)
358 static float ambient
[] = {0.1, 0.1, 0.1, 1.0};
359 static float diffuse
[] = {0.5, 1.0, 1.0, 1.0};
360 static float position
[] = {90.0, 90.0, 150.0, 0.0};
361 static float front_mat_shininess
[] = {60.0};
362 static float front_mat_specular
[] = {0.2, 0.2, 0.2, 1.0};
363 static float front_mat_diffuse
[] = {0.5, 0.28, 0.38, 1.0};
364 static float back_mat_shininess
[] = {60.0};
365 static float back_mat_specular
[] = {0.5, 0.5, 0.2, 1.0};
366 static float back_mat_diffuse
[] = {1.0, 1.0, 0.2, 1.0};
367 static float lmodel_ambient
[] = {1.0, 1.0, 1.0, 1.0};
368 static float lmodel_twoside
[] = {GL_TRUE
};
370 glMatrixMode(GL_PROJECTION
);
371 gluPerspective(90.0, 1.0, 0.5, 10.0);
373 glLightfv(GL_LIGHT0
, GL_AMBIENT
, ambient
);
374 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, diffuse
);
375 glLightfv(GL_LIGHT0
, GL_POSITION
, position
);
376 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, lmodel_ambient
);
377 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE
, lmodel_twoside
);
378 glEnable(GL_LIGHTING
);
381 glMaterialfv(GL_FRONT
, GL_SHININESS
, front_mat_shininess
);
382 glMaterialfv(GL_FRONT
, GL_SPECULAR
, front_mat_specular
);
383 glMaterialfv(GL_FRONT
, GL_DIFFUSE
, front_mat_diffuse
);
384 glMaterialfv(GL_BACK
, GL_SHININESS
, back_mat_shininess
);
385 glMaterialfv(GL_BACK
, GL_SPECULAR
, back_mat_specular
);
386 glMaterialfv(GL_BACK
, GL_DIFFUSE
, back_mat_diffuse
);
388 glColorMaterial(GL_FRONT_AND_BACK
, GL_DIFFUSE
);
392 glEnable(GL_COLOR_MATERIAL
);
398 static void InitTexture(void)
401 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
402 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
403 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
404 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
405 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
408 static void Init(void)
411 glClearColor(0.0, 0.0, 0.0, 0.0);
413 glShadeModel(GL_FLAT
);
417 glEnable(GL_DEPTH_TEST
);
423 glMatrixMode(GL_MODELVIEW
);
424 glTranslatef(0.0, 0.4, -1.8);
425 glScalef(2.0, 2.0, 2.0);
426 glRotatef(-35.0, 1.0, 0.0, 0.0);
427 glRotatef(35.0, 0.0, 0.0, 1.0);
430 static void Reshape(int width
, int height
)
433 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
436 static void Key(unsigned char key
, int x
, int y
)
444 if (contouring
== 1) {
445 static GLfloat map
[4] = {0, 0, 20, 0};
447 glTexImage2D(GL_TEXTURE_2D
, 0, 3, 4, 4, 0, GL_LUMINANCE
,
448 GL_UNSIGNED_BYTE
, (GLvoid
*)contourTexture1
);
449 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_OBJECT_LINEAR
);
450 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_OBJECT_LINEAR
);
451 glTexGenfv(GL_S
, GL_OBJECT_PLANE
, map
);
452 glTexGenfv(GL_T
, GL_OBJECT_PLANE
, map
);
453 glEnable(GL_TEXTURE_2D
);
454 glEnable(GL_TEXTURE_GEN_S
);
455 glEnable(GL_TEXTURE_GEN_T
);
456 } else if (contouring
== 2) {
457 static GLfloat map
[4] = {0, 0, 20, 0};
459 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
460 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
462 glMatrixMode(GL_MODELVIEW
);
464 glTexGenfv(GL_S
, GL_EYE_PLANE
, map
);
465 glTexGenfv(GL_T
, GL_EYE_PLANE
, map
);
469 glDisable(GL_TEXTURE_GEN_S
);
470 glDisable(GL_TEXTURE_GEN_T
);
471 glDisable(GL_TEXTURE_2D
);
477 glShadeModel(GL_SMOOTH
);
479 glShadeModel(GL_FLAT
);
483 lighting
= !lighting
;
485 glEnable(GL_LIGHTING
);
488 glEnable(GL_COLOR_MATERIAL
);
491 glDisable(GL_LIGHTING
);
492 glDisable(GL_LIGHT0
);
494 glDisable(GL_COLOR_MATERIAL
);
501 glEnable(GL_DEPTH_TEST
);
502 clearMask
|= GL_DEPTH_BUFFER_BIT
;
504 glDisable(GL_DEPTH_TEST
);
505 clearMask
&= ~GL_DEPTH_BUFFER_BIT
;
509 stepMode
= !stepMode
;
513 glutIdleFunc(glut_post_redisplay_p
);
522 spinMode
= !spinMode
;
530 static GLenum
Args(int argc
, char **argv
)
535 doubleBuffer
= GL_TRUE
;
542 for (i
= 1; i
< argc
; i
++) {
543 if (strcmp(argv
[i
], "-ci") == 0) {
545 } else if (strcmp(argv
[i
], "-rgb") == 0) {
547 } else if (strcmp(argv
[i
], "-sb") == 0) {
548 doubleBuffer
= GL_FALSE
;
549 } else if (strcmp(argv
[i
], "-db") == 0) {
550 doubleBuffer
= GL_TRUE
;
551 } else if (strcmp(argv
[i
], "-grid") == 0) {
552 if (i
+2 >= argc
|| argv
[i
+1][0] == '-' || argv
[i
+2][0] == '-') {
553 printf("-grid (No numbers).\n");
556 widthX
= atoi(argv
[++i
]);
557 widthY
= atoi(argv
[++i
]);
559 } else if (strcmp(argv
[i
], "-size") == 0) {
560 if (i
+1 >= argc
|| argv
[i
+1][0] == '-') {
561 printf("-checker (No number).\n");
564 checkerSize
= atoi(argv
[++i
]);
566 } else if (strcmp(argv
[i
], "-wave") == 0) {
567 if (i
+1 >= argc
|| argv
[i
+1][0] == '-') {
568 printf("-wave (No number).\n");
571 height
= atof(argv
[++i
]);
573 } else if (strcmp(argv
[i
], "-frames") == 0) {
574 if (i
+1 >= argc
|| argv
[i
+1][0] == '-') {
575 printf("-frames (No number).\n");
578 frames
= atoi(argv
[++i
]);
581 printf("%s (Bad option).\n", argv
[i
]);
588 int main(int argc
, char **argv
)
592 glutInit(&argc
, argv
);
594 if (Args(argc
, argv
) == GL_FALSE
) {
598 glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
601 type
|= (rgb
) ? GLUT_RGB
: GLUT_INDEX
;
602 type
|= (doubleBuffer
) ? GLUT_DOUBLE
: GLUT_SINGLE
;
603 glutInitDisplayMode(type
);
605 if (glutCreateWindow("Wave Demo") == GL_FALSE
) {
613 glutReshapeFunc(Reshape
);
614 glutKeyboardFunc(Key
);
615 glutDisplayFunc(Animate
);
616 glutIdleFunc(glut_post_redisplay_p
);