3 * Display an isosurface of 3-D wind speed volume.
5 * Command line options:
6 * -info print GL implementation information
8 * Brian Paul This file in public domain.
15 * - Arrow keys to rotate
16 * - 's' toggles smooth shading
17 * - 'l' toggles lighting
19 * - 'I' and 'i' zoom in and out
20 * - 'c' toggles a user clip plane
21 * - 'm' toggles colorful materials in GL_TRIANGLES modes.
22 * - '+' and '-' move the user clip plane
24 * Other options are available via the popup menu.
40 #define TEXTURE_FILE "../images/reflect.rgb"
42 #define LIT 0x00000001
43 #define UNLIT 0x00000002
44 #define REFLECT 0x00000004
45 #define POINT_FILTER 0x00000008
46 #define LINEAR_FILTER 0x00000010
47 #define GLVERTEX 0x00000020
48 #define DRAW_ELTS 0x00000040
49 #define DRAW_ARRAYS 0x00000080
50 #define ARRAY_ELT 0x00000100
51 #define LOCKED 0x00000200
52 #define UNLOCKED 0x00000400
53 #define IMMEDIATE 0x00000800
54 #define DISPLAYLIST 0x00001000
55 #define SHADE_SMOOTH 0x00002000
56 #define SHADE_FLAT 0x00004000
57 #define TRIANGLES 0x00008000
58 #define STRIPS 0x00010000
59 #define POINTS 0x00020000
60 #define USER_CLIP 0x00040000
61 #define NO_USER_CLIP 0x00080000
62 #define MATERIALS 0x00100000
63 #define NO_MATERIALS 0x00200000
64 #define FOG 0x00400000
65 #define NO_FOG 0x00800000
66 #define QUIT 0x01000000
67 #define GLINFO 0x02000000
68 #define STIPPLE 0x04000000
69 #define NO_STIPPLE 0x08000000
70 #define POLYGON_FILL 0x10000000
71 #define POLYGON_LINE 0x20000000
72 #define POLYGON_POINT 0x40000000
74 #define LIGHT_MASK (LIT|UNLIT|REFLECT)
75 #define FILTER_MASK (POINT_FILTER|LINEAR_FILTER)
76 #define RENDER_STYLE_MASK (GLVERTEX|DRAW_ARRAYS|DRAW_ELTS|ARRAY_ELT)
77 #define DLIST_MASK (IMMEDIATE|DISPLAYLIST)
78 #define LOCK_MASK (LOCKED|UNLOCKED)
79 #define MATERIAL_MASK (MATERIALS|NO_MATERIALS)
80 #define PRIMITIVE_MASK (TRIANGLES|STRIPS|POINTS)
81 #define CLIP_MASK (USER_CLIP|NO_USER_CLIP)
82 #define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT)
83 #define FOG_MASK (FOG|NO_FOG)
84 #define STIPPLE_MASK (STIPPLE|NO_STIPPLE)
85 #define POLYGON_MASK (POLYGON_FILL|POLYGON_LINE|POLYGON_POINT)
87 #define MAXVERTS 10000
88 static GLint maxverts
= MAXVERTS
;
89 static float data
[MAXVERTS
][6];
90 static float compressed_data
[MAXVERTS
][6];
91 static float expanded_data
[MAXVERTS
*3][6];
92 static GLuint indices
[MAXVERTS
];
93 static GLuint tri_indices
[MAXVERTS
*3];
94 static GLuint strip_indices
[MAXVERTS
];
95 static GLfloat col
[100][4];
96 static GLint numverts
, num_tri_verts
, numuniq
;
101 static GLint state
, allowed
= ~0;
102 static GLboolean doubleBuffer
= GL_TRUE
;
103 static GLdouble plane
[4];
104 static GLuint surf1
, dlist_state
;
106 static GLboolean PrintInfo
= GL_FALSE
;
109 static GLubyte halftone
[] = {
110 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
111 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
112 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
113 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
114 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
115 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
116 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
117 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
118 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
119 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
120 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
123 static void read_surface( char *filename
)
127 f
= fopen(filename
,"r");
129 printf("couldn't read %s\n", filename
);
134 while (!feof(f
) && numverts
<maxverts
) {
135 fscanf( f
, "%f %f %f %f %f %f",
136 &data
[numverts
][0], &data
[numverts
][1], &data
[numverts
][2],
137 &data
[numverts
][3], &data
[numverts
][4], &data
[numverts
][5] );
142 printf("%d vertices, %d triangles\n", numverts
, numverts
-2);
148 static void print_flags( const char *msg
, GLuint flags
)
151 "%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
153 (flags
& GLVERTEX
) ? "glVertex, " : "",
154 (flags
& DRAW_ARRAYS
) ? "glDrawArrays, " : "",
155 (flags
& DRAW_ELTS
) ? "glDrawElements, " : "",
156 (flags
& ARRAY_ELT
) ? "glArrayElement, " : "",
157 (flags
& LOCKED
) ? "locked arrays, " : "",
158 (flags
& TRIANGLES
) ? "GL_TRIANGLES, " : "",
159 (flags
& STRIPS
) ? "GL_TRIANGLE_STRIP, " : "",
160 (flags
& POINTS
) ? "GL_POINTS, " : "",
161 (flags
& DISPLAYLIST
) ? "as a displaylist, " : "",
162 (flags
& LIT
) ? "lit, " : "",
163 (flags
& UNLIT
) ? "unlit, " : "",
164 (flags
& REFLECT
) ? "reflect, " : "",
165 (flags
& SHADE_FLAT
) ? "flat-shaded, " : "",
166 (flags
& USER_CLIP
) ? "user_clip, " : "",
167 (flags
& MATERIALS
) ? "materials, " : "",
168 (flags
& FOG
) ? "fog, " : "",
169 (flags
& STIPPLE
) ? "stipple, " : "",
170 (flags
& POLYGON_LINE
) ? "polygon mode line, " : "",
171 (flags
& POLYGON_POINT
) ? "polygon mode point, " : "");
183 #define COMPARE_FUNC( AXIS ) \
184 static int compare_axis_##AXIS( const void *a, const void *b ) \
186 float t = ( (*(struct data_idx *)a).data[AXIS] - \
187 (*(struct data_idx *)b).data[AXIS] ); \
189 if (t < 0) return -1; \
190 if (t > 0) return 1; \
202 int (*(compare
[7]))( const void *a
, const void *b
) =
214 #define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i)
216 static int sort_axis( int axis
,
219 struct data_idx
*indices
,
228 if (finish
-start
> 2)
230 qsort( indices
+start
, finish
-start
, sizeof(*indices
), compare
[axis
] );
232 else if (indices
[start
].data
[axis
] > indices
[start
+1].data
[axis
])
234 struct data_idx tmp
= indices
[start
];
235 indices
[start
] = indices
[start
+1];
236 indices
[start
+1] = tmp
;
239 if (axis
== vec_size
-1) {
240 for (i
= start
; i
< finish
; ) {
241 float max
= indices
[i
].data
[axis
] + fudge
;
242 float *dest
= VEC_ELT(out
, vec_stride
, uniq
);
245 for (j
= 0 ; j
< vec_size
; j
++)
246 dest
[j
] = indices
[i
].data
[j
];
248 for ( ; i
< finish
&& max
>= indices
[i
].data
[axis
]; i
++)
249 indices
[i
].uniq_idx
= uniq
;
254 for (i
= start
; i
< finish
; ) {
256 float max
= indices
[i
].data
[axis
] + fudge
;
257 while (j
< finish
&& max
>= indices
[j
].data
[axis
]) j
++;
259 float *dest
= VEC_ELT(out
, vec_stride
, uniq
);
262 indices
[i
].uniq_idx
= uniq
;
264 for (k
= 0 ; k
< vec_size
; k
++)
265 dest
[k
] = indices
[i
].data
[k
];
269 uniq
= sort_axis( axis
+1, vec_size
, vec_stride
,
270 indices
, i
, j
, out
, uniq
, fudge
);
280 static void extract_indices1( const struct data_idx
*in
, unsigned int *out
,
284 for ( i
= 0 ; i
< n
; i
++ ) {
285 out
[in
[i
].idx
] = in
[i
].uniq_idx
;
290 static void compactify_arrays(void)
293 struct data_idx
*ind
;
295 ind
= (struct data_idx
*) malloc( sizeof(struct data_idx
) * numverts
);
297 for (i
= 0 ; i
< numverts
; i
++) {
299 ind
[i
].data
= data
[i
];
302 numuniq
= sort_axis(0,
303 sizeof(compressed_data
[0])/sizeof(float),
304 sizeof(compressed_data
[0]),
308 (float *)compressed_data
,
312 printf("Nr unique vertex/normal pairs: %d\n", numuniq
);
314 extract_indices1( ind
, indices
, numverts
);
318 static void expand_arrays(void)
322 for (i
= 2 ; i
< numverts
; i
++, parity
^= 1) {
326 memcpy( expanded_data
[(i
-2)*3+0], data
[v0
], sizeof(data
[0]) );
327 memcpy( expanded_data
[(i
-2)*3+1], data
[v1
], sizeof(data
[0]) );
328 memcpy( expanded_data
[(i
-2)*3+2], data
[v2
], sizeof(data
[0]) );
332 static float myrand( float max
)
334 return max
*rand()/(RAND_MAX
+1.0);
338 static void make_tri_indices( void )
340 unsigned int *v
= tri_indices
;
341 unsigned int parity
= 0;
344 for (j
=2;j
<numverts
;j
++,parity
^=1) {
356 num_tri_verts
= v
- tri_indices
;
357 printf("num_tri_verts: %d\n", num_tri_verts
);
359 for (i
= j
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
361 col
[j
][2] = myrand(1);
362 col
[j
][1] = myrand(1);
363 col
[j
][0] = myrand(1);
366 for (i
= 0; i
< numverts
; i
++)
367 strip_indices
[i
] = i
;
370 #define MIN(x,y) (x < y) ? x : y
372 static void draw_surface( unsigned int with_state
)
376 if (with_state
& DISPLAYLIST
) {
377 if ((with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
|MATERIAL_MASK
)) !=
381 fprintf(stderr
, "rebuilding displaylist\n");
384 glDeleteLists( surf1
, 1 );
386 dlist_state
= with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
|
388 surf1
= glGenLists(1);
389 glNewList(surf1
, GL_COMPILE
);
390 draw_surface( dlist_state
);
398 switch (with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
)) {
399 #ifdef GL_EXT_vertex_array
401 case (DRAW_ELTS
|TRIANGLES
):
402 if (with_state
& MATERIALS
) {
403 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
404 GLuint nr
= MIN(num_tri_verts
-i
, 600);
405 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
406 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
407 glDrawElements( GL_TRIANGLES
, nr
, GL_UNSIGNED_INT
, tri_indices
+i
);
410 glDrawElements( GL_TRIANGLES
, num_tri_verts
, GL_UNSIGNED_INT
,
415 case (DRAW_ARRAYS
|TRIANGLES
):
416 glDrawArraysEXT( GL_TRIANGLES
, 0, (numverts
-2)*3 );
419 case (ARRAY_ELT
|TRIANGLES
):
420 if (with_state
& MATERIALS
) {
421 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
422 GLuint nr
= MIN(num_tri_verts
-i
, 600);
424 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
425 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
426 glBegin( GL_TRIANGLES
);
427 for (k
= 0 ; k
< nr
; k
++)
428 glArrayElement( tri_indices
[i
+k
] );
432 glBegin( GL_TRIANGLES
);
433 for (i
= 0 ; i
< num_tri_verts
; i
++)
434 glArrayElement( tri_indices
[i
] );
441 /* Uses the original arrays (including duplicate elements):
443 case (DRAW_ARRAYS
|STRIPS
):
444 glDrawArraysEXT( GL_TRIANGLE_STRIP
, 0, numverts
);
446 case (DRAW_ELTS
|STRIPS
):
447 glDrawElements( GL_TRIANGLE_STRIP
, numverts
,
448 GL_UNSIGNED_INT
, strip_indices
);
451 /* Uses the original arrays (including duplicate elements):
453 case (ARRAY_ELT
|STRIPS
):
454 glBegin( GL_TRIANGLE_STRIP
);
455 for (i
= 0 ; i
< numverts
; i
++)
460 case (DRAW_ARRAYS
|POINTS
):
461 glDrawArraysEXT( GL_POINTS
, 0, numuniq
);
463 case (DRAW_ELTS
|POINTS
):
464 /* can use numuniq with strip_indices as strip_indices[i] == i.
466 glDrawElements( GL_POINTS
, numuniq
,
467 GL_UNSIGNED_INT
, strip_indices
);
469 case (ARRAY_ELT
|POINTS
):
470 /* just emit each unique element once:
472 glBegin( GL_POINTS
);
473 for (i
= 0 ; i
< numuniq
; i
++)
479 case (GLVERTEX
|TRIANGLES
):
480 if (with_state
& MATERIALS
) {
481 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
482 GLuint nr
= MIN(num_tri_verts
-i
, 600);
484 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
485 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
486 glBegin( GL_TRIANGLES
);
487 for (k
= 0 ; k
< nr
; k
++) {
488 glNormal3fv( &compressed_data
[tri_indices
[i
+k
]][3] );
489 glVertex3fv( &compressed_data
[tri_indices
[i
+k
]][0] );
494 glBegin( GL_TRIANGLES
);
495 for (i
= 0 ; i
< num_tri_verts
; i
++) {
496 glNormal3fv( &compressed_data
[tri_indices
[i
]][3] );
497 glVertex3fv( &compressed_data
[tri_indices
[i
]][0] );
503 case (GLVERTEX
|POINTS
):
504 /* Renders all points, but not in strip order... Shouldn't be a
505 * problem, but people may be confused as to why points are so
506 * much faster in this demo... And why cva doesn't help them...
508 glBegin( GL_POINTS
);
509 for ( i
= 0 ; i
< numuniq
; i
++ ) {
510 glNormal3fv( &compressed_data
[i
][3] );
511 glVertex3fv( &compressed_data
[i
][0] );
516 case (GLVERTEX
|STRIPS
):
517 if (with_state
& MATERIALS
) {
518 glBegin( GL_TRIANGLE_STRIP
);
519 for (i
=0;i
<numverts
;i
++) {
520 if (i
% 600 == 0 && i
!= 0) {
521 unsigned j
= i
/ 600;
522 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
523 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
525 glNormal3fv( &data
[i
][3] );
526 glVertex3fv( &data
[i
][0] );
531 glBegin( GL_TRIANGLE_STRIP
);
532 for (i
=0;i
<numverts
;i
++) {
533 glNormal3fv( &data
[i
][3] );
534 glVertex3fv( &data
[i
][0] );
541 fprintf(stderr
, "unimplemented mode %x...\n",
542 (with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
)));
549 static void Display(void)
551 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
552 draw_surface( state
);
554 if (doubleBuffer
) glutSwapBuffers();
558 /* KW: only do this when necessary, so CVA can re-use results.
560 static void set_matrix( void )
562 glMatrixMode(GL_MODELVIEW
);
564 glTranslatef( 0.0, 0.0, dist
);
565 glRotatef( yrot
, 0.0, 1.0, 0.0 );
566 glRotatef( xrot
, 1.0, 0.0, 0.0 );
569 static void Benchmark( float xdiff
, float ydiff
)
571 int startTime
, endTime
;
573 double seconds
, fps
, triPerSecond
;
575 printf("Benchmarking...\n");
578 startTime
= glutGet(GLUT_ELAPSED_TIME
);
586 endTime
= glutGet(GLUT_ELAPSED_TIME
);
587 } while (endTime
- startTime
< 5000); /* 5 seconds */
590 seconds
= (double) (endTime
- startTime
) / 1000.0;
591 triPerSecond
= (numverts
- 2) * draws
/ seconds
;
592 fps
= draws
/ seconds
;
593 printf("Result: triangles/sec: %g fps: %g\n", triPerSecond
, fps
);
597 static void InitMaterials(void)
599 static float ambient
[] = {0.1, 0.1, 0.1, 1.0};
600 static float diffuse
[] = {0.5, 1.0, 1.0, 1.0};
601 static float position0
[] = {0.0, 0.0, 20.0, 0.0};
602 static float position1
[] = {0.0, 0.0, -20.0, 0.0};
603 static float front_mat_shininess
[] = {60.0};
604 static float front_mat_specular
[] = {0.2, 0.2, 0.2, 1.0};
605 static float front_mat_diffuse
[] = {0.5, 0.28, 0.38, 1.0};
607 static float back_mat_shininess[] = {60.0};
608 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
609 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
611 static float lmodel_ambient
[] = {1.0, 1.0, 1.0, 1.0};
612 static float lmodel_twoside
[] = {GL_FALSE
};
614 glLightfv(GL_LIGHT0
, GL_AMBIENT
, ambient
);
615 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, diffuse
);
616 glLightfv(GL_LIGHT0
, GL_POSITION
, position0
);
619 glLightfv(GL_LIGHT1
, GL_AMBIENT
, ambient
);
620 glLightfv(GL_LIGHT1
, GL_DIFFUSE
, diffuse
);
621 glLightfv(GL_LIGHT1
, GL_POSITION
, position1
);
624 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, lmodel_ambient
);
625 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE
, lmodel_twoside
);
627 glMaterialfv(GL_FRONT_AND_BACK
, GL_SHININESS
, front_mat_shininess
);
628 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, front_mat_specular
);
629 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, front_mat_diffuse
);
631 glPolygonStipple (halftone
);
636 #define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
637 #define CHANGED(o,n,mask) ((n&mask) && (n&mask) != (o&mask) )
639 static void ModeMenu(int m
)
649 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION
));
650 printf("GL_EXTENSIONS: %s\n", (char *) glGetString(GL_EXTENSIONS
));
651 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER
));
655 if (CHANGED(state
, m
, FILTER_MASK
)) {
656 UPDATE(state
, m
, FILTER_MASK
);
657 if (m
& LINEAR_FILTER
) {
658 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
659 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
661 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
662 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
666 if (CHANGED(state
, m
, LIGHT_MASK
)) {
667 UPDATE(state
, m
, LIGHT_MASK
);
669 glEnable(GL_LIGHTING
);
670 glDisable(GL_TEXTURE_GEN_S
);
671 glDisable(GL_TEXTURE_GEN_T
);
672 glDisable(GL_TEXTURE_2D
);
674 else if (m
& UNLIT
) {
675 glDisable(GL_LIGHTING
);
676 glDisable(GL_TEXTURE_GEN_S
);
677 glDisable(GL_TEXTURE_GEN_T
);
678 glDisable(GL_TEXTURE_2D
);
680 else if (m
& REFLECT
) {
681 glDisable(GL_LIGHTING
);
682 glEnable(GL_TEXTURE_GEN_S
);
683 glEnable(GL_TEXTURE_GEN_T
);
684 glEnable(GL_TEXTURE_2D
);
688 if (CHANGED(state
, m
, SHADE_MASK
)) {
689 UPDATE(state
, m
, SHADE_MASK
);
690 if (m
& SHADE_SMOOTH
)
691 glShadeModel(GL_SMOOTH
);
693 glShadeModel(GL_FLAT
);
697 if (CHANGED(state
, m
, CLIP_MASK
)) {
698 UPDATE(state
, m
, CLIP_MASK
);
700 glEnable(GL_CLIP_PLANE0
);
702 glDisable(GL_CLIP_PLANE0
);
706 if (CHANGED(state
, m
, FOG_MASK
)) {
707 UPDATE(state
, m
, FOG_MASK
);
716 if (CHANGED(state
, m
, STIPPLE_MASK
)) {
717 UPDATE(state
, m
, STIPPLE_MASK
);
719 glEnable(GL_POLYGON_STIPPLE
);
722 glDisable(GL_POLYGON_STIPPLE
);
726 if (CHANGED(state
, m
, POLYGON_MASK
)) {
727 UPDATE(state
, m
, POLYGON_MASK
);
728 if (m
& POLYGON_FILL
) {
729 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
731 else if (m
& POLYGON_LINE
) {
732 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
735 glPolygonMode(GL_FRONT_AND_BACK
, GL_POINT
);
739 #ifdef GL_EXT_vertex_array
740 if (CHANGED(state
, m
, (LOCK_MASK
|RENDER_STYLE_MASK
|PRIMITIVE_MASK
)))
742 if (m
& (PRIMITIVE_MASK
)) {
743 UPDATE(state
, m
, (PRIMITIVE_MASK
));
746 if (m
& (RENDER_STYLE_MASK
)) {
747 UPDATE(state
, m
, (RENDER_STYLE_MASK
));
751 UPDATE(state
, m
, (LOCK_MASK
));
755 print_flags("primitive", state
& PRIMITIVE_MASK
);
756 print_flags("render style", state
& RENDER_STYLE_MASK
);
758 if ((state
& PRIMITIVE_MASK
) != STRIPS
&&
759 ((state
& RENDER_STYLE_MASK
) == DRAW_ELTS
||
760 (state
& RENDER_STYLE_MASK
) == ARRAY_ELT
||
761 (state
& PRIMITIVE_MASK
) == POINTS
))
763 fprintf(stderr
, "enabling small arrays\n");
764 /* Rendering any primitive with draw-element/array-element
765 * --> Can't do strips here as ordering has been lost in
766 * compaction process...
768 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), numuniq
,
770 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), numuniq
,
771 &compressed_data
[0][3]);
772 #ifdef GL_EXT_compiled_vertex_array
773 if (allowed
& LOCKED
) {
774 if (state
& LOCKED
) {
775 glLockArraysEXT( 0, numuniq
);
782 else if ((state
& PRIMITIVE_MASK
) == TRIANGLES
&&
783 (state
& RENDER_STYLE_MASK
) == DRAW_ARRAYS
) {
784 fprintf(stderr
, "enabling big arrays\n");
785 /* Only get here for TRIANGLES and drawarrays
787 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), (numverts
-2) * 3,
789 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), (numverts
-2) * 3,
790 &expanded_data
[0][3]);
792 #ifdef GL_EXT_compiled_vertex_array
793 if (allowed
& LOCKED
) {
794 if (state
& LOCKED
) {
795 glLockArraysEXT( 0, (numverts
-2)*3 );
803 fprintf(stderr
, "enabling normal arrays\n");
804 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), numverts
, data
);
805 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), numverts
, &data
[0][3]);
806 #ifdef GL_EXT_compiled_vertex_array
807 if (allowed
& LOCKED
) {
808 if (state
& LOCKED
) {
809 glLockArraysEXT( 0, numverts
);
821 if (m
& DLIST_MASK
) {
822 UPDATE(state
, m
, DLIST_MASK
);
825 if (m
& MATERIAL_MASK
) {
826 UPDATE(state
, m
, MATERIAL_MASK
);
829 print_flags("new flags", state
);
836 static void Init(int argc
, char *argv
[])
838 GLfloat fogColor
[4] = {0.5,1.0,0.5,1.0};
848 glClearColor(0.0, 0.0, 1.0, 0.0);
849 glEnable( GL_DEPTH_TEST
);
850 glEnableClientState( GL_VERTEX_ARRAY
);
851 glEnableClientState( GL_NORMAL_ARRAY
);
853 glMatrixMode(GL_PROJECTION
);
855 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
857 glMatrixMode(GL_MODELVIEW
);
859 glClipPlane(GL_CLIP_PLANE0
, plane
);
865 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
866 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_FASTEST
);
868 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_SPHERE_MAP
);
869 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_SPHERE_MAP
);
872 /* Green fog is easy to see */
873 glFogi(GL_FOG_MODE
,GL_EXP2
);
874 glFogfv(GL_FOG_COLOR
,fogColor
);
875 glFogf(GL_FOG_DENSITY
,0.15);
876 glHint(GL_FOG_HINT
,GL_DONT_CARE
);
879 static int firsttime
= 1;
886 if (!LoadRGBMipmaps(TEXTURE_FILE
, GL_RGB
)) {
887 printf("Error: couldn't load texture image\n");
893 ModeMenu(SHADE_SMOOTH
|
906 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
907 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION
));
908 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR
));
909 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS
));
915 static void Reshape(int width
, int height
)
917 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
922 static void Key( unsigned char key
, int x
, int y
)
930 ModeMenu((state
^ FOG_MASK
) & FOG_MASK
);
933 ModeMenu((state
^ SHADE_MASK
) & SHADE_MASK
);
936 ModeMenu((state
^ STIPPLE_MASK
) & STIPPLE_MASK
);
939 ModeMenu((state
^ LIGHT_MASK
) & (LIT
|UNLIT
));
942 ModeMenu((state
^ MATERIAL_MASK
) & MATERIAL_MASK
);
945 ModeMenu((state
^ CLIP_MASK
) & CLIP_MASK
);
948 ModeMenu((LOCKED
|IMMEDIATE
|DRAW_ELTS
|TRIANGLES
) & allowed
);
951 ModeMenu(UNLOCKED
|IMMEDIATE
|GLVERTEX
|STRIPS
);
972 glMatrixMode(GL_MODELVIEW
);
974 glClipPlane(GL_CLIP_PLANE0
, plane
);
981 glMatrixMode(GL_MODELVIEW
);
983 glClipPlane(GL_CLIP_PLANE0
, plane
);
994 static void SpecialKey( int key
, int x
, int y
)
1002 case GLUT_KEY_RIGHT
:
1015 glutPostRedisplay();
1020 static GLint
Args(int argc
, char **argv
)
1025 for (i
= 1; i
< argc
; i
++) {
1026 if (strcmp(argv
[i
], "-sb") == 0) {
1027 doubleBuffer
= GL_FALSE
;
1029 else if (strcmp(argv
[i
], "-db") == 0) {
1030 doubleBuffer
= GL_TRUE
;
1032 else if (strcmp(argv
[i
], "-info") == 0) {
1033 PrintInfo
= GL_TRUE
;
1035 else if (strcmp(argv
[i
], "-10") == 0) {
1038 else if (strcmp(argv
[i
], "-100") == 0) {
1041 else if (strcmp(argv
[i
], "-1000") == 0) {
1045 printf("%s (Bad option).\n", argv
[i
]);
1053 int main(int argc
, char **argv
)
1057 GLuint arg_mode
= Args(argc
, argv
);
1059 if (arg_mode
& QUIT
)
1062 read_surface( "isosurf.dat" );
1064 glutInitWindowSize(400, 400);
1065 glutInit( &argc
, argv
);
1069 type
|= (doubleBuffer
) ? GLUT_DOUBLE
: GLUT_SINGLE
;
1070 glutInitDisplayMode(type
);
1072 if (glutCreateWindow("Isosurface") <= 0) {
1078 /* Make sure server supports the vertex array extension */
1079 if (!GLEW_EXT_vertex_array
)
1081 printf("Vertex arrays not supported by this renderer\n");
1082 allowed
&= ~(LOCKED
|DRAW_ARRAYS
|DRAW_ELTS
|ARRAY_ELT
);
1084 else if (!GLEW_EXT_compiled_vertex_array
)
1086 printf("Compiled vertex arrays not supported by this renderer\n");
1093 glutCreateMenu(ModeMenu
);
1094 glutAddMenuEntry("GL info", GLINFO
);
1095 glutAddMenuEntry("", 0);
1096 glutAddMenuEntry("Lit", LIT
);
1097 glutAddMenuEntry("Unlit", UNLIT
);
1098 glutAddMenuEntry("Reflect", REFLECT
);
1099 glutAddMenuEntry("", 0);
1100 glutAddMenuEntry("Smooth", SHADE_SMOOTH
);
1101 glutAddMenuEntry("Flat", SHADE_FLAT
);
1102 glutAddMenuEntry("", 0);
1103 glutAddMenuEntry("Fog", FOG
);
1104 glutAddMenuEntry("No Fog", NO_FOG
);
1105 glutAddMenuEntry("", 0);
1106 glutAddMenuEntry("Stipple", STIPPLE
);
1107 glutAddMenuEntry("No Stipple", NO_STIPPLE
);
1108 glutAddMenuEntry("", 0);
1109 glutAddMenuEntry("Polygon Mode Fill", POLYGON_FILL
);
1110 glutAddMenuEntry("Polygon Mode Line", POLYGON_LINE
);
1111 glutAddMenuEntry("Polygon Mode Points", POLYGON_POINT
);
1112 glutAddMenuEntry("", 0);
1113 glutAddMenuEntry("Point Filtered", POINT_FILTER
);
1114 glutAddMenuEntry("Linear Filtered", LINEAR_FILTER
);
1115 glutAddMenuEntry("", 0);
1116 glutAddMenuEntry("GL_TRIANGLES", TRIANGLES
);
1117 glutAddMenuEntry("GL_TRIANGLE_STRIPS", STRIPS
);
1118 glutAddMenuEntry("GL_POINTS", POINTS
);
1119 glutAddMenuEntry("", 0);
1120 glutAddMenuEntry("Displaylist", DISPLAYLIST
);
1121 glutAddMenuEntry("Immediate", IMMEDIATE
);
1122 glutAddMenuEntry("", 0);
1123 if (allowed
& LOCKED
) {
1124 glutAddMenuEntry("Locked Arrays (CVA)", LOCKED
);
1125 glutAddMenuEntry("Unlocked Arrays", UNLOCKED
);
1126 glutAddMenuEntry("", 0);
1128 glutAddMenuEntry("glVertex", GLVERTEX
);
1129 if (allowed
& DRAW_ARRAYS
) {
1130 glutAddMenuEntry("glDrawElements", DRAW_ELTS
);
1131 glutAddMenuEntry("glDrawArrays", DRAW_ARRAYS
);
1132 glutAddMenuEntry("glArrayElement", ARRAY_ELT
);
1134 glutAddMenuEntry("", 0);
1135 glutAddMenuEntry("Quit", QUIT
);
1136 glutAttachMenu(GLUT_RIGHT_BUTTON
);
1138 glutReshapeFunc(Reshape
);
1139 glutKeyboardFunc(Key
);
1140 glutSpecialFunc(SpecialKey
);
1141 glutDisplayFunc(Display
);