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.
39 #define TEXTURE_FILE "../images/reflect.rgb"
41 #define LIT 0x00000001
42 #define UNLIT 0x00000002
43 #define REFLECT 0x00000004
44 #define POINT_FILTER 0x00000008
45 #define LINEAR_FILTER 0x00000010
46 #define GLVERTEX 0x00000020
47 #define DRAW_ELTS 0x00000040
48 #define DRAW_ARRAYS 0x00000080
49 #define ARRAY_ELT 0x00000100
50 #define LOCKED 0x00000200
51 #define UNLOCKED 0x00000400
52 #define IMMEDIATE 0x00000800
53 #define DISPLAYLIST 0x00001000
54 #define SHADE_SMOOTH 0x00002000
55 #define SHADE_FLAT 0x00004000
56 #define TRIANGLES 0x00008000
57 #define STRIPS 0x00010000
58 #define POINTS 0x00020000
59 #define USER_CLIP 0x00040000
60 #define NO_USER_CLIP 0x00080000
61 #define MATERIALS 0x00100000
62 #define NO_MATERIALS 0x00200000
63 #define FOG 0x00400000
64 #define NO_FOG 0x00800000
65 #define QUIT 0x01000000
66 #define GLINFO 0x02000000
67 #define STIPPLE 0x04000000
68 #define NO_STIPPLE 0x08000000
69 #define POLYGON_FILL 0x10000000
70 #define POLYGON_LINE 0x20000000
71 #define POLYGON_POINT 0x40000000
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|POLYGON_POINT)
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
) {
135 result
= 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] );
143 printf("%d vertices, %d triangles\n", numverts
, numverts
-2);
149 static void print_flags( const char *msg
, GLuint flags
)
152 "%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
154 (flags
& GLVERTEX
) ? "glVertex, " : "",
155 (flags
& DRAW_ARRAYS
) ? "glDrawArrays, " : "",
156 (flags
& DRAW_ELTS
) ? "glDrawElements, " : "",
157 (flags
& ARRAY_ELT
) ? "glArrayElement, " : "",
158 (flags
& LOCKED
) ? "locked arrays, " : "",
159 (flags
& TRIANGLES
) ? "GL_TRIANGLES, " : "",
160 (flags
& STRIPS
) ? "GL_TRIANGLE_STRIP, " : "",
161 (flags
& POINTS
) ? "GL_POINTS, " : "",
162 (flags
& DISPLAYLIST
) ? "as a displaylist, " : "",
163 (flags
& LIT
) ? "lit, " : "",
164 (flags
& UNLIT
) ? "unlit, " : "",
165 (flags
& REFLECT
) ? "reflect, " : "",
166 (flags
& SHADE_FLAT
) ? "flat-shaded, " : "",
167 (flags
& USER_CLIP
) ? "user_clip, " : "",
168 (flags
& MATERIALS
) ? "materials, " : "",
169 (flags
& FOG
) ? "fog, " : "",
170 (flags
& STIPPLE
) ? "stipple, " : "",
171 (flags
& POLYGON_LINE
) ? "polygon mode line, " : "",
172 (flags
& POLYGON_POINT
) ? "polygon mode point, " : "");
184 #define COMPARE_FUNC( AXIS ) \
185 static int compare_axis_##AXIS( const void *a, const void *b ) \
187 float t = ( (*(struct data_idx *)a).data[AXIS] - \
188 (*(struct data_idx *)b).data[AXIS] ); \
190 if (t < 0) return -1; \
191 if (t > 0) return 1; \
203 int (*(compare
[7]))( const void *a
, const void *b
) =
215 #define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i)
217 static int sort_axis( int axis
,
220 struct data_idx
*indices
,
229 if (finish
-start
> 2)
231 qsort( indices
+start
, finish
-start
, sizeof(*indices
), compare
[axis
] );
233 else if (indices
[start
].data
[axis
] > indices
[start
+1].data
[axis
])
235 struct data_idx tmp
= indices
[start
];
236 indices
[start
] = indices
[start
+1];
237 indices
[start
+1] = tmp
;
240 if (axis
== vec_size
-1) {
241 for (i
= start
; i
< finish
; ) {
242 float max
= indices
[i
].data
[axis
] + fudge
;
243 float *dest
= VEC_ELT(out
, vec_stride
, uniq
);
246 for (j
= 0 ; j
< vec_size
; j
++)
247 dest
[j
] = indices
[i
].data
[j
];
249 for ( ; i
< finish
&& max
>= indices
[i
].data
[axis
]; i
++)
250 indices
[i
].uniq_idx
= uniq
;
255 for (i
= start
; i
< finish
; ) {
257 float max
= indices
[i
].data
[axis
] + fudge
;
258 while (j
< finish
&& max
>= indices
[j
].data
[axis
]) j
++;
260 float *dest
= VEC_ELT(out
, vec_stride
, uniq
);
263 indices
[i
].uniq_idx
= uniq
;
265 for (k
= 0 ; k
< vec_size
; k
++)
266 dest
[k
] = indices
[i
].data
[k
];
270 uniq
= sort_axis( axis
+1, vec_size
, vec_stride
,
271 indices
, i
, j
, out
, uniq
, fudge
);
281 static void extract_indices1( const struct data_idx
*in
, unsigned int *out
,
285 for ( i
= 0 ; i
< n
; i
++ ) {
286 out
[in
[i
].idx
] = in
[i
].uniq_idx
;
291 static void compactify_arrays(void)
294 struct data_idx
*ind
;
296 ind
= (struct data_idx
*) malloc( sizeof(struct data_idx
) * numverts
);
298 for (i
= 0 ; i
< numverts
; i
++) {
300 ind
[i
].data
= data
[i
];
303 numuniq
= sort_axis(0,
304 sizeof(compressed_data
[0])/sizeof(float),
305 sizeof(compressed_data
[0]),
309 (float *)compressed_data
,
313 printf("Nr unique vertex/normal pairs: %d\n", numuniq
);
315 extract_indices1( ind
, indices
, numverts
);
319 static void expand_arrays(void)
323 for (i
= 2 ; i
< numverts
; i
++, parity
^= 1) {
327 memcpy( expanded_data
[(i
-2)*3+0], data
[v0
], sizeof(data
[0]) );
328 memcpy( expanded_data
[(i
-2)*3+1], data
[v1
], sizeof(data
[0]) );
329 memcpy( expanded_data
[(i
-2)*3+2], data
[v2
], sizeof(data
[0]) );
333 static float myrand( float max
)
335 return max
*rand()/(RAND_MAX
+1.0);
339 static void make_tri_indices( void )
341 unsigned int *v
= tri_indices
;
342 unsigned int parity
= 0;
345 for (j
=2;j
<numverts
;j
++,parity
^=1) {
357 num_tri_verts
= v
- tri_indices
;
358 printf("num_tri_verts: %d\n", num_tri_verts
);
360 for (i
= j
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
362 col
[j
][2] = myrand(1);
363 col
[j
][1] = myrand(1);
364 col
[j
][0] = myrand(1);
367 for (i
= 0; i
< numverts
; i
++)
368 strip_indices
[i
] = i
;
371 #define MIN(x,y) (x < y) ? x : y
373 static void draw_surface( unsigned int with_state
)
377 if (with_state
& DISPLAYLIST
) {
378 if ((with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
|MATERIAL_MASK
)) !=
382 fprintf(stderr
, "rebuilding displaylist\n");
385 glDeleteLists( surf1
, 1 );
387 dlist_state
= with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
|
389 surf1
= glGenLists(1);
390 glNewList(surf1
, GL_COMPILE
);
391 draw_surface( dlist_state
);
399 switch (with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
)) {
400 #ifdef GL_EXT_vertex_array
402 case (DRAW_ELTS
|TRIANGLES
):
403 if (with_state
& MATERIALS
) {
404 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
405 GLuint nr
= MIN(num_tri_verts
-i
, 600);
406 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
407 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
408 glDrawElements( GL_TRIANGLES
, nr
, GL_UNSIGNED_INT
, tri_indices
+i
);
411 glDrawElements( GL_TRIANGLES
, num_tri_verts
, GL_UNSIGNED_INT
,
416 case (DRAW_ARRAYS
|TRIANGLES
):
417 glDrawArraysEXT( GL_TRIANGLES
, 0, (numverts
-2)*3 );
420 case (ARRAY_ELT
|TRIANGLES
):
421 if (with_state
& MATERIALS
) {
422 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
423 GLuint nr
= MIN(num_tri_verts
-i
, 600);
425 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
426 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
427 glBegin( GL_TRIANGLES
);
428 for (k
= 0 ; k
< nr
; k
++)
429 glArrayElement( tri_indices
[i
+k
] );
433 glBegin( GL_TRIANGLES
);
434 for (i
= 0 ; i
< num_tri_verts
; i
++)
435 glArrayElement( tri_indices
[i
] );
442 /* Uses the original arrays (including duplicate elements):
444 case (DRAW_ARRAYS
|STRIPS
):
445 glDrawArraysEXT( GL_TRIANGLE_STRIP
, 0, numverts
);
447 case (DRAW_ELTS
|STRIPS
):
448 glDrawElements( GL_TRIANGLE_STRIP
, numverts
,
449 GL_UNSIGNED_INT
, strip_indices
);
452 /* Uses the original arrays (including duplicate elements):
454 case (ARRAY_ELT
|STRIPS
):
455 glBegin( GL_TRIANGLE_STRIP
);
456 for (i
= 0 ; i
< numverts
; i
++)
461 case (DRAW_ARRAYS
|POINTS
):
462 glDrawArraysEXT( GL_POINTS
, 0, numuniq
);
464 case (DRAW_ELTS
|POINTS
):
465 /* can use numuniq with strip_indices as strip_indices[i] == i.
467 glDrawElements( GL_POINTS
, numuniq
,
468 GL_UNSIGNED_INT
, strip_indices
);
470 case (ARRAY_ELT
|POINTS
):
471 /* just emit each unique element once:
473 glBegin( GL_POINTS
);
474 for (i
= 0 ; i
< numuniq
; i
++)
480 case (GLVERTEX
|TRIANGLES
):
481 if (with_state
& MATERIALS
) {
482 for (j
= i
= 0 ; i
< num_tri_verts
; i
+= 600, j
++) {
483 GLuint nr
= MIN(num_tri_verts
-i
, 600);
485 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
486 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
487 glBegin( GL_TRIANGLES
);
488 for (k
= 0 ; k
< nr
; k
++) {
489 glNormal3fv( &compressed_data
[tri_indices
[i
+k
]][3] );
490 glVertex3fv( &compressed_data
[tri_indices
[i
+k
]][0] );
495 glBegin( GL_TRIANGLES
);
496 for (i
= 0 ; i
< num_tri_verts
; i
++) {
497 glNormal3fv( &compressed_data
[tri_indices
[i
]][3] );
498 glVertex3fv( &compressed_data
[tri_indices
[i
]][0] );
504 case (GLVERTEX
|POINTS
):
505 /* Renders all points, but not in strip order... Shouldn't be a
506 * problem, but people may be confused as to why points are so
507 * much faster in this demo... And why cva doesn't help them...
509 glBegin( GL_POINTS
);
510 for ( i
= 0 ; i
< numuniq
; i
++ ) {
511 glNormal3fv( &compressed_data
[i
][3] );
512 glVertex3fv( &compressed_data
[i
][0] );
517 case (GLVERTEX
|STRIPS
):
518 if (with_state
& MATERIALS
) {
519 glBegin( GL_TRIANGLE_STRIP
);
520 for (i
=0;i
<numverts
;i
++) {
521 if (i
% 600 == 0 && i
!= 0) {
522 unsigned j
= i
/ 600;
523 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, col
[j
]);
524 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, col
[j
]);
526 glNormal3fv( &data
[i
][3] );
527 glVertex3fv( &data
[i
][0] );
532 glBegin( GL_TRIANGLE_STRIP
);
533 for (i
=0;i
<numverts
;i
++) {
534 glNormal3fv( &data
[i
][3] );
535 glVertex3fv( &data
[i
][0] );
542 fprintf(stderr
, "unimplemented mode %x...\n",
543 (with_state
& (RENDER_STYLE_MASK
|PRIMITIVE_MASK
)));
550 static void Display(void)
552 glClear( GL_COLOR_BUFFER_BIT
| GL_DEPTH_BUFFER_BIT
);
553 draw_surface( state
);
555 if (doubleBuffer
) glutSwapBuffers();
559 /* KW: only do this when necessary, so CVA can re-use results.
561 static void set_matrix( void )
563 glMatrixMode(GL_MODELVIEW
);
565 glTranslatef( 0.0, 0.0, dist
);
566 glRotatef( yrot
, 0.0, 1.0, 0.0 );
567 glRotatef( xrot
, 1.0, 0.0, 0.0 );
570 static void Benchmark( float xdiff
, float ydiff
)
572 int startTime
, endTime
;
574 double seconds
, fps
, triPerSecond
;
576 printf("Benchmarking...\n");
579 startTime
= glutGet(GLUT_ELAPSED_TIME
);
587 endTime
= glutGet(GLUT_ELAPSED_TIME
);
588 } while (endTime
- startTime
< 5000); /* 5 seconds */
591 seconds
= (double) (endTime
- startTime
) / 1000.0;
592 triPerSecond
= (numverts
- 2) * draws
/ seconds
;
593 fps
= draws
/ seconds
;
594 printf("Result: triangles/sec: %g fps: %g\n", triPerSecond
, fps
);
598 static void InitMaterials(void)
600 static float ambient
[] = {0.1, 0.1, 0.1, 1.0};
601 static float diffuse
[] = {0.5, 1.0, 1.0, 1.0};
602 static float position0
[] = {0.0, 0.0, 20.0, 0.0};
603 static float position1
[] = {0.0, 0.0, -20.0, 0.0};
604 static float front_mat_shininess
[] = {60.0};
605 static float front_mat_specular
[] = {0.2, 0.2, 0.2, 1.0};
606 static float front_mat_diffuse
[] = {0.5, 0.28, 0.38, 1.0};
608 static float back_mat_shininess[] = {60.0};
609 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
610 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
612 static float lmodel_ambient
[] = {1.0, 1.0, 1.0, 1.0};
613 static float lmodel_twoside
[] = {GL_FALSE
};
615 glLightfv(GL_LIGHT0
, GL_AMBIENT
, ambient
);
616 glLightfv(GL_LIGHT0
, GL_DIFFUSE
, diffuse
);
617 glLightfv(GL_LIGHT0
, GL_POSITION
, position0
);
620 glLightfv(GL_LIGHT1
, GL_AMBIENT
, ambient
);
621 glLightfv(GL_LIGHT1
, GL_DIFFUSE
, diffuse
);
622 glLightfv(GL_LIGHT1
, GL_POSITION
, position1
);
625 glLightModelfv(GL_LIGHT_MODEL_AMBIENT
, lmodel_ambient
);
626 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE
, lmodel_twoside
);
628 glMaterialfv(GL_FRONT_AND_BACK
, GL_SHININESS
, front_mat_shininess
);
629 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, front_mat_specular
);
630 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, front_mat_diffuse
);
632 glPolygonStipple (halftone
);
637 #define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
638 #define CHANGED(o,n,mask) ((n&mask) && (n&mask) != (o&mask) )
640 static void ModeMenu(int m
)
650 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION
));
651 printf("GL_EXTENSIONS: %s\n", (char *) glGetString(GL_EXTENSIONS
));
652 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER
));
656 if (CHANGED(state
, m
, FILTER_MASK
)) {
657 UPDATE(state
, m
, FILTER_MASK
);
658 if (m
& LINEAR_FILTER
) {
659 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_LINEAR
);
660 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_LINEAR
);
662 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
663 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
667 if (CHANGED(state
, m
, LIGHT_MASK
)) {
668 UPDATE(state
, m
, LIGHT_MASK
);
670 glEnable(GL_LIGHTING
);
671 glDisable(GL_TEXTURE_GEN_S
);
672 glDisable(GL_TEXTURE_GEN_T
);
673 glDisable(GL_TEXTURE_2D
);
675 else if (m
& UNLIT
) {
676 glDisable(GL_LIGHTING
);
677 glDisable(GL_TEXTURE_GEN_S
);
678 glDisable(GL_TEXTURE_GEN_T
);
679 glDisable(GL_TEXTURE_2D
);
681 else if (m
& REFLECT
) {
682 glDisable(GL_LIGHTING
);
683 glEnable(GL_TEXTURE_GEN_S
);
684 glEnable(GL_TEXTURE_GEN_T
);
685 glEnable(GL_TEXTURE_2D
);
689 if (CHANGED(state
, m
, SHADE_MASK
)) {
690 UPDATE(state
, m
, SHADE_MASK
);
691 if (m
& SHADE_SMOOTH
)
692 glShadeModel(GL_SMOOTH
);
694 glShadeModel(GL_FLAT
);
698 if (CHANGED(state
, m
, CLIP_MASK
)) {
699 UPDATE(state
, m
, CLIP_MASK
);
701 glEnable(GL_CLIP_PLANE0
);
703 glDisable(GL_CLIP_PLANE0
);
707 if (CHANGED(state
, m
, FOG_MASK
)) {
708 UPDATE(state
, m
, FOG_MASK
);
717 if (CHANGED(state
, m
, STIPPLE_MASK
)) {
718 UPDATE(state
, m
, STIPPLE_MASK
);
720 glEnable(GL_POLYGON_STIPPLE
);
723 glDisable(GL_POLYGON_STIPPLE
);
727 if (CHANGED(state
, m
, POLYGON_MASK
)) {
728 UPDATE(state
, m
, POLYGON_MASK
);
729 if (m
& POLYGON_FILL
) {
730 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
732 else if (m
& POLYGON_LINE
) {
733 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
736 glPolygonMode(GL_FRONT_AND_BACK
, GL_POINT
);
740 #ifdef GL_EXT_vertex_array
741 if (CHANGED(state
, m
, (LOCK_MASK
|RENDER_STYLE_MASK
|PRIMITIVE_MASK
)))
743 if (m
& (PRIMITIVE_MASK
)) {
744 UPDATE(state
, m
, (PRIMITIVE_MASK
));
747 if (m
& (RENDER_STYLE_MASK
)) {
748 UPDATE(state
, m
, (RENDER_STYLE_MASK
));
752 UPDATE(state
, m
, (LOCK_MASK
));
756 print_flags("primitive", state
& PRIMITIVE_MASK
);
757 print_flags("render style", state
& RENDER_STYLE_MASK
);
759 if ((state
& PRIMITIVE_MASK
) != STRIPS
&&
760 ((state
& RENDER_STYLE_MASK
) == DRAW_ELTS
||
761 (state
& RENDER_STYLE_MASK
) == ARRAY_ELT
||
762 (state
& PRIMITIVE_MASK
) == POINTS
))
764 fprintf(stderr
, "enabling small arrays\n");
765 /* Rendering any primitive with draw-element/array-element
766 * --> Can't do strips here as ordering has been lost in
767 * compaction process...
769 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), numuniq
,
771 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), numuniq
,
772 &compressed_data
[0][3]);
773 #ifdef GL_EXT_compiled_vertex_array
774 if (allowed
& LOCKED
) {
775 if (state
& LOCKED
) {
776 glLockArraysEXT( 0, numuniq
);
783 else if ((state
& PRIMITIVE_MASK
) == TRIANGLES
&&
784 (state
& RENDER_STYLE_MASK
) == DRAW_ARRAYS
) {
785 fprintf(stderr
, "enabling big arrays\n");
786 /* Only get here for TRIANGLES and drawarrays
788 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), (numverts
-2) * 3,
790 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), (numverts
-2) * 3,
791 &expanded_data
[0][3]);
793 #ifdef GL_EXT_compiled_vertex_array
794 if (allowed
& LOCKED
) {
795 if (state
& LOCKED
) {
796 glLockArraysEXT( 0, (numverts
-2)*3 );
804 fprintf(stderr
, "enabling normal arrays\n");
805 glVertexPointerEXT( 3, GL_FLOAT
, sizeof(data
[0]), numverts
, data
);
806 glNormalPointerEXT( GL_FLOAT
, sizeof(data
[0]), numverts
, &data
[0][3]);
807 #ifdef GL_EXT_compiled_vertex_array
808 if (allowed
& LOCKED
) {
809 if (state
& LOCKED
) {
810 glLockArraysEXT( 0, numverts
);
822 if (m
& DLIST_MASK
) {
823 UPDATE(state
, m
, DLIST_MASK
);
826 if (m
& MATERIAL_MASK
) {
827 UPDATE(state
, m
, MATERIAL_MASK
);
830 print_flags("new flags", state
);
837 static void Init(int argc
, char *argv
[])
839 GLfloat fogColor
[4] = {0.5,1.0,0.5,1.0};
849 glClearColor(0.0, 0.0, 1.0, 0.0);
850 glEnable( GL_DEPTH_TEST
);
851 glEnableClientState( GL_VERTEX_ARRAY
);
852 glEnableClientState( GL_NORMAL_ARRAY
);
854 glMatrixMode(GL_PROJECTION
);
856 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
858 glMatrixMode(GL_MODELVIEW
);
860 glClipPlane(GL_CLIP_PLANE0
, plane
);
866 glTexEnvi(GL_TEXTURE_ENV
, GL_TEXTURE_ENV_MODE
, GL_REPLACE
);
867 glHint(GL_PERSPECTIVE_CORRECTION_HINT
, GL_FASTEST
);
869 glTexGeni(GL_S
, GL_TEXTURE_GEN_MODE
, GL_SPHERE_MAP
);
870 glTexGeni(GL_T
, GL_TEXTURE_GEN_MODE
, GL_SPHERE_MAP
);
873 /* Green fog is easy to see */
874 glFogi(GL_FOG_MODE
,GL_EXP2
);
875 glFogfv(GL_FOG_COLOR
,fogColor
);
876 glFogf(GL_FOG_DENSITY
,0.15);
877 glHint(GL_FOG_HINT
,GL_DONT_CARE
);
880 static int firsttime
= 1;
887 if (!LoadRGBMipmaps(TEXTURE_FILE
, GL_RGB
)) {
888 printf("Error: couldn't load texture image\n");
894 ModeMenu(SHADE_SMOOTH
|
907 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
908 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION
));
909 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR
));
910 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS
));
916 static void Reshape(int width
, int height
)
918 glViewport(0, 0, (GLint
)width
, (GLint
)height
);
923 static void Key( unsigned char key
, int x
, int y
)
931 ModeMenu((state
^ FOG_MASK
) & FOG_MASK
);
934 ModeMenu((state
^ SHADE_MASK
) & SHADE_MASK
);
937 ModeMenu((state
^ STIPPLE_MASK
) & STIPPLE_MASK
);
940 ModeMenu((state
^ LIGHT_MASK
) & (LIT
|UNLIT
));
943 ModeMenu((state
^ MATERIAL_MASK
) & MATERIAL_MASK
);
946 ModeMenu((state
^ CLIP_MASK
) & CLIP_MASK
);
949 ModeMenu((LOCKED
|IMMEDIATE
|DRAW_ELTS
|TRIANGLES
) & allowed
);
952 ModeMenu(UNLOCKED
|IMMEDIATE
|GLVERTEX
|STRIPS
);
973 glMatrixMode(GL_MODELVIEW
);
975 glClipPlane(GL_CLIP_PLANE0
, plane
);
982 glMatrixMode(GL_MODELVIEW
);
984 glClipPlane(GL_CLIP_PLANE0
, plane
);
995 static void SpecialKey( int key
, int x
, int y
)
1003 case GLUT_KEY_RIGHT
:
1016 glutPostRedisplay();
1021 static GLint
Args(int argc
, char **argv
)
1026 for (i
= 1; i
< argc
; i
++) {
1027 if (strcmp(argv
[i
], "-sb") == 0) {
1028 doubleBuffer
= GL_FALSE
;
1030 else if (strcmp(argv
[i
], "-db") == 0) {
1031 doubleBuffer
= GL_TRUE
;
1033 else if (strcmp(argv
[i
], "-info") == 0) {
1034 PrintInfo
= GL_TRUE
;
1036 else if (strcmp(argv
[i
], "-10") == 0) {
1039 else if (strcmp(argv
[i
], "-100") == 0) {
1042 else if (strcmp(argv
[i
], "-1000") == 0) {
1046 printf("%s (Bad option).\n", argv
[i
]);
1054 int main(int argc
, char **argv
)
1058 GLuint arg_mode
= Args(argc
, argv
);
1060 if (arg_mode
& QUIT
)
1063 read_surface( "isosurf.dat" );
1065 glutInitWindowSize(400, 400);
1066 glutInit( &argc
, argv
);
1070 type
|= (doubleBuffer
) ? GLUT_DOUBLE
: GLUT_SINGLE
;
1071 glutInitDisplayMode(type
);
1073 if (glutCreateWindow("Isosurface") <= 0) {
1079 /* Make sure server supports the vertex array extension */
1080 if (!GLEW_EXT_vertex_array
)
1082 printf("Vertex arrays not supported by this renderer\n");
1083 allowed
&= ~(LOCKED
|DRAW_ARRAYS
|DRAW_ELTS
|ARRAY_ELT
);
1085 else if (!GLEW_EXT_compiled_vertex_array
)
1087 printf("Compiled vertex arrays not supported by this renderer\n");
1094 glutCreateMenu(ModeMenu
);
1095 glutAddMenuEntry("GL info", GLINFO
);
1096 glutAddMenuEntry("", 0);
1097 glutAddMenuEntry("Lit", LIT
);
1098 glutAddMenuEntry("Unlit", UNLIT
);
1099 glutAddMenuEntry("Reflect", REFLECT
);
1100 glutAddMenuEntry("", 0);
1101 glutAddMenuEntry("Smooth", SHADE_SMOOTH
);
1102 glutAddMenuEntry("Flat", SHADE_FLAT
);
1103 glutAddMenuEntry("", 0);
1104 glutAddMenuEntry("Fog", FOG
);
1105 glutAddMenuEntry("No Fog", NO_FOG
);
1106 glutAddMenuEntry("", 0);
1107 glutAddMenuEntry("Stipple", STIPPLE
);
1108 glutAddMenuEntry("No Stipple", NO_STIPPLE
);
1109 glutAddMenuEntry("", 0);
1110 glutAddMenuEntry("Polygon Mode Fill", POLYGON_FILL
);
1111 glutAddMenuEntry("Polygon Mode Line", POLYGON_LINE
);
1112 glutAddMenuEntry("Polygon Mode Points", POLYGON_POINT
);
1113 glutAddMenuEntry("", 0);
1114 glutAddMenuEntry("Point Filtered", POINT_FILTER
);
1115 glutAddMenuEntry("Linear Filtered", LINEAR_FILTER
);
1116 glutAddMenuEntry("", 0);
1117 glutAddMenuEntry("GL_TRIANGLES", TRIANGLES
);
1118 glutAddMenuEntry("GL_TRIANGLE_STRIPS", STRIPS
);
1119 glutAddMenuEntry("GL_POINTS", POINTS
);
1120 glutAddMenuEntry("", 0);
1121 glutAddMenuEntry("Displaylist", DISPLAYLIST
);
1122 glutAddMenuEntry("Immediate", IMMEDIATE
);
1123 glutAddMenuEntry("", 0);
1124 if (allowed
& LOCKED
) {
1125 glutAddMenuEntry("Locked Arrays (CVA)", LOCKED
);
1126 glutAddMenuEntry("Unlocked Arrays", UNLOCKED
);
1127 glutAddMenuEntry("", 0);
1129 glutAddMenuEntry("glVertex", GLVERTEX
);
1130 if (allowed
& DRAW_ARRAYS
) {
1131 glutAddMenuEntry("glDrawElements", DRAW_ELTS
);
1132 glutAddMenuEntry("glDrawArrays", DRAW_ARRAYS
);
1133 glutAddMenuEntry("glArrayElement", ARRAY_ELT
);
1135 glutAddMenuEntry("", 0);
1136 glutAddMenuEntry("Quit", QUIT
);
1137 glutAttachMenu(GLUT_RIGHT_BUTTON
);
1139 glutReshapeFunc(Reshape
);
1140 glutKeyboardFunc(Key
);
1141 glutSpecialFunc(SpecialKey
);
1142 glutDisplayFunc(Display
);