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.
36 #define GL_GLEXT_PROTOTYPES
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
73 #define LIGHT_MASK (LIT|UNLIT|REFLECT)
74 #define FILTER_MASK (POINT_FILTER|LINEAR_FILTER)
75 #define RENDER_STYLE_MASK (GLVERTEX|DRAW_ARRAYS|DRAW_ELTS|ARRAY_ELT)
76 #define DLIST_MASK (IMMEDIATE|DISPLAYLIST)
77 #define LOCK_MASK (LOCKED|UNLOCKED)
78 #define MATERIAL_MASK (MATERIALS|NO_MATERIALS)
79 #define PRIMITIVE_MASK (TRIANGLES|STRIPS|POINTS)
80 #define CLIP_MASK (USER_CLIP|NO_USER_CLIP)
81 #define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT)
82 #define FOG_MASK (FOG|NO_FOG)
83 #define STIPPLE_MASK (STIPPLE|NO_STIPPLE)
84 #define POLYGON_MASK (POLYGON_FILL|POLYGON_LINE)
86 #define MAXVERTS 10000
87 static GLint maxverts
= MAXVERTS
;
88 static float data
[MAXVERTS
][6];
89 static float compressed_data
[MAXVERTS
][6];
90 static float expanded_data
[MAXVERTS
*3][6];
91 static GLuint indices
[MAXVERTS
];
92 static GLuint tri_indices
[MAXVERTS
*3];
93 static GLuint strip_indices
[MAXVERTS
];
94 static GLfloat col
[100][4];
95 static GLint numverts
, num_tri_verts
, numuniq
;
100 static GLint state
, allowed
= ~0;
101 static GLboolean doubleBuffer
= GL_TRUE
;
102 static GLdouble plane
[4];
103 static GLuint surf1
, dlist_state
;
105 static GLboolean PrintInfo
= GL_FALSE
;
108 static GLubyte halftone
[] = {
109 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
110 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
111 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
112 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
113 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
114 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
115 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
116 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
117 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
118 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
119 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
122 static void read_surface( char *filename
)
126 f
= fopen(filename
,"r");
128 printf("couldn't read %s\n", filename
);
133 while (!feof(f
) && numverts
<maxverts
) {
134 fscanf( f
, "%f %f %f %f %f %f",
135 &data
[numverts
][0], &data
[numverts
][1], &data
[numverts
][2],
136 &data
[numverts
][3], &data
[numverts
][4], &data
[numverts
][5] );
141 printf("%d vertices, %d triangles\n", numverts
, numverts
-2);
147 static void print_flags( const char *msg
, GLuint flags
)
150 "%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
152 (flags
& GLVERTEX
) ? "glVertex, " : "",
153 (flags
& DRAW_ARRAYS
) ? "glDrawArrays, " : "",
154 (flags
& DRAW_ELTS
) ? "glDrawElements, " : "",
155 (flags
& ARRAY_ELT
) ? "glArrayElement, " : "",
156 (flags
& LOCKED
) ? "locked arrays, " : "",
157 (flags
& TRIANGLES
) ? "GL_TRIANGLES, " : "",
158 (flags
& STRIPS
) ? "GL_TRIANGLE_STRIP, " : "",
159 (flags
& POINTS
) ? "GL_POINTS, " : "",
160 (flags
& DISPLAYLIST
) ? "as a displaylist, " : "",
161 (flags
& LIT
) ? "lit, " : "",
162 (flags
& UNLIT
) ? "unlit, " : "",
163 (flags
& REFLECT
) ? "reflect, " : "",
164 (flags
& SHADE_FLAT
) ? "flat-shaded, " : "",
165 (flags
& USER_CLIP
) ? "user_clip, " : "",
166 (flags
& MATERIALS
) ? "materials, " : "",
167 (flags
& FOG
) ? "fog, " : "",
168 (flags
& STIPPLE
) ? "stipple, " : "",
169 (flags
& POLYGON_LINE
) ? "polygon mode line, " : "");
181 #define COMPARE_FUNC( AXIS ) \
182 static int compare_axis_##AXIS( const void *a, const void *b ) \
184 float t = ( (*(struct data_idx *)a).data[AXIS] - \
185 (*(struct data_idx *)b).data[AXIS] ); \
187 if (t < 0) return -1; \
188 if (t > 0) return 1; \
200 int (*(compare
[7]))( const void *a
, const void *b
) =
212 #define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i)
214 static int sort_axis( int axis
,
217 struct data_idx
*indices
,
226 if (finish
-start
> 2)
228 qsort( indices
+start
, finish
-start
, sizeof(*indices
), compare
[axis
] );
230 else if (indices
[start
].data
[axis
] > indices
[start
+1].data
[axis
])
232 struct data_idx tmp
= indices
[start
];
233 indices
[start
] = indices
[start
+1];
234 indices
[start
+1] = tmp
;
237 if (axis
== vec_size
-1) {
238 for (i
= start
; i
< finish
; ) {
239 float max
= indices
[i
].data
[axis
] + fudge
;
240 float *dest
= VEC_ELT(out
, vec_stride
, uniq
);
243 for (j
= 0 ; j
< vec_size
; j
++)
244 dest
[j
] = indices
[i
].data
[j
];
246 for ( ; i
< finish
&& max
>= indices
[i
].data
[axis
]; i
++)
247 indices
[i
].uniq_idx
= uniq
;
252 for (i
= start
; i
< finish
; ) {
254 float max
= indices
[i
].data
[axis
] + fudge
;
255 while (j
< finish
&& max
>= indices
[j
].data
[axis
]) j
++;
257 float *dest
= VEC_ELT(out
, vec_stride
, uniq
);
260 indices
[i
].uniq_idx
= uniq
;
262 for (k
= 0 ; k
< vec_size
; k
++)
263 dest
[k
] = indices
[i
].data
[k
];
267 uniq
= sort_axis( axis
+1, vec_size
, vec_stride
,
268 indices
, i
, j
, out
, uniq
, fudge
);
278 static void extract_indices1( const struct data_idx
*in
, unsigned int *out
,
282 for ( i
= 0 ; i
< n
; i
++ ) {
283 out
[in
[i
].idx
] = in
[i
].uniq_idx
;
288 static void compactify_arrays(void)
291 struct data_idx
*ind
;
293 ind
= (struct data_idx
*) malloc( sizeof(struct data_idx
) * numverts
);
295 for (i
= 0 ; i
< numverts
; i
++) {
297 ind
[i
].data
= data
[i
];
300 numuniq
= sort_axis(0,
301 sizeof(compressed_data
[0])/sizeof(float),
302 sizeof(compressed_data
[0]),
306 (float *)compressed_data
,
310 printf("Nr unique vertex/normal pairs: %d\n", numuniq
);
312 extract_indices1( ind
, indices
, numverts
);
316 static void expand_arrays(void)
320 for (i
= 2 ; i
< numverts
; i
++, parity
^= 1) {
324 memcpy( expanded_data
[(i
-2)*3+0], data
[v0
], sizeof(data
[0]) );
325 memcpy( expanded_data
[(i
-2)*3+1], data
[v1
], sizeof(data
[0]) );
326 memcpy( expanded_data
[(i
-2)*3+2], data
[v2
], sizeof(data
[0]) );
330 static float myrand( float max
)
332 return max
*rand()/(RAND_MAX
+1.0);
336 static void make_tri_indices( void )
338 unsigned int *v
= tri_indices
;
339 unsigned int parity
= 0;
342 for (j
=2;j
<numverts
;j
++,parity
^=1) {
354 num_tri_verts
= v
- tri_indices
;
355 printf("num_tri_verts: %d\n", num_tri_verts
);
357 for (i
= j
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
359 col
[j
][2] = myrand(1);
360 col
[j
][1] = myrand(1);
361 col
[j
][0] = myrand(1);
364 for (i
= 0; i
< numverts
; i
++)
365 strip_indices
[i
] = i
;
368 #define MIN(x,y) (x < y) ? x : y
370 static void draw_surface( unsigned int with_state
)
374 if (with_state
& DISPLAYLIST
) {
375 if ((with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
|MATERIAL_MASK
)) !=
379 fprintf(stderr
, "rebuilding displaylist\n");
382 glDeleteLists( surf1
, 1 );
384 dlist_state
= with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
|
386 surf1
= glGenLists(1);
387 glNewList(surf1
, GL_COMPILE
);
388 draw_surface( dlist_state
);
396 switch (with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
)) {
397 #ifdef GL_EXT_vertex_array
399 case (DRAW_ELTS
|TRIANGLES
):
400 if (with_state
& MATERIALS
) {
401 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
402 GLuint nr
= MIN(num_tri_verts
-i
, 600);
403 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
404 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
405 glDrawElements( GL_TRIANGLES
, nr
, GL_UNSIGNED_INT
, tri_indices
+i
);
408 glDrawElements( GL_TRIANGLES
, num_tri_verts
, GL_UNSIGNED_INT
,
413 case (DRAW_ARRAYS
|TRIANGLES
):
414 glDrawArraysEXT( GL_TRIANGLES
, 0, (numverts
-2)*3 );
417 case (ARRAY_ELT
|TRIANGLES
):
418 if (with_state
& MATERIALS
) {
419 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
420 GLuint nr
= MIN(num_tri_verts
-i
, 600);
422 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
423 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
424 glBegin( GL_TRIANGLES
);
425 for (k
= 0 ; k
< nr
; k
++)
426 glArrayElement( tri_indices
[i
+k
] );
430 glBegin( GL_TRIANGLES
);
431 for (i
= 0 ; i
< num_tri_verts
; i
++)
432 glArrayElement( tri_indices
[i
] );
439 /* Uses the original arrays (including duplicate elements):
441 case (DRAW_ARRAYS
|STRIPS
):
442 glDrawArraysEXT( GL_TRIANGLE_STRIP
, 0, numverts
);
444 case (DRAW_ELTS
|STRIPS
):
445 glDrawElements( GL_TRIANGLE_STRIP
, numverts
,
446 GL_UNSIGNED_INT
, strip_indices
);
449 /* Uses the original arrays (including duplicate elements):
451 case (ARRAY_ELT
|STRIPS
):
452 glBegin( GL_TRIANGLE_STRIP
);
453 for (i
= 0 ; i
< numverts
; i
++)
458 case (DRAW_ARRAYS
|POINTS
):
459 glDrawArraysEXT( GL_POINTS
, 0, numuniq
);
461 case (DRAW_ELTS
|POINTS
):
462 /* can use numuniq with strip_indices as strip_indices[i] == i.
464 glDrawElements( GL_POINTS
, numuniq
,
465 GL_UNSIGNED_INT
, strip_indices
);
467 case (ARRAY_ELT
|POINTS
):
468 /* just emit each unique element once:
470 glBegin( GL_POINTS
);
471 for (i
= 0 ; i
< numuniq
; i
++)
477 case (GLVERTEX
|TRIANGLES
):
478 if (with_state
& MATERIALS
) {
479 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
480 GLuint nr
= MIN(num_tri_verts
-i
, 600);
482 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
483 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
484 glBegin( GL_TRIANGLES
);
485 for (k
= 0 ; k
< nr
; k
++) {
486 glNormal3fv( &compressed_data
[tri_indices
[i
+k
]][3] );
487 glVertex3fv( &compressed_data
[tri_indices
[i
+k
]][0] );
492 glBegin( GL_TRIANGLES
);
493 for (i
= 0 ; i
< num_tri_verts
; i
++) {
494 glNormal3fv( &compressed_data
[tri_indices
[i
]][3] );
495 glVertex3fv( &compressed_data
[tri_indices
[i
]][0] );
501 case (GLVERTEX
|POINTS
):
502 /* Renders all points, but not in strip order... Shouldn't be a
503 * problem, but people may be confused as to why points are so
504 * much faster in this demo... And why cva doesn't help them...
506 glBegin( GL_POINTS
);
507 for ( i
= 0 ; i
< numuniq
; i
++ ) {
508 glNormal3fv( &compressed_data
[i
][3] );
509 glVertex3fv( &compressed_data
[i
][0] );
514 case (GLVERTEX
|STRIPS
):
515 glBegin( GL_TRIANGLE_STRIP
);
516 for (i
=0;i
<numverts
;i
++) {
517 glNormal3fv( &data
[i
][3] );
518 glVertex3fv( &data
[i
][0] );
524 fprintf(stderr
, "unimplemented mode %x...\n",
525 (with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
)));
532 static void Display(void)
534 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
535 draw_surface( state
);
537 if (doubleBuffer
) glutSwapBuffers();
541 /* KW: only do this when necessary, so CVA can re-use results.
543 static void set_matrix( void )
545 glMatrixMode(GL_MODELVIEW
);
547 glTranslatef( 0.0, 0.0, dist
);
548 glRotatef( yrot
, 0.0, 1.0, 0.0 );
549 glRotatef( xrot
, 1.0, 0.0, 0.0 );
552 static void Benchmark( float xdiff
, float ydiff
)
554 int startTime
, endTime
;
556 double seconds
, fps
, triPerSecond
;
558 printf("Benchmarking...\n");
561 startTime
= glutGet(GLUT_ELAPSED_TIME
);
569 endTime
= glutGet(GLUT_ELAPSED_TIME
);
570 } while (endTime
- startTime
< 5000); /* 5 seconds */
573 seconds
= (double) (endTime
- startTime
) / 1000.0;
574 triPerSecond
= (numverts
- 2) * draws
/ seconds
;
575 fps
= draws
/ seconds
;
576 printf("Result: triangles/sec: %g fps: %g\n", triPerSecond
, fps
);
580 static void InitMaterials(void)
582 static float ambient
[] = {0.1, 0.1, 0.1, 1.0};
583 static float diffuse
[] = {0.5, 1.0, 1.0, 1.0};
584 static float position0
[] = {0.0, 0.0, 20.0, 0.0};
585 static float position1
[] = {0.0, 0.0, -20.0, 0.0};
586 static float front_mat_shininess
[] = {60.0};
587 static float front_mat_specular
[] = {0.2, 0.2, 0.2, 1.0};
588 static float front_mat_diffuse
[] = {0.5, 0.28, 0.38, 1.0};
590 static float back_mat_shininess[] = {60.0};
591 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
592 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
594 static float lmodel_ambient
[] = {1.0, 1.0, 1.0, 1.0};
595 static float lmodel_twoside
[] = {GL_FALSE
};
597 glLightfv(GL_LIGHT0
, GL_AMBIENT
, ambient
);
598 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, diffuse
);
599 glLightfv(GL_LIGHT0
, GL_POSITION
, position0
);
602 glLightfv(GL_LIGHT1
, GL_AMBIENT
, ambient
);
603 glLightfv(GL_LIGHT1
, GL_DIFFUSE
, diffuse
);
604 glLightfv(GL_LIGHT1
, GL_POSITION
, position1
);
607 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, lmodel_ambient
);
608 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE
, lmodel_twoside
);
610 glMaterialfv(GL_FRONT_AND_BACK
, GL_SHININESS
, front_mat_shininess
);
611 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, front_mat_specular
);
612 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, front_mat_diffuse
);
614 glPolygonStipple (halftone
);
619 #define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
620 #define CHANGED(o,n,mask) ((n&mask) && (n&mask) != (o&mask) )
622 static void ModeMenu(int m
)
632 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION
));
633 printf("GL_EXTENSIONS: %s\n", (char *) glGetString(GL_EXTENSIONS
));
634 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER
));
638 if (CHANGED(state
, m
, FILTER_MASK
)) {
639 UPDATE(state
, m
, FILTER_MASK
);
640 if (m
& LINEAR_FILTER
) {
641 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
642 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
644 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
645 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
649 if (CHANGED(state
, m
, LIGHT_MASK
)) {
650 UPDATE(state
, m
, LIGHT_MASK
);
652 glEnable(GL_LIGHTING
);
653 glDisable(GL_TEXTURE_GEN_S
);
654 glDisable(GL_TEXTURE_GEN_T
);
655 glDisable(GL_TEXTURE_2D
);
657 else if (m
& UNLIT
) {
658 glDisable(GL_LIGHTING
);
659 glDisable(GL_TEXTURE_GEN_S
);
660 glDisable(GL_TEXTURE_GEN_T
);
661 glDisable(GL_TEXTURE_2D
);
663 else if (m
& REFLECT
) {
664 glDisable(GL_LIGHTING
);
665 glEnable(GL_TEXTURE_GEN_S
);
666 glEnable(GL_TEXTURE_GEN_T
);
667 glEnable(GL_TEXTURE_2D
);
671 if (CHANGED(state
, m
, SHADE_MASK
)) {
672 UPDATE(state
, m
, SHADE_MASK
);
673 if (m
& SHADE_SMOOTH
)
674 glShadeModel(GL_SMOOTH
);
676 glShadeModel(GL_FLAT
);
680 if (CHANGED(state
, m
, CLIP_MASK
)) {
681 UPDATE(state
, m
, CLIP_MASK
);
683 glEnable(GL_CLIP_PLANE0
);
685 glDisable(GL_CLIP_PLANE0
);
689 if (CHANGED(state
, m
, FOG_MASK
)) {
690 UPDATE(state
, m
, FOG_MASK
);
699 if (CHANGED(state
, m
, STIPPLE_MASK
)) {
700 UPDATE(state
, m
, STIPPLE_MASK
);
702 glEnable(GL_POLYGON_STIPPLE
);
705 glDisable(GL_POLYGON_STIPPLE
);
709 if (CHANGED(state
, m
, POLYGON_MASK
)) {
710 UPDATE(state
, m
, POLYGON_MASK
);
711 if (m
& POLYGON_FILL
) {
712 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
715 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
719 #ifdef GL_EXT_vertex_array
720 if (CHANGED(state
, m
, (LOCK_MASK
|RENDER_STYLE_MASK
|PRIMITIVE_MASK
)))
722 if (m
& (PRIMITIVE_MASK
)) {
723 UPDATE(state
, m
, (PRIMITIVE_MASK
));
726 if (m
& (RENDER_STYLE_MASK
)) {
727 UPDATE(state
, m
, (RENDER_STYLE_MASK
));
731 UPDATE(state
, m
, (LOCK_MASK
));
735 print_flags("primitive", state
& PRIMITIVE_MASK
);
736 print_flags("render style", state
& RENDER_STYLE_MASK
);
738 if ((state
& PRIMITIVE_MASK
) != STRIPS
&&
739 ((state
& RENDER_STYLE_MASK
) == DRAW_ELTS
||
740 (state
& RENDER_STYLE_MASK
) == ARRAY_ELT
||
741 (state
& PRIMITIVE_MASK
) == POINTS
))
743 fprintf(stderr
, "enabling small arrays\n");
744 /* Rendering any primitive with draw-element/array-element
745 * --> Can't do strips here as ordering has been lost in
746 * compaction process...
748 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), numuniq
,
750 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), numuniq
,
751 &compressed_data
[0][3]);
752 #ifdef GL_EXT_compiled_vertex_array
753 if (allowed
& LOCKED
) {
754 if (state
& LOCKED
) {
755 glLockArraysEXT( 0, numuniq
);
762 else if ((state
& PRIMITIVE_MASK
) == TRIANGLES
&&
763 (state
& RENDER_STYLE_MASK
) == DRAW_ARRAYS
) {
764 fprintf(stderr
, "enabling big arrays\n");
765 /* Only get here for TRIANGLES and drawarrays
767 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), (numverts
-2) * 3,
769 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), (numverts
-2) * 3,
770 &expanded_data
[0][3]);
772 #ifdef GL_EXT_compiled_vertex_array
773 if (allowed
& LOCKED
) {
774 if (state
& LOCKED
) {
775 glLockArraysEXT( 0, (numverts
-2)*3 );
783 fprintf(stderr
, "enabling normal arrays\n");
784 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), numverts
, data
);
785 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), numverts
, &data
[0][3]);
786 #ifdef GL_EXT_compiled_vertex_array
787 if (allowed
& LOCKED
) {
788 if (state
& LOCKED
) {
789 glLockArraysEXT( 0, numverts
);
801 if (m
& DLIST_MASK
) {
802 UPDATE(state
, m
, DLIST_MASK
);
805 if (m
& MATERIAL_MASK
) {
806 UPDATE(state
, m
, MATERIAL_MASK
);
809 print_flags("new flags", state
);
816 static void Init(int argc
, char *argv
[])
818 GLfloat fogColor
[4] = {0.5,1.0,0.5,1.0};
828 glClearColor(0.0, 0.0, 1.0, 0.0);
829 glEnable( GL_DEPTH_TEST
);
830 glEnable( GL_VERTEX_ARRAY_EXT
);
831 glEnable( GL_NORMAL_ARRAY_EXT
);
833 glMatrixMode(GL_PROJECTION
);
835 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
837 glMatrixMode(GL_MODELVIEW
);
839 glClipPlane(GL_CLIP_PLANE0
, plane
);
845 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
846 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_FASTEST
);
848 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_SPHERE_MAP
);
849 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_SPHERE_MAP
);
852 /* Green fog is easy to see */
853 glFogi(GL_FOG_MODE
,GL_EXP2
);
854 glFogfv(GL_FOG_COLOR
,fogColor
);
855 glFogf(GL_FOG_DENSITY
,0.15);
856 glHint(GL_FOG_HINT
,GL_DONT_CARE
);
859 static int firsttime
= 1;
866 if (!LoadRGBMipmaps(TEXTURE_FILE
, GL_RGB
)) {
867 printf("Error: couldn't load texture image\n");
873 ModeMenu(SHADE_SMOOTH
|
886 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
887 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION
));
888 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR
));
889 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS
));
895 static void Reshape(int width
, int height
)
897 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
902 static void Key( unsigned char key
, int x
, int y
)
910 ModeMenu((state
^ FOG_MASK
) & FOG_MASK
);
913 ModeMenu((state
^ SHADE_MASK
) & SHADE_MASK
);
916 ModeMenu((state
^ STIPPLE_MASK
) & STIPPLE_MASK
);
919 ModeMenu((state
^ LIGHT_MASK
) & (LIT
|UNLIT
));
922 ModeMenu((state
^ MATERIAL_MASK
) & MATERIAL_MASK
);
925 ModeMenu((state
^ CLIP_MASK
) & CLIP_MASK
);
928 ModeMenu((LOCKED
|IMMEDIATE
|DRAW_ELTS
|TRIANGLES
) & allowed
);
931 ModeMenu(UNLOCKED
|IMMEDIATE
|GLVERTEX
|STRIPS
);
952 glMatrixMode(GL_MODELVIEW
);
954 glClipPlane(GL_CLIP_PLANE0
, plane
);
961 glMatrixMode(GL_MODELVIEW
);
963 glClipPlane(GL_CLIP_PLANE0
, plane
);
974 static void SpecialKey( int key
, int x
, int y
)
1000 static GLint
Args(int argc
, char **argv
)
1005 for (i
= 1; i
< argc
; i
++) {
1006 if (strcmp(argv
[i
], "-sb") == 0) {
1007 doubleBuffer
= GL_FALSE
;
1009 else if (strcmp(argv
[i
], "-db") == 0) {
1010 doubleBuffer
= GL_TRUE
;
1012 else if (strcmp(argv
[i
], "-info") == 0) {
1013 PrintInfo
= GL_TRUE
;
1015 else if (strcmp(argv
[i
], "-10") == 0) {
1018 else if (strcmp(argv
[i
], "-100") == 0) {
1021 else if (strcmp(argv
[i
], "-1000") == 0) {
1025 printf("%s (Bad option).\n", argv
[i
]);
1033 int main(int argc
, char **argv
)
1038 GLuint arg_mode
= Args(argc
, argv
);
1040 if (arg_mode
& QUIT
)
1043 read_surface( "isosurf.dat" );
1045 glutInit( &argc
, argv
);
1046 glutInitWindowPosition(0, 0);
1047 glutInitWindowSize(400, 400);
1051 type
|= (doubleBuffer
) ? GLUT_DOUBLE
: GLUT_SINGLE
;
1052 glutInitDisplayMode(type
);
1054 if (glutCreateWindow("Isosurface") <= 0) {
1058 /* Make sure server supports the vertex array extension */
1059 extensions
= (char *) glGetString( GL_EXTENSIONS
);
1061 if (!strstr( extensions
, "GL_EXT_vertex_array" ))
1063 printf("Vertex arrays not supported by this renderer\n");
1064 allowed
&= ~(LOCKED
|DRAW_ARRAYS
|DRAW_ELTS
|ARRAY_ELT
);
1066 else if (!strstr( extensions
, "GL_EXT_compiled_vertex_array" ))
1068 printf("Compiled vertex arrays not supported by this renderer\n");
1075 glutCreateMenu(ModeMenu
);
1076 glutAddMenuEntry("GL info", GLINFO
);
1077 glutAddMenuEntry("", 0);
1078 glutAddMenuEntry("Lit", LIT
);
1079 glutAddMenuEntry("Unlit", UNLIT
);
1080 glutAddMenuEntry("Reflect", REFLECT
);
1081 glutAddMenuEntry("", 0);
1082 glutAddMenuEntry("Smooth", SHADE_SMOOTH
);
1083 glutAddMenuEntry("Flat", SHADE_FLAT
);
1084 glutAddMenuEntry("", 0);
1085 glutAddMenuEntry("Fog", FOG
);
1086 glutAddMenuEntry("No Fog", NO_FOG
);
1087 glutAddMenuEntry("", 0);
1088 glutAddMenuEntry("Stipple", STIPPLE
);
1089 glutAddMenuEntry("No Stipple", NO_STIPPLE
);
1090 glutAddMenuEntry("", 0);
1091 glutAddMenuEntry("Polygon Mode Fill", POLYGON_FILL
);
1092 glutAddMenuEntry("Polygon Mode Line", POLYGON_LINE
);
1093 glutAddMenuEntry("", 0);
1094 glutAddMenuEntry("Point Filtered", POINT_FILTER
);
1095 glutAddMenuEntry("Linear Filtered", LINEAR_FILTER
);
1096 glutAddMenuEntry("", 0);
1097 glutAddMenuEntry("GL_TRIANGLES", TRIANGLES
);
1098 glutAddMenuEntry("GL_TRIANGLE_STRIPS", STRIPS
);
1099 glutAddMenuEntry("GL_POINTS", POINTS
);
1100 glutAddMenuEntry("", 0);
1101 glutAddMenuEntry("Displaylist", DISPLAYLIST
);
1102 glutAddMenuEntry("Immediate", IMMEDIATE
);
1103 glutAddMenuEntry("", 0);
1104 if (allowed
& LOCKED
) {
1105 glutAddMenuEntry("Locked Arrays (CVA)", LOCKED
);
1106 glutAddMenuEntry("Unlocked Arrays", UNLOCKED
);
1107 glutAddMenuEntry("", 0);
1109 glutAddMenuEntry("glVertex", GLVERTEX
);
1110 if (allowed
& DRAW_ARRAYS
) {
1111 glutAddMenuEntry("glDrawElements", DRAW_ELTS
);
1112 glutAddMenuEntry("glDrawArrays", DRAW_ARRAYS
);
1113 glutAddMenuEntry("glArrayElement", ARRAY_ELT
);
1115 glutAddMenuEntry("", 0);
1116 glutAddMenuEntry("Quit", QUIT
);
1117 glutAttachMenu(GLUT_RIGHT_BUTTON
);
1119 glutReshapeFunc(Reshape
);
1120 glutKeyboardFunc(Key
);
1121 glutSpecialFunc(SpecialKey
);
1122 glutDisplayFunc(Display
);