blob: 29550c465d292e7f434e502a5c480af0f322dc88 [file] [log] [blame]
Brian Paul36ca6bd1999-09-08 22:14:31 +00001/* $Id: isosurf.c,v 1.3 1999/09/08 22:14:31 brianp Exp $ */
jtgafb833d1999-08-19 00:55:39 +00002
3/*
Keith Whitwell44c73931999-09-03 14:56:40 +00004 * Display an isosurface of 3-D wind speed volume.
5 *
jtgafb833d1999-08-19 00:55:39 +00006 * Brian Paul This file in public domain.
7 */
8
Keith Whitwell44c73931999-09-03 14:56:40 +00009
10/* Keys:
11 * =====
12 *
13 * - Arrow keys to rotate
14 * - 's' toggles smooth shading
15 * - 'l' toggles lighting
16 * - 'f' toggles fog
17 * - 'I' and 'i' zoom in and out
18 * - 'c' toggles a user clip plane
19 * - 'm' toggles colorful materials in GL_TRIANGLES modes.
20 * - '+' and '-' move the user clip plane
21 *
22 * Other options are available via the popup menu.
23 */
24
jtgafb833d1999-08-19 00:55:39 +000025/*
26 * $Log: isosurf.c,v $
Brian Paul36ca6bd1999-09-08 22:14:31 +000027 * Revision 1.3 1999/09/08 22:14:31 brianp
28 * minor changes. always call compactify_arrays()
29 *
Keith Whitwell44c73931999-09-03 14:56:40 +000030 * Revision 1.2 1999/09/03 14:56:40 keithw
31 * Fog, displaylist and zoom operations
jtgafb833d1999-08-19 00:55:39 +000032 *
33 * Revision 3.4 1999/04/24 01:10:47 keithw
34 * clip planes, materials
35 *
36 * Revision 3.3 1999/03/31 19:42:14 keithw
37 * support for cva
38 *
39 * Revision 3.1 1998/11/01 20:30:20 brianp
40 * added benchmark feature (b key)
41 *
42 * Revision 3.0 1998/02/14 18:42:29 brianp
43 * initial rev
44 *
45 */
46
47
48
49#include <stdio.h>
50#include <string.h>
51#include <stdlib.h>
52#include <math.h>
53#include "GL/glut.h"
54
55#include "../util/readtex.c" /* I know, this is a hack. KW: me too. */
56#define TEXTURE_FILE "../images/reflect.rgb"
57
58#define LIT 0x1
59#define UNLIT 0x2
60#define TEXTURE 0x4
61#define NO_TEXTURE 0x8
62#define REFLECT 0x10
63#define NO_REFLECT 0x20
64#define POINT_FILTER 0x40
65#define LINEAR_FILTER 0x80
Keith Whitwell44c73931999-09-03 14:56:40 +000066#define GLVERTEX 0x100
jtgafb833d1999-08-19 00:55:39 +000067#define DRAW_ARRAYS 0x200 /* or draw_elts, if compiled */
68#define ARRAY_ELT 0x400
69#define COMPILED 0x800
Keith Whitwell44c73931999-09-03 14:56:40 +000070#define IMMEDIATE 0x1000
jtgafb833d1999-08-19 00:55:39 +000071#define SHADE_SMOOTH 0x2000
72#define SHADE_FLAT 0x4000
73#define TRIANGLES 0x8000
74#define STRIPS 0x10000
75#define USER_CLIP 0x20000
76#define NO_USER_CLIP 0x40000
77#define MATERIALS 0x80000
78#define NO_MATERIALS 0x100000
Keith Whitwell44c73931999-09-03 14:56:40 +000079#define FOG 0x200000
80#define NO_FOG 0x400000
jtgafb833d1999-08-19 00:55:39 +000081#define QUIT 0x800000
Keith Whitwell44c73931999-09-03 14:56:40 +000082#define DISPLAYLIST 0x1000000
jtgafb833d1999-08-19 00:55:39 +000083
84#define LIGHT_MASK (LIT|UNLIT)
85#define TEXTURE_MASK (TEXTURE|NO_TEXTURE)
86#define REFLECT_MASK (REFLECT|NO_REFLECT)
87#define FILTER_MASK (POINT_FILTER|LINEAR_FILTER)
Keith Whitwell44c73931999-09-03 14:56:40 +000088#define RENDER_STYLE_MASK (GLVERTEX|DRAW_ARRAYS|ARRAY_ELT)
89#define COMPILED_MASK (COMPILED|IMMEDIATE|DISPLAYLIST)
jtgafb833d1999-08-19 00:55:39 +000090#define MATERIAL_MASK (MATERIALS|NO_MATERIALS)
91#define PRIMITIVE_MASK (TRIANGLES|STRIPS)
92#define CLIP_MASK (USER_CLIP|NO_USER_CLIP)
93#define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT)
Keith Whitwell44c73931999-09-03 14:56:40 +000094#define FOG_MASK (FOG|NO_FOG)
jtgafb833d1999-08-19 00:55:39 +000095
96#define MAXVERTS 10000
97static float data[MAXVERTS][6];
98static float compressed_data[MAXVERTS][6];
99static GLuint indices[MAXVERTS];
100static GLuint tri_indices[MAXVERTS*3];
101static GLfloat col[100][4];
102static GLint numverts, num_tri_verts, numuniq;
103
104static GLfloat xrot;
105static GLfloat yrot;
Keith Whitwell44c73931999-09-03 14:56:40 +0000106static GLfloat dist = -6;
jtgafb833d1999-08-19 00:55:39 +0000107static GLint state, allowed = ~0;
108static GLboolean doubleBuffer = GL_TRUE;
109static GLdouble plane[4] = {1.0, 0.0, -1.0, 0.0};
Keith Whitwell44c73931999-09-03 14:56:40 +0000110static GLuint surf1;
jtgafb833d1999-08-19 00:55:39 +0000111
Brian Paul36ca6bd1999-09-08 22:14:31 +0000112/* forward decl */
113int BuildList( int mode );
114
115
jtgafb833d1999-08-19 00:55:39 +0000116static void read_surface( char *filename )
117{
118 FILE *f;
119
120 f = fopen(filename,"r");
121 if (!f) {
122 printf("couldn't read %s\n", filename);
123 exit(1);
124 }
125
126 numverts = 0;
127 while (!feof(f) && numverts<MAXVERTS) {
128 fscanf( f, "%f %f %f %f %f %f",
129 &data[numverts][0], &data[numverts][1], &data[numverts][2],
130 &data[numverts][3], &data[numverts][4], &data[numverts][5] );
131 numverts++;
132 }
133 numverts--;
134
135 printf("%d vertices, %d triangles\n", numverts, numverts-2);
136 fclose(f);
137}
138
139
140
141
142struct data_idx {
143 float *data;
144 int idx;
145 int uniq_idx;
146};
147
148
149#define COMPARE_FUNC( AXIS ) \
150int compare_axis_##AXIS( const void *a, const void *b ) \
151{ \
152 float t = ( (*(struct data_idx *)a).data[AXIS] - \
153 (*(struct data_idx *)b).data[AXIS] ); \
154 \
155 if (t < 0) return -1; \
156 if (t > 0) return 1; \
157 return 0; \
158}
159
160COMPARE_FUNC(0)
161COMPARE_FUNC(1)
162COMPARE_FUNC(2)
163COMPARE_FUNC(3)
164COMPARE_FUNC(4)
165COMPARE_FUNC(5)
166COMPARE_FUNC(6)
167
168int (*(compare[7]))( const void *a, const void *b ) =
169{
170 compare_axis_0,
171 compare_axis_1,
172 compare_axis_2,
173 compare_axis_3,
174 compare_axis_4,
175 compare_axis_5,
176 compare_axis_6,
177};
178
179
180#define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i)
181
182static int sort_axis( int axis,
183 int vec_size,
184 int vec_stride,
185 struct data_idx *indices,
186 int start,
187 int finish,
188 float *out,
189 int uniq,
190 const float fudge )
191{
192 int i;
193
194 if (finish-start > 2)
195 {
196 qsort( indices+start, finish-start, sizeof(*indices), compare[axis] );
197 }
198 else if (indices[start].data[axis] > indices[start+1].data[axis])
199 {
200 struct data_idx tmp = indices[start];
201 indices[start] = indices[start+1];
202 indices[start+1] = tmp;
203 }
204
205 if (axis == vec_size-1) {
206 for (i = start ; i < finish ; ) {
207 float max = indices[i].data[axis] + fudge;
208 float *dest = VEC_ELT(out, vec_stride, uniq);
209 int j;
210
211 for (j = 0 ; j < vec_size ; j++)
212 dest[j] = indices[i].data[j];
213
214 for ( ; i < finish && max >= indices[i].data[axis]; i++)
215 indices[i].uniq_idx = uniq;
216
217 uniq++;
218 }
219 } else {
220 for (i = start ; i < finish ; ) {
221 int j = i + 1;
222 float max = indices[i].data[axis] + fudge;
223 while (j < finish && max >= indices[j].data[axis]) j++;
224 if (j == i+1) {
225 float *dest = VEC_ELT(out, vec_stride, uniq);
226 int k;
227
228 indices[i].uniq_idx = uniq;
229
230 for (k = 0 ; k < vec_size ; k++)
231 dest[k] = indices[i].data[k];
232
233 uniq++;
234 } else {
235 uniq = sort_axis( axis+1, vec_size, vec_stride,
236 indices, i, j, out, uniq, fudge );
237 }
238 i = j;
239 }
240 }
241
242 return uniq;
243}
244
245
246static void extract_indices1( const struct data_idx *in, unsigned int *out,
247 int n )
248{
249 int i;
250 for ( i = 0 ; i < n ; i++ ) {
251 out[in[i].idx] = in[i].uniq_idx;
252 }
253}
254
255
Brian Paul36ca6bd1999-09-08 22:14:31 +0000256static void compactify_arrays(void)
jtgafb833d1999-08-19 00:55:39 +0000257{
258 int i;
259 struct data_idx *ind;
260
261 ind = (struct data_idx *) malloc( sizeof(struct data_idx) * numverts );
262
263 for (i = 0 ; i < numverts ; i++) {
264 ind[i].idx = i;
265 ind[i].data = data[i];
266 }
267
268 numuniq = sort_axis(0,
269 sizeof(compressed_data[0])/sizeof(float),
270 sizeof(compressed_data[0]),
271 ind,
272 0,
273 numverts,
274 (float *)compressed_data,
275 0,
276 1e-6);
277
278 printf("Nr unique vertex/normal pairs: %d\n", numuniq);
279
280 extract_indices1( ind, indices, numverts );
281 free( ind );
282}
283
284static float myrand( float max )
285{
286 return max*rand()/(RAND_MAX+1.0);
287}
288
289
290static void make_tri_indices( void )
291{
292 unsigned int *v = tri_indices;
293 unsigned int parity = 0;
294 unsigned int i, j;
295
296 for (j=2;j<numverts;j++,parity^=1) {
297 if (parity) {
298 *v++ = indices[j-1];
299 *v++ = indices[j-2];
300 *v++ = indices[j];
301 } else {
302 *v++ = indices[j-2];
303 *v++ = indices[j-1];
304 *v++ = indices[j];
305 }
306 }
307
308 num_tri_verts = v - tri_indices;
309 printf("num_tri_verts: %d\n", num_tri_verts);
310
311 for (i = j = 0 ; i < num_tri_verts ; i += 600, j++) {
312 col[j][3] = 1;
313 col[j][2] = myrand(1);
314 col[j][1] = myrand(1);
315 col[j][0] = myrand(1);
316 }
317}
318
319#define MIN(x,y) (x < y) ? x : y
320
Keith Whitwell44c73931999-09-03 14:56:40 +0000321static void draw_surface( int with_state )
jtgafb833d1999-08-19 00:55:39 +0000322{
323 GLuint i, j;
324
Keith Whitwell44c73931999-09-03 14:56:40 +0000325 switch (with_state & (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
jtgafb833d1999-08-19 00:55:39 +0000326#ifdef GL_EXT_vertex_array
327
328 case (COMPILED|DRAW_ARRAYS|STRIPS):
329 glDrawElements( GL_TRIANGLE_STRIP, numverts, GL_UNSIGNED_INT, indices );
330 break;
331
332
333 case (COMPILED|ARRAY_ELT|STRIPS):
334 glBegin( GL_TRIANGLE_STRIP );
335 for (i = 0 ; i < numverts ; i++)
336 glArrayElement( indices[i] );
337 glEnd();
338 break;
339
340 case (COMPILED|DRAW_ARRAYS|TRIANGLES):
Keith Whitwell44c73931999-09-03 14:56:40 +0000341 case (IMMEDIATE|DRAW_ARRAYS|TRIANGLES):
342 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000343 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
344 GLuint nr = MIN(num_tri_verts-i, 600);
345 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
346 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
347 glDrawElements( GL_TRIANGLES, nr, GL_UNSIGNED_INT, tri_indices+i );
348 }
349 } else {
350 glDrawElements( GL_TRIANGLES, num_tri_verts, GL_UNSIGNED_INT,
351 tri_indices );
352 }
353
354 break;
355
356 /* Uses the original arrays (including duplicate elements):
357 */
Keith Whitwell44c73931999-09-03 14:56:40 +0000358 case (IMMEDIATE|DRAW_ARRAYS|STRIPS):
jtgafb833d1999-08-19 00:55:39 +0000359 glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
360 break;
361
362 /* Uses the original arrays (including duplicate elements):
363 */
Keith Whitwell44c73931999-09-03 14:56:40 +0000364 case (IMMEDIATE|ARRAY_ELT|STRIPS):
jtgafb833d1999-08-19 00:55:39 +0000365 glBegin( GL_TRIANGLE_STRIP );
366 for (i = 0 ; i < numverts ; i++)
367 glArrayElement( i );
368 glEnd();
369 break;
370
Keith Whitwell44c73931999-09-03 14:56:40 +0000371 case (IMMEDIATE|ARRAY_ELT|TRIANGLES):
jtgafb833d1999-08-19 00:55:39 +0000372 case (COMPILED|ARRAY_ELT|TRIANGLES):
Keith Whitwell44c73931999-09-03 14:56:40 +0000373 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000374 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
375 GLuint nr = MIN(num_tri_verts-i, 600);
376 GLuint k;
377 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
378 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
379 glBegin( GL_TRIANGLES );
380 for (k = 0 ; k < nr ; k++)
381 glArrayElement( tri_indices[i+k] );
382 glEnd();
383 }
384 } else {
385 glBegin( GL_TRIANGLES );
386 for (i = 0 ; i < num_tri_verts ; i++)
387 glArrayElement( tri_indices[i] );
Keith Whitwell44c73931999-09-03 14:56:40 +0000388
jtgafb833d1999-08-19 00:55:39 +0000389 glEnd();
390 }
391 break;
392
Keith Whitwell44c73931999-09-03 14:56:40 +0000393 case (IMMEDIATE|GLVERTEX|TRIANGLES):
394 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000395 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
396 GLuint nr = MIN(num_tri_verts-i, 600);
397 GLuint k;
398 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
399 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
400 glBegin( GL_TRIANGLES );
401 for (k = 0 ; k < nr ; k++) {
402 glNormal3fv( &compressed_data[tri_indices[i+k]][3] );
403 glVertex3fv( &compressed_data[tri_indices[i+k]][0] );
404 }
405 glEnd();
406 }
407 } else {
408 glBegin( GL_TRIANGLES );
409 for (i = 0 ; i < num_tri_verts ; i++) {
410 glNormal3fv( &compressed_data[tri_indices[i]][3] );
411 glVertex3fv( &compressed_data[tri_indices[i]][0] );
412 }
413 glEnd();
414 }
415 break;
416
Keith Whitwell44c73931999-09-03 14:56:40 +0000417 case (DISPLAYLIST|GLVERTEX|STRIPS):
418 if (!surf1)
419 surf1 = BuildList( GL_COMPILE_AND_EXECUTE );
420 else
421 glCallList(surf1);
422 break;
423
jtgafb833d1999-08-19 00:55:39 +0000424#endif
425
426 /* Uses the original arrays (including duplicate elements):
427 */
428 default:
429 glBegin( GL_TRIANGLE_STRIP );
430 for (i=0;i<numverts;i++) {
431 glNormal3fv( &data[i][3] );
432 glVertex3fv( &data[i][0] );
433 }
434 glEnd();
435 }
436}
437
438
439
440static void Display(void)
441{
442 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Keith Whitwell44c73931999-09-03 14:56:40 +0000443 draw_surface( state );
jtgafb833d1999-08-19 00:55:39 +0000444 glFlush();
445 if (doubleBuffer) glutSwapBuffers();
446}
447
Keith Whitwell44c73931999-09-03 14:56:40 +0000448int BuildList( int mode )
449{
450 int rv = glGenLists(1);
451 glNewList(rv, mode );
452 draw_surface( IMMEDIATE|GLVERTEX|STRIPS );
453 glEndList();
454 return rv;
455}
456
jtgafb833d1999-08-19 00:55:39 +0000457/* KW: only do this when necessary, so CVA can re-use results.
458 */
459static void set_matrix( void )
460{
461 glMatrixMode(GL_MODELVIEW);
462 glLoadIdentity();
Keith Whitwell44c73931999-09-03 14:56:40 +0000463 glTranslatef( 0.0, 0.0, dist );
jtgafb833d1999-08-19 00:55:39 +0000464 glRotatef( yrot, 0.0, 1.0, 0.0 );
465 glRotatef( xrot, 1.0, 0.0, 0.0 );
466}
467
468static void Benchmark( float xdiff, float ydiff )
469{
470 int startTime, endTime;
471 int draws;
472 double seconds, fps, triPerSecond;
473
474 printf("Benchmarking...\n");
475
476 draws = 0;
477 startTime = glutGet(GLUT_ELAPSED_TIME);
478 xrot = 0.0;
479 do {
480 xrot += xdiff;
481 yrot += ydiff;
482 set_matrix();
483 Display();
484 draws++;
485 endTime = glutGet(GLUT_ELAPSED_TIME);
486 } while (endTime - startTime < 5000); /* 5 seconds */
487
488 /* Results */
489 seconds = (double) (endTime - startTime) / 1000.0;
490 triPerSecond = (numverts - 2) * draws / seconds;
491 fps = draws / seconds;
492 printf("Result: triangles/sec: %g fps: %g\n", triPerSecond, fps);
493}
494
495
496static void InitMaterials(void)
497{
498 static float ambient[] = {0.1, 0.1, 0.1, 1.0};
499 static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
500 static float position0[] = {0.0, 0.0, 20.0, 0.0};
501 static float position1[] = {0.0, 0.0, -20.0, 0.0};
502 static float front_mat_shininess[] = {60.0};
503 static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
504 static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
505 /*
506 static float back_mat_shininess[] = {60.0};
507 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
508 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
509 */
510 static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
511 static float lmodel_twoside[] = {GL_FALSE};
512
513 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
514 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
515 glLightfv(GL_LIGHT0, GL_POSITION, position0);
516 glEnable(GL_LIGHT0);
517
518 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
519 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
520 glLightfv(GL_LIGHT1, GL_POSITION, position1);
521 glEnable(GL_LIGHT1);
522
523 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
524 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
525
526 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
527 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
528 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
529}
530
531
532
533#define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
534#define CHANGED(o,n,mask) ((n&mask) && \
535 (n&mask) != (o&mask) ? UPDATE(o,n,mask) : 0)
536
537static void ModeMenu(int m)
538{
539 m &= allowed;
540
541 if (!m) return;
542
543 if (m==QUIT)
544 exit(0);
545
546 if (CHANGED(state, m, FILTER_MASK)) {
547 if (m & LINEAR_FILTER) {
548 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
549 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
550 } else {
551 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
552 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
553 }
554 }
555
556 if (CHANGED(state, m, LIGHT_MASK)) {
557 if (m & LIT)
558 glEnable(GL_LIGHTING);
559 else
560 glDisable(GL_LIGHTING);
561 }
562
563 if (CHANGED(state, m, SHADE_MASK)) {
564 if (m & SHADE_SMOOTH)
565 glShadeModel(GL_SMOOTH);
566 else
567 glShadeModel(GL_FLAT);
568 }
569
570
571 if (CHANGED(state, m, TEXTURE_MASK)) {
572 if (m & TEXTURE)
573 glEnable(GL_TEXTURE_2D);
574 else
575 glDisable(GL_TEXTURE_2D);
576 }
577
578 if (CHANGED(state, m, REFLECT_MASK)) {
579 if (m & REFLECT) {
580 glEnable(GL_TEXTURE_GEN_S);
581 glEnable(GL_TEXTURE_GEN_T);
582 } else {
583 glDisable(GL_TEXTURE_GEN_S);
584 glDisable(GL_TEXTURE_GEN_T);
585 }
586 }
587
588 if (CHANGED(state, m, CLIP_MASK)) {
589 if (m & USER_CLIP) {
590 glEnable(GL_CLIP_PLANE0);
591 } else {
592 glDisable(GL_CLIP_PLANE0);
593 }
594 }
595
Keith Whitwell44c73931999-09-03 14:56:40 +0000596 if (CHANGED(state, m, FOG_MASK)) {
597 if (m & FOG)
598 {
599 glEnable(GL_FOG);
600 printf("FOG enable\n");
601 }
602 else
603 {
604 glDisable(GL_FOG);
605 printf("FOG disable\n");
606 }
607 }
608
jtgafb833d1999-08-19 00:55:39 +0000609#ifdef GL_EXT_vertex_array
610 if (CHANGED(state, m, (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)))
611 {
Keith Whitwell44c73931999-09-03 14:56:40 +0000612 if ((m & (COMPILED_MASK|PRIMITIVE_MASK)) == (IMMEDIATE|STRIPS))
jtgafb833d1999-08-19 00:55:39 +0000613 {
614 glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numverts, data );
615 glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numverts, &data[0][3]);
616 }
617 else
618 {
619 glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numuniq,
620 compressed_data );
621 glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numuniq,
622 &compressed_data[0][3]);
623 }
624#ifdef GL_EXT_compiled_vertex_array
625 if (m & COMPILED) {
626 glLockArraysEXT( 0, numuniq );
627 } else {
628 glUnlockArraysEXT();
629 }
630#endif
631 }
632#endif
633
634 if (m & (RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
635 UPDATE(state, m, (RENDER_STYLE_MASK|PRIMITIVE_MASK));
636 }
637
638 if (m & MATERIAL_MASK) {
639 UPDATE(state, m, MATERIAL_MASK);
640 }
641
642 glutPostRedisplay();
643}
644
645
646
647static void Init(void)
648{
Keith Whitwell44c73931999-09-03 14:56:40 +0000649 GLfloat fogColor[4] = {0.5,1.0,0.5,1.0};
650
jtgafb833d1999-08-19 00:55:39 +0000651 glClearColor(0.0, 0.0, 0.0, 0.0);
652 glEnable( GL_DEPTH_TEST );
653 glEnable( GL_VERTEX_ARRAY_EXT );
654 glEnable( GL_NORMAL_ARRAY_EXT );
655
656 InitMaterials();
657
658 glMatrixMode(GL_PROJECTION);
659 glLoadIdentity();
660 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
661
662 glMatrixMode(GL_MODELVIEW);
663 glLoadIdentity();
664 glClipPlane(GL_CLIP_PLANE0, plane);
665
666 set_matrix();
667
668 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
669 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
670
671 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
672 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
673
674 if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
675 printf("Error: couldn't load texture image\n");
676 exit(1);
677 }
678
Keith Whitwell44c73931999-09-03 14:56:40 +0000679 /* Green fog is easy to see */
680 glFogi(GL_FOG_MODE,GL_EXP2);
681 glFogfv(GL_FOG_COLOR,fogColor);
682 glFogf(GL_FOG_DENSITY,0.15);
683 glHint(GL_FOG_HINT,GL_DONT_CARE);
684
685
Brian Paul36ca6bd1999-09-08 22:14:31 +0000686 compactify_arrays();
687 make_tri_indices();
jtgafb833d1999-08-19 00:55:39 +0000688
Keith Whitwell44c73931999-09-03 14:56:40 +0000689 surf1 = BuildList( GL_COMPILE );
690
jtgafb833d1999-08-19 00:55:39 +0000691 ModeMenu(SHADE_SMOOTH|
692 LIT|
693 NO_TEXTURE|
694 NO_REFLECT|
695 POINT_FILTER|
Keith Whitwell44c73931999-09-03 14:56:40 +0000696 IMMEDIATE|
jtgafb833d1999-08-19 00:55:39 +0000697 NO_USER_CLIP|
698 NO_MATERIALS|
Keith Whitwell44c73931999-09-03 14:56:40 +0000699 NO_FOG|
700 GLVERTEX);
jtgafb833d1999-08-19 00:55:39 +0000701}
702
703
704
705static void Reshape(int width, int height)
706{
707 glViewport(0, 0, (GLint)width, (GLint)height);
708}
709
710
711
712static void Key( unsigned char key, int x, int y )
713{
Brian Paul36ca6bd1999-09-08 22:14:31 +0000714 (void) x;
715 (void) y;
jtgafb833d1999-08-19 00:55:39 +0000716 switch (key) {
Keith Whitwell44c73931999-09-03 14:56:40 +0000717 case 27:
718 exit(0);
719 case 'f':
720 ModeMenu((state ^ FOG_MASK) & FOG_MASK);
721 break;
722 case 's':
723 ModeMenu((state ^ SHADE_MASK) & SHADE_MASK);
724 break;
725 case 'l':
726 ModeMenu((state ^ LIGHT_MASK) & LIGHT_MASK);
727 break;
728 case 'm':
729 ModeMenu((state ^ MATERIAL_MASK) & MATERIAL_MASK);
730 break;
731 case 'c':
732 ModeMenu((state ^ CLIP_MASK) & CLIP_MASK);
733 break;
734 case 'b':
735 Benchmark(5.0, 0);
736 break;
737 case 'B':
738 Benchmark(0, 5.0);
739 break;
740 case 'i':
741 dist += .25;
742 set_matrix();
743 glutPostRedisplay();
744 break;
745 case 'I':
746 dist -= .25;
747 set_matrix();
748 glutPostRedisplay();
749 break;
750 case '-':
751 case '_':
752 plane[3] += 2.0;
753 glMatrixMode(GL_MODELVIEW);
754 glLoadIdentity();
755 glClipPlane(GL_CLIP_PLANE0, plane);
756 set_matrix();
757 glutPostRedisplay();
758 break;
759 case '+':
760 case '=':
761 plane[3] -= 2.0;
762 glMatrixMode(GL_MODELVIEW);
763 glLoadIdentity();
764 glClipPlane(GL_CLIP_PLANE0, plane);
765 set_matrix();
766 glutPostRedisplay();
767 break;
jtgafb833d1999-08-19 00:55:39 +0000768
769 }
770}
771
772
773static void SpecialKey( int key, int x, int y )
774{
Brian Paul36ca6bd1999-09-08 22:14:31 +0000775 (void) x;
776 (void) y;
jtgafb833d1999-08-19 00:55:39 +0000777 switch (key) {
778 case GLUT_KEY_LEFT:
779 yrot -= 15.0;
780 break;
781 case GLUT_KEY_RIGHT:
782 yrot += 15.0;
783 break;
784 case GLUT_KEY_UP:
785 xrot += 15.0;
786 break;
787 case GLUT_KEY_DOWN:
788 xrot -= 15.0;
789 break;
790 default:
791 return;
792 }
793 set_matrix();
794 glutPostRedisplay();
795}
796
797
798
799static GLint Args(int argc, char **argv)
800{
801 GLint i;
802 GLint mode = 0;
803
804 for (i = 1; i < argc; i++) {
805 if (strcmp(argv[i], "-sb") == 0) {
806 doubleBuffer = GL_FALSE;
807 }
808 else if (strcmp(argv[i], "-db") == 0) {
809 doubleBuffer = GL_TRUE;
810 }
811 else {
812 printf("%s (Bad option).\n", argv[i]);
813 return QUIT;
814 }
815 }
816
817 return mode;
818}
819
820int main(int argc, char **argv)
821{
822 GLenum type;
823 char *extensions;
824
825 GLuint arg_mode = Args(argc, argv);
826
827 if (arg_mode & QUIT)
828 exit(0);
829
830 read_surface( "isosurf.dat" );
831
832 glutInitWindowPosition(0, 0);
833 glutInitWindowSize(400, 400);
834
835 type = GLUT_DEPTH;
836 type |= GLUT_RGB;
837 type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
838 glutInitDisplayMode(type);
839
840 if (glutCreateWindow("Isosurface") <= 0) {
841 exit(0);
842 }
843
844 /* Make sure server supports the vertex array extension */
845 extensions = (char *) glGetString( GL_EXTENSIONS );
846
847 if (!strstr( extensions, "GL_EXT_vertex_array" ))
848 {
849 printf("Vertex arrays not supported by this renderer\n");
850 allowed &= ~(COMPILED|DRAW_ARRAYS|ARRAY_ELT);
851 }
852 else if (!strstr( extensions, "GL_EXT_compiled_vertex_array" ))
853 {
854 printf("Compiled vertex arrays not supported by this renderer\n");
855 allowed &= ~COMPILED;
856 }
857
858 Init();
859 ModeMenu(arg_mode);
860
861 glutCreateMenu(ModeMenu);
862 glutAddMenuEntry("Lit", LIT|NO_TEXTURE|NO_REFLECT);
863 glutAddMenuEntry("Unlit", UNLIT|NO_TEXTURE|NO_REFLECT);
864/* glutAddMenuEntry("Textured", TEXTURE); */
865 glutAddMenuEntry("Reflect", TEXTURE|REFLECT);
866 glutAddMenuEntry("", 0);
867 glutAddMenuEntry("Smooth", SHADE_SMOOTH);
868 glutAddMenuEntry("Flat", SHADE_FLAT);
869 glutAddMenuEntry("", 0);
Keith Whitwell44c73931999-09-03 14:56:40 +0000870 glutAddMenuEntry("Fog", FOG);
871 glutAddMenuEntry("No Fog", NO_FOG);
872 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +0000873 glutAddMenuEntry("Point Filtered", POINT_FILTER);
874 glutAddMenuEntry("Linear Filtered", LINEAR_FILTER);
875 glutAddMenuEntry("", 0);
Keith Whitwell44c73931999-09-03 14:56:40 +0000876 glutAddMenuEntry("glVertex (STRIPS)", IMMEDIATE|GLVERTEX|STRIPS);
877 glutAddMenuEntry("glVertex (TRIANGLES)", IMMEDIATE|GLVERTEX|TRIANGLES);
878 glutAddMenuEntry("", 0);
879 glutAddMenuEntry("glVertex display list (STRIPS)",
880 DISPLAYLIST|GLVERTEX|STRIPS);
jtgafb833d1999-08-19 00:55:39 +0000881 glutAddMenuEntry("", 0);
882 if (allowed & DRAW_ARRAYS) {
883 glutAddMenuEntry("DrawArrays (STRIPS)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000884 IMMEDIATE|DRAW_ARRAYS|STRIPS);
jtgafb833d1999-08-19 00:55:39 +0000885 glutAddMenuEntry("ArrayElement (STRIPS)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000886 IMMEDIATE|ARRAY_ELT|STRIPS);
jtgafb833d1999-08-19 00:55:39 +0000887 glutAddMenuEntry("DrawElements (TRIANGLES)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000888 IMMEDIATE|DRAW_ARRAYS|TRIANGLES);
jtgafb833d1999-08-19 00:55:39 +0000889 glutAddMenuEntry("ArrayElement (TRIANGLES)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000890 IMMEDIATE|ARRAY_ELT|TRIANGLES);
jtgafb833d1999-08-19 00:55:39 +0000891 glutAddMenuEntry("", 0);
892
893 }
894 if (allowed & COMPILED) {
895 glutAddMenuEntry("Compiled DrawElements (TRIANGLES)",
896 COMPILED|DRAW_ARRAYS|TRIANGLES);
897 glutAddMenuEntry("Compiled DrawElements (STRIPS)",
898 COMPILED|DRAW_ARRAYS|STRIPS);
Keith Whitwell44c73931999-09-03 14:56:40 +0000899 glutAddMenuEntry("Compiled ArrayElement (TRIANGLES)",
900 COMPILED|ARRAY_ELT|TRIANGLES);
901 glutAddMenuEntry("Compiled ArrayElement (STRIPS)",
jtgafb833d1999-08-19 00:55:39 +0000902 COMPILED|ARRAY_ELT|STRIPS);
903 glutAddMenuEntry("", 0);
904 }
905 glutAddMenuEntry("Quit", QUIT);
906 glutAttachMenu(GLUT_RIGHT_BUTTON);
907
908 glutReshapeFunc(Reshape);
909 glutKeyboardFunc(Key);
910 glutSpecialFunc(SpecialKey);
911 glutDisplayFunc(Display);
912 glutMainLoop();
913 return 0;
914}