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 void GLUTCALLBACK
glut_post_redisplay_p(void)
95 static void Animate(void)
105 if (nextFrame
|| !stepMode
) {
108 if (curFrame
>= theMesh
.frames
) {
112 if ((nextFrame
|| !stepMode
) && spinMode
) {
113 glRotatef(5.0, 0.0, 0.0, 1.0);
117 for (i
= 0; i
< theMesh
.widthX
; i
++) {
118 glBegin(GL_QUAD_STRIP
);
120 for (j
= 0; j
< theMesh
.widthY
; j
++) {
121 facet
= GETFACET(curFrame
, i
, j
);
122 if (!smooth
&& lighting
) {
123 glNormal3fv(facet
->normal
);
127 thisColor
= facet
->color
;
128 glColor3fv(facet
->color
);
130 thisColor
= facet
->color
;
131 glMaterialfv(GL_FRONT_AND_BACK
, GL_COLOR_INDEXES
,
136 thisColor
= facet
->color
;
137 glColor3fv(facet
->color
);
139 thisColor
= facet
->color
;
140 glIndexf(facet
->color
[1]);
144 if (!lastColor
|| (thisColor
[0] != lastColor
[0] && smooth
)) {
147 glBegin(GL_QUAD_STRIP
);
149 coord
= GETCOORD(curFrame
, i
, j
);
150 if (smooth
&& lighting
) {
151 glNormal3fv(coord
->normal
);
153 glVertex3fv(coord
->vertex
);
155 coord
= GETCOORD(curFrame
, i
+1, j
);
156 if (smooth
&& lighting
) {
157 glNormal3fv(coord
->normal
);
159 glVertex3fv(coord
->vertex
);
162 coord
= GETCOORD(curFrame
, i
, j
+1);
163 if (smooth
&& lighting
) {
164 glNormal3fv(coord
->normal
);
166 glVertex3fv(coord
->vertex
);
168 coord
= GETCOORD(curFrame
, i
+1, j
+1);
169 if (smooth
&& lighting
) {
170 glNormal3fv(coord
->normal
);
172 glVertex3fv(coord
->vertex
);
174 lastColor
= thisColor
;
185 static void SetColorMap(void)
187 static float green
[3] = {0.2, 1.0, 0.2};
188 static float red
[3] = {1.0, 0.2, 0.2};
189 float *color
= 0, percent
;
190 GLint
*indexes
= 0, entries
, i
, j
;
192 entries
= glutGet(GLUT_WINDOW_COLORMAP_SIZE
);
194 colorIndexes1
[0] = 1;
195 colorIndexes1
[1] = 1 + (GLint
)((entries
- 1) * 0.3);
196 colorIndexes1
[2] = (GLint
)((entries
- 1) * 0.5);
197 colorIndexes2
[0] = 1 + (GLint
)((entries
- 1) * 0.5);
198 colorIndexes2
[1] = 1 + (GLint
)((entries
- 1) * 0.8);
199 colorIndexes2
[2] = entries
- 1;
201 for (i
= 0; i
< 2; i
++) {
205 indexes
= colorIndexes1
;
209 indexes
= colorIndexes2
;
213 for (j
= indexes
[0]; j
< indexes
[1]; j
++) {
214 percent
= 0.2 + 0.8 * (j
- indexes
[0]) /
215 (float)(indexes
[1] - indexes
[0]);
216 glutSetColor(j
, percent
*color
[0], percent
*color
[1],
219 for (j
=indexes
[1]; j
<=indexes
[2]; j
++) {
220 percent
= (j
- indexes
[1]) / (float)(indexes
[2] - indexes
[1]);
221 glutSetColor(j
, percent
*(1-color
[0])+color
[0],
222 percent
*(1-color
[1])+color
[1],
223 percent
*(1-color
[2])+color
[2]);
228 static void InitMesh(void)
232 float dp1
[3], dp2
[3];
233 float *pt1
, *pt2
, *pt3
;
234 float angle
, d
, x
, y
;
235 GLint numFacets
, numCoords
, frameNum
, i
, j
;
237 theMesh
.widthX
= widthX
;
238 theMesh
.widthY
= widthY
;
239 theMesh
.frames
= frames
;
241 numFacets
= widthX
* widthY
;
242 numCoords
= (widthX
+ 1) * (widthY
+ 1);
244 theMesh
.numCoords
= numCoords
;
245 theMesh
.numFacets
= numFacets
;
247 theMesh
.coords
= (struct coord
*)malloc(frames
*numCoords
*
248 sizeof(struct coord
));
249 theMesh
.facets
= (struct facet
*)malloc(frames
*numFacets
*
250 sizeof(struct facet
));
251 if (theMesh
.coords
== NULL
|| theMesh
.facets
== NULL
) {
252 printf("Out of memory.\n");
256 for (frameNum
= 0; frameNum
< frames
; frameNum
++) {
257 for (i
= 0; i
<= widthX
; i
++) {
258 x
= i
/ (float)widthX
;
259 for (j
= 0; j
<= widthY
; j
++) {
260 y
= j
/ (float)widthY
;
266 angle
= 2 * PI
* d
+ (2 * PI
/ frames
* frameNum
);
268 coord
= GETCOORD(frameNum
, i
, j
);
270 coord
->vertex
[0] = x
- 0.5;
271 coord
->vertex
[1] = y
- 0.5;
272 coord
->vertex
[2] = (height
- height
* d
) * cos(angle
);
274 coord
->normal
[0] = -(height
/ d
) * x
* ((1 - d
) * 2 * PI
*
275 sin(angle
) + cos(angle
));
276 coord
->normal
[1] = -(height
/ d
) * y
* ((1 - d
) * 2 * PI
*
277 sin(angle
) + cos(angle
));
278 coord
->normal
[2] = -1;
280 d
= 1.0 / sqrt(coord
->normal
[0]*coord
->normal
[0]+
281 coord
->normal
[1]*coord
->normal
[1]+1);
282 coord
->normal
[0] *= d
;
283 coord
->normal
[1] *= d
;
284 coord
->normal
[2] *= d
;
287 for (i
= 0; i
< widthX
; i
++) {
288 for (j
= 0; j
< widthY
; j
++) {
289 facet
= GETFACET(frameNum
, i
, j
);
290 if (((i
/checkerSize
)%2)^(j
/checkerSize
)%2) {
292 facet
->color
[0] = 1.0;
293 facet
->color
[1] = 0.2;
294 facet
->color
[2] = 0.2;
296 facet
->color
[0] = colorIndexes1
[0];
297 facet
->color
[1] = colorIndexes1
[1];
298 facet
->color
[2] = colorIndexes1
[2];
302 facet
->color
[0] = 0.2;
303 facet
->color
[1] = 1.0;
304 facet
->color
[2] = 0.2;
306 facet
->color
[0] = colorIndexes2
[0];
307 facet
->color
[1] = colorIndexes2
[1];
308 facet
->color
[2] = colorIndexes2
[2];
311 pt1
= GETCOORD(frameNum
, i
, j
)->vertex
;
312 pt2
= GETCOORD(frameNum
, i
, j
+1)->vertex
;
313 pt3
= GETCOORD(frameNum
, i
+1, j
+1)->vertex
;
315 dp1
[0] = pt2
[0] - pt1
[0];
316 dp1
[1] = pt2
[1] - pt1
[1];
317 dp1
[2] = pt2
[2] - pt1
[2];
319 dp2
[0] = pt3
[0] - pt2
[0];
320 dp2
[1] = pt3
[1] - pt2
[1];
321 dp2
[2] = pt3
[2] - pt2
[2];
323 facet
->normal
[0] = dp1
[1] * dp2
[2] - dp1
[2] * dp2
[1];
324 facet
->normal
[1] = dp1
[2] * dp2
[0] - dp1
[0] * dp2
[2];
325 facet
->normal
[2] = dp1
[0] * dp2
[1] - dp1
[1] * dp2
[0];
327 d
= 1.0 / sqrt(facet
->normal
[0]*facet
->normal
[0]+
328 facet
->normal
[1]*facet
->normal
[1]+
329 facet
->normal
[2]*facet
->normal
[2]);
331 facet
->normal
[0] *= d
;
332 facet
->normal
[1] *= d
;
333 facet
->normal
[2] *= d
;
339 static void InitMaterials(void)
341 static float ambient
[] = {0.1, 0.1, 0.1, 1.0};
342 static float diffuse
[] = {0.5, 1.0, 1.0, 1.0};
343 static float position
[] = {90.0, 90.0, 150.0, 0.0};
344 static float front_mat_shininess
[] = {60.0};
345 static float front_mat_specular
[] = {0.2, 0.2, 0.2, 1.0};
346 static float front_mat_diffuse
[] = {0.5, 0.28, 0.38, 1.0};
347 static float back_mat_shininess
[] = {60.0};
348 static float back_mat_specular
[] = {0.5, 0.5, 0.2, 1.0};
349 static float back_mat_diffuse
[] = {1.0, 1.0, 0.2, 1.0};
350 static float lmodel_ambient
[] = {1.0, 1.0, 1.0, 1.0};
351 static float lmodel_twoside
[] = {GL_TRUE
};
353 glMatrixMode(GL_PROJECTION
);
354 gluPerspective(90.0, 1.0, 0.5, 10.0);
356 glLightfv(GL_LIGHT0
, GL_AMBIENT
, ambient
);
357 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, diffuse
);
358 glLightfv(GL_LIGHT0
, GL_POSITION
, position
);
359 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, lmodel_ambient
);
360 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE
, lmodel_twoside
);
361 glEnable(GL_LIGHTING
);
364 glMaterialfv(GL_FRONT
, GL_SHININESS
, front_mat_shininess
);
365 glMaterialfv(GL_FRONT
, GL_SPECULAR
, front_mat_specular
);
366 glMaterialfv(GL_FRONT
, GL_DIFFUSE
, front_mat_diffuse
);
367 glMaterialfv(GL_BACK
, GL_SHININESS
, back_mat_shininess
);
368 glMaterialfv(GL_BACK
, GL_SPECULAR
, back_mat_specular
);
369 glMaterialfv(GL_BACK
, GL_DIFFUSE
, back_mat_diffuse
);
371 glColorMaterial(GL_FRONT_AND_BACK
, GL_DIFFUSE
);
375 glEnable(GL_COLOR_MATERIAL
);
381 static void InitTexture(void)
384 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_REPEAT
);
385 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_REPEAT
);
386 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
387 glTexParameterf(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
388 glTexEnvf(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_MODULATE
);
391 static void Init(void)
394 glClearColor(0.0, 0.0, 0.0, 0.0);
396 glShadeModel(GL_FLAT
);
400 glEnable(GL_DEPTH_TEST
);
406 glMatrixMode(GL_MODELVIEW
);
407 glTranslatef(0.0, 0.4, -1.8);
408 glScalef(2.0, 2.0, 2.0);
409 glRotatef(-35.0, 1.0, 0.0, 0.0);
410 glRotatef(35.0, 0.0, 0.0, 1.0);
413 static void Reshape(int width
, int height
)
416 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
419 static void Key(unsigned char key
, int x
, int y
)
427 if (contouring
== 1) {
428 static GLfloat map
[4] = {0, 0, 20, 0};
430 glTexImage2D(GL_TEXTURE_2D
, 0, 3, 4, 4, 0, GL_LUMINANCE
,
431 GL_UNSIGNED_BYTE
, (GLvoid
*)contourTexture1
);
432 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_OBJECT_LINEAR
);
433 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_OBJECT_LINEAR
);
434 glTexGenfv(GL_S
, GL_OBJECT_PLANE
, map
);
435 glTexGenfv(GL_T
, GL_OBJECT_PLANE
, map
);
436 glEnable(GL_TEXTURE_2D
);
437 glEnable(GL_TEXTURE_GEN_S
);
438 glEnable(GL_TEXTURE_GEN_T
);
439 } else if (contouring
== 2) {
440 static GLfloat map
[4] = {0, 0, 20, 0};
442 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
443 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_EYE_LINEAR
);
445 glMatrixMode(GL_MODELVIEW
);
447 glTexGenfv(GL_S
, GL_EYE_PLANE
, map
);
448 glTexGenfv(GL_T
, GL_EYE_PLANE
, map
);
452 glDisable(GL_TEXTURE_GEN_S
);
453 glDisable(GL_TEXTURE_GEN_T
);
454 glDisable(GL_TEXTURE_2D
);
460 glShadeModel(GL_SMOOTH
);
462 glShadeModel(GL_FLAT
);
466 lighting
= !lighting
;
468 glEnable(GL_LIGHTING
);
471 glEnable(GL_COLOR_MATERIAL
);
474 glDisable(GL_LIGHTING
);
475 glDisable(GL_LIGHT0
);
477 glDisable(GL_COLOR_MATERIAL
);
484 glEnable(GL_DEPTH_TEST
);
485 clearMask
|= GL_DEPTH_BUFFER_BIT
;
487 glDisable(GL_DEPTH_TEST
);
488 clearMask
&= ~GL_DEPTH_BUFFER_BIT
;
492 stepMode
= !stepMode
;
496 glutIdleFunc(glut_post_redisplay_p
);
505 spinMode
= !spinMode
;
513 static GLenum
Args(int argc
, char **argv
)
518 doubleBuffer
= GL_TRUE
;
525 for (i
= 1; i
< argc
; i
++) {
526 if (strcmp(argv
[i
], "-ci") == 0) {
528 } else if (strcmp(argv
[i
], "-rgb") == 0) {
530 } else if (strcmp(argv
[i
], "-sb") == 0) {
531 doubleBuffer
= GL_FALSE
;
532 } else if (strcmp(argv
[i
], "-db") == 0) {
533 doubleBuffer
= GL_TRUE
;
534 } else if (strcmp(argv
[i
], "-grid") == 0) {
535 if (i
+2 >= argc
|| argv
[i
+1][0] == '-' || argv
[i
+2][0] == '-') {
536 printf("-grid (No numbers).\n");
539 widthX
= atoi(argv
[++i
]);
540 widthY
= atoi(argv
[++i
]);
542 } else if (strcmp(argv
[i
], "-size") == 0) {
543 if (i
+1 >= argc
|| argv
[i
+1][0] == '-') {
544 printf("-checker (No number).\n");
547 checkerSize
= atoi(argv
[++i
]);
549 } else if (strcmp(argv
[i
], "-wave") == 0) {
550 if (i
+1 >= argc
|| argv
[i
+1][0] == '-') {
551 printf("-wave (No number).\n");
554 height
= atof(argv
[++i
]);
556 } else if (strcmp(argv
[i
], "-frames") == 0) {
557 if (i
+1 >= argc
|| argv
[i
+1][0] == '-') {
558 printf("-frames (No number).\n");
561 frames
= atoi(argv
[++i
]);
564 printf("%s (Bad option).\n", argv
[i
]);
571 int main(int argc
, char **argv
)
575 glutInit(&argc
, argv
);
577 if (Args(argc
, argv
) == GL_FALSE
) {
581 glutInitWindowPosition(0, 0); glutInitWindowSize( 300, 300);
584 type
|= (rgb
) ? GLUT_RGB
: GLUT_INDEX
;
585 type
|= (doubleBuffer
) ? GLUT_DOUBLE
: GLUT_SINGLE
;
586 glutInitDisplayMode(type
);
588 if (glutCreateWindow("Wave Demo") == GL_FALSE
) {
596 glutReshapeFunc(Reshape
);
597 glutKeyboardFunc(Key
);
598 glutDisplayFunc(Animate
);
599 glutIdleFunc(glut_post_redisplay_p
);