1 /* $Id: isosurf.c,v 1.15 2002/10/18 17:47:35 kschultz Exp $ */
4 * Display an isosurface of 3-D wind speed volume.
6 * Command line options:
7 * -info print GL implementation information
9 * Brian Paul This file in public domain.
16 * - Arrow keys to rotate
17 * - 's' toggles smooth shading
18 * - 'l' toggles lighting
20 * - 'I' and 'i' zoom in and out
21 * - 'c' toggles a user clip plane
22 * - 'm' toggles colorful materials in GL_TRIANGLES modes.
23 * - '+' and '-' move the user clip plane
25 * Other options are available via the popup menu.
37 #define GL_GLEXT_LEGACY
40 #include "readtex.c" /* I know, this is a hack. KW: me too. */
41 #define TEXTURE_FILE "../images/reflect.rgb"
43 #define LIT 0x00000001
44 #define UNLIT 0x00000002
45 #define REFLECT 0x00000004
46 #define POINT_FILTER 0x00000008
47 #define LINEAR_FILTER 0x00000010
48 #define GLVERTEX 0x00000020
49 #define DRAW_ELTS 0x00000040
50 #define DRAW_ARRAYS 0x00000080
51 #define ARRAY_ELT 0x00000100
52 #define LOCKED 0x00000200
53 #define UNLOCKED 0x00000400
54 #define IMMEDIATE 0x00000800
55 #define DISPLAYLIST 0x00001000
56 #define SHADE_SMOOTH 0x00002000
57 #define SHADE_FLAT 0x00004000
58 #define TRIANGLES 0x00008000
59 #define STRIPS 0x00010000
60 #define POINTS 0x00020000
61 #define USER_CLIP 0x00040000
62 #define NO_USER_CLIP 0x00080000
63 #define MATERIALS 0x00100000
64 #define NO_MATERIALS 0x00200000
65 #define FOG 0x00400000
66 #define NO_FOG 0x00800000
67 #define QUIT 0x01000000
68 #define GLINFO 0x02000000
69 #define STIPPLE 0x04000000
70 #define NO_STIPPLE 0x08000000
71 #define POLYGON_FILL 0x10000000
72 #define POLYGON_LINE 0x20000000
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)
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\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, " : "");
182 #define COMPARE_FUNC( AXIS ) \
183 static int compare_axis_##AXIS( const void *a, const void *b ) \
185 float t = ( (*(struct data_idx *)a).data[AXIS] - \
186 (*(struct data_idx *)b).data[AXIS] ); \
188 if (t < 0) return -1; \
189 if (t > 0) return 1; \
201 int (*(compare
[7]))( const void *a
, const void *b
) =
213 #define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i)
215 static int sort_axis( int axis
,
218 struct data_idx
*indices
,
227 if (finish
-start
> 2)
229 qsort( indices
+start
, finish
-start
, sizeof(*indices
), compare
[axis
] );
231 else if (indices
[start
].data
[axis
] > indices
[start
+1].data
[axis
])
233 struct data_idx tmp
= indices
[start
];
234 indices
[start
] = indices
[start
+1];
235 indices
[start
+1] = tmp
;
238 if (axis
== vec_size
-1) {
239 for (i
= start
; i
< finish
; ) {
240 float max
= indices
[i
].data
[axis
] + fudge
;
241 float *dest
= VEC_ELT(out
, vec_stride
, uniq
);
244 for (j
= 0 ; j
< vec_size
; j
++)
245 dest
[j
] = indices
[i
].data
[j
];
247 for ( ; i
< finish
&& max
>= indices
[i
].data
[axis
]; i
++)
248 indices
[i
].uniq_idx
= uniq
;
253 for (i
= start
; i
< finish
; ) {
255 float max
= indices
[i
].data
[axis
] + fudge
;
256 while (j
< finish
&& max
>= indices
[j
].data
[axis
]) j
++;
258 float *dest
= VEC_ELT(out
, vec_stride
, uniq
);
261 indices
[i
].uniq_idx
= uniq
;
263 for (k
= 0 ; k
< vec_size
; k
++)
264 dest
[k
] = indices
[i
].data
[k
];
268 uniq
= sort_axis( axis
+1, vec_size
, vec_stride
,
269 indices
, i
, j
, out
, uniq
, fudge
);
279 static void extract_indices1( const struct data_idx
*in
, unsigned int *out
,
283 for ( i
= 0 ; i
< n
; i
++ ) {
284 out
[in
[i
].idx
] = in
[i
].uniq_idx
;
289 static void compactify_arrays(void)
292 struct data_idx
*ind
;
294 ind
= (struct data_idx
*) malloc( sizeof(struct data_idx
) * numverts
);
296 for (i
= 0 ; i
< numverts
; i
++) {
298 ind
[i
].data
= data
[i
];
301 numuniq
= sort_axis(0,
302 sizeof(compressed_data
[0])/sizeof(float),
303 sizeof(compressed_data
[0]),
307 (float *)compressed_data
,
311 printf("Nr unique vertex/normal pairs: %d\n", numuniq
);
313 extract_indices1( ind
, indices
, numverts
);
317 static void expand_arrays(void)
321 for (i
= 2 ; i
< numverts
; i
++, parity
^= 1) {
325 memcpy( expanded_data
[(i
-2)*3+0], data
[v0
], sizeof(data
[0]) );
326 memcpy( expanded_data
[(i
-2)*3+1], data
[v1
], sizeof(data
[0]) );
327 memcpy( expanded_data
[(i
-2)*3+2], data
[v2
], sizeof(data
[0]) );
331 static float myrand( float max
)
333 return max
*rand()/(RAND_MAX
+1.0);
337 static void make_tri_indices( void )
339 unsigned int *v
= tri_indices
;
340 unsigned int parity
= 0;
343 for (j
=2;j
<numverts
;j
++,parity
^=1) {
355 num_tri_verts
= v
- tri_indices
;
356 printf("num_tri_verts: %d\n", num_tri_verts
);
358 for (i
= j
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
360 col
[j
][2] = myrand(1);
361 col
[j
][1] = myrand(1);
362 col
[j
][0] = myrand(1);
365 for (i
= 0; i
< numverts
; i
++)
366 strip_indices
[i
] = i
;
369 #define MIN(x,y) (x < y) ? x : y
371 static void draw_surface( unsigned int with_state
)
375 if (with_state
& DISPLAYLIST
) {
376 if ((with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
|MATERIAL_MASK
)) !=
380 fprintf(stderr
, "rebuilding displaylist\n");
383 glDeleteLists( surf1
, 1 );
385 dlist_state
= with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
|
387 surf1
= glGenLists(1);
388 glNewList(surf1
, GL_COMPILE
);
389 draw_surface( dlist_state
);
397 switch (with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
)) {
398 #ifdef GL_EXT_vertex_array
400 case (DRAW_ELTS
|TRIANGLES
):
401 if (with_state
& MATERIALS
) {
402 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
403 GLuint nr
= MIN(num_tri_verts
-i
, 600);
404 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
405 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
406 glDrawElements( GL_TRIANGLES
, nr
, GL_UNSIGNED_INT
, tri_indices
+i
);
409 glDrawElements( GL_TRIANGLES
, num_tri_verts
, GL_UNSIGNED_INT
,
414 case (DRAW_ARRAYS
|TRIANGLES
):
415 glDrawArraysEXT( GL_TRIANGLES
, 0, (numverts
-2)*3 );
418 case (ARRAY_ELT
|TRIANGLES
):
419 if (with_state
& MATERIALS
) {
420 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
421 GLuint nr
= MIN(num_tri_verts
-i
, 600);
423 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
424 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
425 glBegin( GL_TRIANGLES
);
426 for (k
= 0 ; k
< nr
; k
++)
427 glArrayElement( tri_indices
[i
+k
] );
431 glBegin( GL_TRIANGLES
);
432 for (i
= 0 ; i
< num_tri_verts
; i
++)
433 glArrayElement( tri_indices
[i
] );
440 /* Uses the original arrays (including duplicate elements):
442 case (DRAW_ARRAYS
|STRIPS
):
443 glDrawArraysEXT( GL_TRIANGLE_STRIP
, 0, numverts
);
445 case (DRAW_ELTS
|STRIPS
):
446 glDrawElements( GL_TRIANGLE_STRIP
, numverts
,
447 GL_UNSIGNED_INT
, strip_indices
);
450 /* Uses the original arrays (including duplicate elements):
452 case (ARRAY_ELT
|STRIPS
):
453 glBegin( GL_TRIANGLE_STRIP
);
454 for (i
= 0 ; i
< numverts
; i
++)
459 case (DRAW_ARRAYS
|POINTS
):
460 glDrawArraysEXT( GL_POINTS
, 0, numuniq
);
462 case (DRAW_ELTS
|POINTS
):
463 /* can use numuniq with strip_indices as strip_indices[i] == i.
465 glDrawElements( GL_POINTS
, numuniq
,
466 GL_UNSIGNED_INT
, strip_indices
);
468 case (ARRAY_ELT
|POINTS
):
469 /* just emit each unique element once:
471 glBegin( GL_POINTS
);
472 for (i
= 0 ; i
< numuniq
; i
++)
478 case (GLVERTEX
|TRIANGLES
):
479 if (with_state
& MATERIALS
) {
480 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
481 GLuint nr
= MIN(num_tri_verts
-i
, 600);
483 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
484 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
485 glBegin( GL_TRIANGLES
);
486 for (k
= 0 ; k
< nr
; k
++) {
487 glNormal3fv( &compressed_data
[tri_indices
[i
+k
]][3] );
488 glVertex3fv( &compressed_data
[tri_indices
[i
+k
]][0] );
493 glBegin( GL_TRIANGLES
);
494 for (i
= 0 ; i
< num_tri_verts
; i
++) {
495 glNormal3fv( &compressed_data
[tri_indices
[i
]][3] );
496 glVertex3fv( &compressed_data
[tri_indices
[i
]][0] );
502 case (GLVERTEX
|POINTS
):
503 /* Renders all points, but not in strip order... Shouldn't be a
504 * problem, but people may be confused as to why points are so
505 * much faster in this demo... And why cva doesn't help them...
507 glBegin( GL_POINTS
);
508 for ( i
= 0 ; i
< numuniq
; i
++ ) {
509 glNormal3fv( &compressed_data
[i
][3] );
510 glVertex3fv( &compressed_data
[i
][0] );
515 case (GLVERTEX
|STRIPS
):
516 glBegin( GL_TRIANGLE_STRIP
);
517 for (i
=0;i
<numverts
;i
++) {
518 glNormal3fv( &data
[i
][3] );
519 glVertex3fv( &data
[i
][0] );
525 fprintf(stderr
, "unimplemented mode %x...\n",
526 (with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
)));
533 static void Display(void)
535 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
536 draw_surface( state
);
538 if (doubleBuffer
) glutSwapBuffers();
542 /* KW: only do this when necessary, so CVA can re-use results.
544 static void set_matrix( void )
546 glMatrixMode(GL_MODELVIEW
);
548 glTranslatef( 0.0, 0.0, dist
);
549 glRotatef( yrot
, 0.0, 1.0, 0.0 );
550 glRotatef( xrot
, 1.0, 0.0, 0.0 );
553 static void Benchmark( float xdiff
, float ydiff
)
555 int startTime
, endTime
;
557 double seconds
, fps
, triPerSecond
;
559 printf("Benchmarking...\n");
562 startTime
= glutGet(GLUT_ELAPSED_TIME
);
570 endTime
= glutGet(GLUT_ELAPSED_TIME
);
571 } while (endTime
- startTime
< 5000); /* 5 seconds */
574 seconds
= (double) (endTime
- startTime
) / 1000.0;
575 triPerSecond
= (numverts
- 2) * draws
/ seconds
;
576 fps
= draws
/ seconds
;
577 printf("Result: triangles/sec: %g fps: %g\n", triPerSecond
, fps
);
581 static void InitMaterials(void)
583 static float ambient
[] = {0.1, 0.1, 0.1, 1.0};
584 static float diffuse
[] = {0.5, 1.0, 1.0, 1.0};
585 static float position0
[] = {0.0, 0.0, 20.0, 0.0};
586 static float position1
[] = {0.0, 0.0, -20.0, 0.0};
587 static float front_mat_shininess
[] = {60.0};
588 static float front_mat_specular
[] = {0.2, 0.2, 0.2, 1.0};
589 static float front_mat_diffuse
[] = {0.5, 0.28, 0.38, 1.0};
591 static float back_mat_shininess[] = {60.0};
592 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
593 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
595 static float lmodel_ambient
[] = {1.0, 1.0, 1.0, 1.0};
596 static float lmodel_twoside
[] = {GL_FALSE
};
598 glLightfv(GL_LIGHT0
, GL_AMBIENT
, ambient
);
599 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, diffuse
);
600 glLightfv(GL_LIGHT0
, GL_POSITION
, position0
);
603 glLightfv(GL_LIGHT1
, GL_AMBIENT
, ambient
);
604 glLightfv(GL_LIGHT1
, GL_DIFFUSE
, diffuse
);
605 glLightfv(GL_LIGHT1
, GL_POSITION
, position1
);
608 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, lmodel_ambient
);
609 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE
, lmodel_twoside
);
611 glMaterialfv(GL_FRONT_AND_BACK
, GL_SHININESS
, front_mat_shininess
);
612 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, front_mat_specular
);
613 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, front_mat_diffuse
);
615 glPolygonStipple (halftone
);
620 #define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
621 #define CHANGED(o,n,mask) ((n&mask) && (n&mask) != (o&mask) )
623 static void ModeMenu(int m
)
633 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION
));
634 printf("GL_EXTENSIONS: %s\n", (char *) glGetString(GL_EXTENSIONS
));
635 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER
));
639 if (CHANGED(state
, m
, FILTER_MASK
)) {
640 UPDATE(state
, m
, FILTER_MASK
);
641 if (m
& LINEAR_FILTER
) {
642 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
643 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
645 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
646 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
650 if (CHANGED(state
, m
, LIGHT_MASK
)) {
651 UPDATE(state
, m
, LIGHT_MASK
);
653 glEnable(GL_LIGHTING
);
654 glDisable(GL_TEXTURE_GEN_S
);
655 glDisable(GL_TEXTURE_GEN_T
);
656 glDisable(GL_TEXTURE_2D
);
658 else if (m
& UNLIT
) {
659 glDisable(GL_LIGHTING
);
660 glDisable(GL_TEXTURE_GEN_S
);
661 glDisable(GL_TEXTURE_GEN_T
);
662 glDisable(GL_TEXTURE_2D
);
664 else if (m
& REFLECT
) {
665 glDisable(GL_LIGHTING
);
666 glEnable(GL_TEXTURE_GEN_S
);
667 glEnable(GL_TEXTURE_GEN_T
);
668 glEnable(GL_TEXTURE_2D
);
672 if (CHANGED(state
, m
, SHADE_MASK
)) {
673 UPDATE(state
, m
, SHADE_MASK
);
674 if (m
& SHADE_SMOOTH
)
675 glShadeModel(GL_SMOOTH
);
677 glShadeModel(GL_FLAT
);
681 if (CHANGED(state
, m
, CLIP_MASK
)) {
682 UPDATE(state
, m
, CLIP_MASK
);
684 glEnable(GL_CLIP_PLANE0
);
686 glDisable(GL_CLIP_PLANE0
);
690 if (CHANGED(state
, m
, FOG_MASK
)) {
691 UPDATE(state
, m
, FOG_MASK
);
700 if (CHANGED(state
, m
, STIPPLE_MASK
)) {
701 UPDATE(state
, m
, STIPPLE_MASK
);
703 glEnable(GL_POLYGON_STIPPLE
);
706 glDisable(GL_POLYGON_STIPPLE
);
710 if (CHANGED(state
, m
, POLYGON_MASK
)) {
711 UPDATE(state
, m
, POLYGON_MASK
);
712 if (m
& POLYGON_FILL
) {
713 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
716 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
720 #ifdef GL_EXT_vertex_array
721 if (CHANGED(state
, m
, (LOCK_MASK
|RENDER_STYLE_MASK
|PRIMITIVE_MASK
)))
723 if (m
& (PRIMITIVE_MASK
)) {
724 UPDATE(state
, m
, (PRIMITIVE_MASK
));
727 if (m
& (RENDER_STYLE_MASK
)) {
728 UPDATE(state
, m
, (RENDER_STYLE_MASK
));
732 UPDATE(state
, m
, (LOCK_MASK
));
736 print_flags("primitive", state
& PRIMITIVE_MASK
);
737 print_flags("render style", state
& RENDER_STYLE_MASK
);
739 if ((state
& PRIMITIVE_MASK
) != STRIPS
&&
740 ((state
& RENDER_STYLE_MASK
) == DRAW_ELTS
||
741 (state
& RENDER_STYLE_MASK
) == ARRAY_ELT
||
742 (state
& PRIMITIVE_MASK
) == POINTS
))
744 fprintf(stderr
, "enabling small arrays\n");
745 /* Rendering any primitive with draw-element/array-element
746 * --> Can't do strips here as ordering has been lost in
747 * compaction process...
749 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), numuniq
,
751 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), numuniq
,
752 &compressed_data
[0][3]);
753 #ifdef GL_EXT_compiled_vertex_array
754 if (allowed
& LOCKED
) {
755 if (state
& LOCKED
) {
756 glLockArraysEXT( 0, numuniq
);
763 else if ((state
& PRIMITIVE_MASK
) == TRIANGLES
&&
764 (state
& RENDER_STYLE_MASK
) == DRAW_ARRAYS
) {
765 fprintf(stderr
, "enabling big arrays\n");
766 /* Only get here for TRIANGLES and drawarrays
768 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), (numverts
-2) * 3,
770 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), (numverts
-2) * 3,
771 &expanded_data
[0][3]);
773 #ifdef GL_EXT_compiled_vertex_array
774 if (allowed
& LOCKED
) {
775 if (state
& LOCKED
) {
776 glLockArraysEXT( 0, (numverts
-2)*3 );
784 fprintf(stderr
, "enabling normal arrays\n");
785 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), numverts
, data
);
786 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), numverts
, &data
[0][3]);
787 #ifdef GL_EXT_compiled_vertex_array
788 if (allowed
& LOCKED
) {
789 if (state
& LOCKED
) {
790 glLockArraysEXT( 0, numverts
);
802 if (m
& DLIST_MASK
) {
803 UPDATE(state
, m
, DLIST_MASK
);
806 if (m
& MATERIAL_MASK
) {
807 UPDATE(state
, m
, MATERIAL_MASK
);
810 print_flags("new flags", state
);
817 static void Init(int argc
, char *argv
[])
819 GLfloat fogColor
[4] = {0.5,1.0,0.5,1.0};
829 glClearColor(0.0, 0.0, 1.0, 0.0);
830 glEnable( GL_DEPTH_TEST
);
831 glEnable( GL_VERTEX_ARRAY_EXT
);
832 glEnable( GL_NORMAL_ARRAY_EXT
);
834 glMatrixMode(GL_PROJECTION
);
836 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
838 glMatrixMode(GL_MODELVIEW
);
840 glClipPlane(GL_CLIP_PLANE0
, plane
);
846 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
847 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_FASTEST
);
849 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_SPHERE_MAP
);
850 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_SPHERE_MAP
);
853 /* Green fog is easy to see */
854 glFogi(GL_FOG_MODE
,GL_EXP2
);
855 glFogfv(GL_FOG_COLOR
,fogColor
);
856 glFogf(GL_FOG_DENSITY
,0.15);
857 glHint(GL_FOG_HINT
,GL_DONT_CARE
);
860 static int firsttime
= 1;
867 if (!LoadRGBMipmaps(TEXTURE_FILE
, GL_RGB
)) {
868 printf("Error: couldn't load texture image\n");
874 ModeMenu(SHADE_SMOOTH
|
887 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
888 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION
));
889 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR
));
890 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS
));
896 static void Reshape(int width
, int height
)
898 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
903 static void Key( unsigned char key
, int x
, int y
)
911 ModeMenu((state
^ FOG_MASK
) & FOG_MASK
);
914 ModeMenu((state
^ SHADE_MASK
) & SHADE_MASK
);
917 ModeMenu((state
^ STIPPLE_MASK
) & STIPPLE_MASK
);
920 ModeMenu((state
^ LIGHT_MASK
) & (LIT
|UNLIT
));
923 ModeMenu((state
^ MATERIAL_MASK
) & MATERIAL_MASK
);
926 ModeMenu((state
^ CLIP_MASK
) & CLIP_MASK
);
929 ModeMenu((LOCKED
|IMMEDIATE
|DRAW_ELTS
|TRIANGLES
) & allowed
);
932 ModeMenu(UNLOCKED
|IMMEDIATE
|GLVERTEX
|STRIPS
);
953 glMatrixMode(GL_MODELVIEW
);
955 glClipPlane(GL_CLIP_PLANE0
, plane
);
962 glMatrixMode(GL_MODELVIEW
);
964 glClipPlane(GL_CLIP_PLANE0
, plane
);
975 static void SpecialKey( int key
, int x
, int y
)
1001 static GLint
Args(int argc
, char **argv
)
1006 for (i
= 1; i
< argc
; i
++) {
1007 if (strcmp(argv
[i
], "-sb") == 0) {
1008 doubleBuffer
= GL_FALSE
;
1010 else if (strcmp(argv
[i
], "-db") == 0) {
1011 doubleBuffer
= GL_TRUE
;
1013 else if (strcmp(argv
[i
], "-info") == 0) {
1014 PrintInfo
= GL_TRUE
;
1016 else if (strcmp(argv
[i
], "-10") == 0) {
1019 else if (strcmp(argv
[i
], "-100") == 0) {
1022 else if (strcmp(argv
[i
], "-1000") == 0) {
1026 printf("%s (Bad option).\n", argv
[i
]);
1034 int main(int argc
, char **argv
)
1039 GLuint arg_mode
= Args(argc
, argv
);
1041 if (arg_mode
& QUIT
)
1044 read_surface( "isosurf.dat" );
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
);