blob: 0ae69d101043ea1c88367ad7ba46f10d26ae4f68 [file] [log] [blame]
Keith Whitwell03b7aee2000-03-30 17:58:56 +00001/* $Id: isosurf.c,v 1.5 2000/03/30 17:58:56 keithw 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 *
Brian Paulac126091999-10-21 16:39:06 +00006 * Command line options:
7 * -info print GL implementation information
8 *
jtgafb833d1999-08-19 00:55:39 +00009 * Brian Paul This file in public domain.
10 */
11
Keith Whitwell44c73931999-09-03 14:56:40 +000012
13/* Keys:
14 * =====
15 *
16 * - Arrow keys to rotate
17 * - 's' toggles smooth shading
18 * - 'l' toggles lighting
19 * - 'f' toggles fog
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
24 *
25 * Other options are available via the popup menu.
26 */
27
jtgafb833d1999-08-19 00:55:39 +000028/*
29 * $Log: isosurf.c,v $
Keith Whitwell03b7aee2000-03-30 17:58:56 +000030 * Revision 1.5 2000/03/30 17:58:56 keithw
31 * Added stipple mode
32 *
Brian Paulac126091999-10-21 16:39:06 +000033 * Revision 1.4 1999/10/21 16:39:06 brianp
34 * added -info command line option
35 *
Brian Paul36ca6bd1999-09-08 22:14:31 +000036 * Revision 1.3 1999/09/08 22:14:31 brianp
37 * minor changes. always call compactify_arrays()
38 *
Keith Whitwell44c73931999-09-03 14:56:40 +000039 * Revision 1.2 1999/09/03 14:56:40 keithw
40 * Fog, displaylist and zoom operations
jtgafb833d1999-08-19 00:55:39 +000041 *
42 * Revision 3.4 1999/04/24 01:10:47 keithw
43 * clip planes, materials
44 *
45 * Revision 3.3 1999/03/31 19:42:14 keithw
46 * support for cva
47 *
48 * Revision 3.1 1998/11/01 20:30:20 brianp
49 * added benchmark feature (b key)
50 *
51 * Revision 3.0 1998/02/14 18:42:29 brianp
52 * initial rev
53 *
54 */
55
56
57
58#include <stdio.h>
59#include <string.h>
60#include <stdlib.h>
Brian Paulac126091999-10-21 16:39:06 +000061#include <string.h>
jtgafb833d1999-08-19 00:55:39 +000062#include <math.h>
63#include "GL/glut.h"
64
65#include "../util/readtex.c" /* I know, this is a hack. KW: me too. */
66#define TEXTURE_FILE "../images/reflect.rgb"
67
68#define LIT 0x1
69#define UNLIT 0x2
70#define TEXTURE 0x4
71#define NO_TEXTURE 0x8
72#define REFLECT 0x10
73#define NO_REFLECT 0x20
74#define POINT_FILTER 0x40
75#define LINEAR_FILTER 0x80
Keith Whitwell44c73931999-09-03 14:56:40 +000076#define GLVERTEX 0x100
jtgafb833d1999-08-19 00:55:39 +000077#define DRAW_ARRAYS 0x200 /* or draw_elts, if compiled */
78#define ARRAY_ELT 0x400
79#define COMPILED 0x800
Keith Whitwell44c73931999-09-03 14:56:40 +000080#define IMMEDIATE 0x1000
jtgafb833d1999-08-19 00:55:39 +000081#define SHADE_SMOOTH 0x2000
82#define SHADE_FLAT 0x4000
83#define TRIANGLES 0x8000
84#define STRIPS 0x10000
85#define USER_CLIP 0x20000
86#define NO_USER_CLIP 0x40000
87#define MATERIALS 0x80000
88#define NO_MATERIALS 0x100000
Keith Whitwell44c73931999-09-03 14:56:40 +000089#define FOG 0x200000
90#define NO_FOG 0x400000
jtgafb833d1999-08-19 00:55:39 +000091#define QUIT 0x800000
Keith Whitwell44c73931999-09-03 14:56:40 +000092#define DISPLAYLIST 0x1000000
Keith Whitwell03b7aee2000-03-30 17:58:56 +000093#define GLINFO 0x2000000
94#define STIPPLE 0x4000000
95#define NO_STIPPLE 0x8000000
jtgafb833d1999-08-19 00:55:39 +000096
97#define LIGHT_MASK (LIT|UNLIT)
98#define TEXTURE_MASK (TEXTURE|NO_TEXTURE)
99#define REFLECT_MASK (REFLECT|NO_REFLECT)
100#define FILTER_MASK (POINT_FILTER|LINEAR_FILTER)
Keith Whitwell44c73931999-09-03 14:56:40 +0000101#define RENDER_STYLE_MASK (GLVERTEX|DRAW_ARRAYS|ARRAY_ELT)
102#define COMPILED_MASK (COMPILED|IMMEDIATE|DISPLAYLIST)
jtgafb833d1999-08-19 00:55:39 +0000103#define MATERIAL_MASK (MATERIALS|NO_MATERIALS)
104#define PRIMITIVE_MASK (TRIANGLES|STRIPS)
105#define CLIP_MASK (USER_CLIP|NO_USER_CLIP)
106#define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT)
Keith Whitwell44c73931999-09-03 14:56:40 +0000107#define FOG_MASK (FOG|NO_FOG)
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000108#define STIPPLE_MASK (STIPPLE|NO_STIPPLE)
jtgafb833d1999-08-19 00:55:39 +0000109
110#define MAXVERTS 10000
111static float data[MAXVERTS][6];
112static float compressed_data[MAXVERTS][6];
113static GLuint indices[MAXVERTS];
114static GLuint tri_indices[MAXVERTS*3];
115static GLfloat col[100][4];
116static GLint numverts, num_tri_verts, numuniq;
117
118static GLfloat xrot;
119static GLfloat yrot;
Keith Whitwell44c73931999-09-03 14:56:40 +0000120static GLfloat dist = -6;
jtgafb833d1999-08-19 00:55:39 +0000121static GLint state, allowed = ~0;
122static GLboolean doubleBuffer = GL_TRUE;
123static GLdouble plane[4] = {1.0, 0.0, -1.0, 0.0};
Keith Whitwell44c73931999-09-03 14:56:40 +0000124static GLuint surf1;
jtgafb833d1999-08-19 00:55:39 +0000125
Brian Paulac126091999-10-21 16:39:06 +0000126static GLboolean PrintInfo = GL_FALSE;
127
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000128
129static GLubyte halftone[] = {
130 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
131 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
132 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
133 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
134 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
135 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
136 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
137 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
138 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
139 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
140 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
141
Brian Paul36ca6bd1999-09-08 22:14:31 +0000142/* forward decl */
143int BuildList( int mode );
144
145
jtgafb833d1999-08-19 00:55:39 +0000146static void read_surface( char *filename )
147{
148 FILE *f;
149
150 f = fopen(filename,"r");
151 if (!f) {
152 printf("couldn't read %s\n", filename);
153 exit(1);
154 }
155
156 numverts = 0;
157 while (!feof(f) && numverts<MAXVERTS) {
158 fscanf( f, "%f %f %f %f %f %f",
159 &data[numverts][0], &data[numverts][1], &data[numverts][2],
160 &data[numverts][3], &data[numverts][4], &data[numverts][5] );
161 numverts++;
162 }
163 numverts--;
164
165 printf("%d vertices, %d triangles\n", numverts, numverts-2);
166 fclose(f);
167}
168
169
170
171
172struct data_idx {
173 float *data;
174 int idx;
175 int uniq_idx;
176};
177
178
179#define COMPARE_FUNC( AXIS ) \
Brian Paulac126091999-10-21 16:39:06 +0000180static int compare_axis_##AXIS( const void *a, const void *b ) \
jtgafb833d1999-08-19 00:55:39 +0000181{ \
182 float t = ( (*(struct data_idx *)a).data[AXIS] - \
183 (*(struct data_idx *)b).data[AXIS] ); \
184 \
185 if (t < 0) return -1; \
186 if (t > 0) return 1; \
187 return 0; \
188}
189
190COMPARE_FUNC(0)
191COMPARE_FUNC(1)
192COMPARE_FUNC(2)
193COMPARE_FUNC(3)
194COMPARE_FUNC(4)
195COMPARE_FUNC(5)
196COMPARE_FUNC(6)
197
198int (*(compare[7]))( const void *a, const void *b ) =
199{
200 compare_axis_0,
201 compare_axis_1,
202 compare_axis_2,
203 compare_axis_3,
204 compare_axis_4,
205 compare_axis_5,
206 compare_axis_6,
207};
208
209
210#define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i)
211
212static int sort_axis( int axis,
213 int vec_size,
214 int vec_stride,
215 struct data_idx *indices,
216 int start,
217 int finish,
218 float *out,
219 int uniq,
220 const float fudge )
221{
222 int i;
223
224 if (finish-start > 2)
225 {
226 qsort( indices+start, finish-start, sizeof(*indices), compare[axis] );
227 }
228 else if (indices[start].data[axis] > indices[start+1].data[axis])
229 {
230 struct data_idx tmp = indices[start];
231 indices[start] = indices[start+1];
232 indices[start+1] = tmp;
233 }
234
235 if (axis == vec_size-1) {
236 for (i = start ; i < finish ; ) {
237 float max = indices[i].data[axis] + fudge;
238 float *dest = VEC_ELT(out, vec_stride, uniq);
239 int j;
240
241 for (j = 0 ; j < vec_size ; j++)
242 dest[j] = indices[i].data[j];
243
244 for ( ; i < finish && max >= indices[i].data[axis]; i++)
245 indices[i].uniq_idx = uniq;
246
247 uniq++;
248 }
249 } else {
250 for (i = start ; i < finish ; ) {
251 int j = i + 1;
252 float max = indices[i].data[axis] + fudge;
253 while (j < finish && max >= indices[j].data[axis]) j++;
254 if (j == i+1) {
255 float *dest = VEC_ELT(out, vec_stride, uniq);
256 int k;
257
258 indices[i].uniq_idx = uniq;
259
260 for (k = 0 ; k < vec_size ; k++)
261 dest[k] = indices[i].data[k];
262
263 uniq++;
264 } else {
265 uniq = sort_axis( axis+1, vec_size, vec_stride,
266 indices, i, j, out, uniq, fudge );
267 }
268 i = j;
269 }
270 }
271
272 return uniq;
273}
274
275
276static void extract_indices1( const struct data_idx *in, unsigned int *out,
277 int n )
278{
279 int i;
280 for ( i = 0 ; i < n ; i++ ) {
281 out[in[i].idx] = in[i].uniq_idx;
282 }
283}
284
285
Brian Paul36ca6bd1999-09-08 22:14:31 +0000286static void compactify_arrays(void)
jtgafb833d1999-08-19 00:55:39 +0000287{
288 int i;
289 struct data_idx *ind;
290
291 ind = (struct data_idx *) malloc( sizeof(struct data_idx) * numverts );
292
293 for (i = 0 ; i < numverts ; i++) {
294 ind[i].idx = i;
295 ind[i].data = data[i];
296 }
297
298 numuniq = sort_axis(0,
299 sizeof(compressed_data[0])/sizeof(float),
300 sizeof(compressed_data[0]),
301 ind,
302 0,
303 numverts,
304 (float *)compressed_data,
305 0,
306 1e-6);
307
308 printf("Nr unique vertex/normal pairs: %d\n", numuniq);
309
310 extract_indices1( ind, indices, numverts );
311 free( ind );
312}
313
314static float myrand( float max )
315{
316 return max*rand()/(RAND_MAX+1.0);
317}
318
319
320static void make_tri_indices( void )
321{
322 unsigned int *v = tri_indices;
323 unsigned int parity = 0;
324 unsigned int i, j;
325
326 for (j=2;j<numverts;j++,parity^=1) {
327 if (parity) {
328 *v++ = indices[j-1];
329 *v++ = indices[j-2];
330 *v++ = indices[j];
331 } else {
332 *v++ = indices[j-2];
333 *v++ = indices[j-1];
334 *v++ = indices[j];
335 }
336 }
337
338 num_tri_verts = v - tri_indices;
339 printf("num_tri_verts: %d\n", num_tri_verts);
340
341 for (i = j = 0 ; i < num_tri_verts ; i += 600, j++) {
342 col[j][3] = 1;
343 col[j][2] = myrand(1);
344 col[j][1] = myrand(1);
345 col[j][0] = myrand(1);
346 }
347}
348
349#define MIN(x,y) (x < y) ? x : y
350
Keith Whitwell44c73931999-09-03 14:56:40 +0000351static void draw_surface( int with_state )
jtgafb833d1999-08-19 00:55:39 +0000352{
353 GLuint i, j;
354
Keith Whitwell44c73931999-09-03 14:56:40 +0000355 switch (with_state & (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
jtgafb833d1999-08-19 00:55:39 +0000356#ifdef GL_EXT_vertex_array
357
358 case (COMPILED|DRAW_ARRAYS|STRIPS):
359 glDrawElements( GL_TRIANGLE_STRIP, numverts, GL_UNSIGNED_INT, indices );
360 break;
361
362
363 case (COMPILED|ARRAY_ELT|STRIPS):
364 glBegin( GL_TRIANGLE_STRIP );
365 for (i = 0 ; i < numverts ; i++)
366 glArrayElement( indices[i] );
367 glEnd();
368 break;
369
370 case (COMPILED|DRAW_ARRAYS|TRIANGLES):
Keith Whitwell44c73931999-09-03 14:56:40 +0000371 case (IMMEDIATE|DRAW_ARRAYS|TRIANGLES):
372 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000373 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
374 GLuint nr = MIN(num_tri_verts-i, 600);
375 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
376 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
377 glDrawElements( GL_TRIANGLES, nr, GL_UNSIGNED_INT, tri_indices+i );
378 }
379 } else {
380 glDrawElements( GL_TRIANGLES, num_tri_verts, GL_UNSIGNED_INT,
381 tri_indices );
382 }
383
384 break;
385
386 /* Uses the original arrays (including duplicate elements):
387 */
Keith Whitwell44c73931999-09-03 14:56:40 +0000388 case (IMMEDIATE|DRAW_ARRAYS|STRIPS):
jtgafb833d1999-08-19 00:55:39 +0000389 glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
390 break;
391
392 /* Uses the original arrays (including duplicate elements):
393 */
Keith Whitwell44c73931999-09-03 14:56:40 +0000394 case (IMMEDIATE|ARRAY_ELT|STRIPS):
jtgafb833d1999-08-19 00:55:39 +0000395 glBegin( GL_TRIANGLE_STRIP );
396 for (i = 0 ; i < numverts ; i++)
397 glArrayElement( i );
398 glEnd();
399 break;
400
Keith Whitwell44c73931999-09-03 14:56:40 +0000401 case (IMMEDIATE|ARRAY_ELT|TRIANGLES):
jtgafb833d1999-08-19 00:55:39 +0000402 case (COMPILED|ARRAY_ELT|TRIANGLES):
Keith Whitwell44c73931999-09-03 14:56:40 +0000403 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000404 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
405 GLuint nr = MIN(num_tri_verts-i, 600);
406 GLuint k;
407 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
408 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
409 glBegin( GL_TRIANGLES );
410 for (k = 0 ; k < nr ; k++)
411 glArrayElement( tri_indices[i+k] );
412 glEnd();
413 }
414 } else {
415 glBegin( GL_TRIANGLES );
416 for (i = 0 ; i < num_tri_verts ; i++)
417 glArrayElement( tri_indices[i] );
Keith Whitwell44c73931999-09-03 14:56:40 +0000418
jtgafb833d1999-08-19 00:55:39 +0000419 glEnd();
420 }
421 break;
422
Keith Whitwell44c73931999-09-03 14:56:40 +0000423 case (IMMEDIATE|GLVERTEX|TRIANGLES):
424 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000425 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
426 GLuint nr = MIN(num_tri_verts-i, 600);
427 GLuint k;
428 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
429 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
430 glBegin( GL_TRIANGLES );
431 for (k = 0 ; k < nr ; k++) {
432 glNormal3fv( &compressed_data[tri_indices[i+k]][3] );
433 glVertex3fv( &compressed_data[tri_indices[i+k]][0] );
434 }
435 glEnd();
436 }
437 } else {
438 glBegin( GL_TRIANGLES );
439 for (i = 0 ; i < num_tri_verts ; i++) {
440 glNormal3fv( &compressed_data[tri_indices[i]][3] );
441 glVertex3fv( &compressed_data[tri_indices[i]][0] );
442 }
443 glEnd();
444 }
445 break;
446
Keith Whitwell44c73931999-09-03 14:56:40 +0000447 case (DISPLAYLIST|GLVERTEX|STRIPS):
448 if (!surf1)
449 surf1 = BuildList( GL_COMPILE_AND_EXECUTE );
450 else
451 glCallList(surf1);
452 break;
453
jtgafb833d1999-08-19 00:55:39 +0000454#endif
455
456 /* Uses the original arrays (including duplicate elements):
457 */
458 default:
459 glBegin( GL_TRIANGLE_STRIP );
460 for (i=0;i<numverts;i++) {
461 glNormal3fv( &data[i][3] );
462 glVertex3fv( &data[i][0] );
463 }
464 glEnd();
465 }
466}
467
468
469
470static void Display(void)
471{
472 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Keith Whitwell44c73931999-09-03 14:56:40 +0000473 draw_surface( state );
jtgafb833d1999-08-19 00:55:39 +0000474 glFlush();
475 if (doubleBuffer) glutSwapBuffers();
476}
477
Keith Whitwell44c73931999-09-03 14:56:40 +0000478int BuildList( int mode )
479{
480 int rv = glGenLists(1);
481 glNewList(rv, mode );
482 draw_surface( IMMEDIATE|GLVERTEX|STRIPS );
483 glEndList();
484 return rv;
485}
486
jtgafb833d1999-08-19 00:55:39 +0000487/* KW: only do this when necessary, so CVA can re-use results.
488 */
489static void set_matrix( void )
490{
491 glMatrixMode(GL_MODELVIEW);
492 glLoadIdentity();
Keith Whitwell44c73931999-09-03 14:56:40 +0000493 glTranslatef( 0.0, 0.0, dist );
jtgafb833d1999-08-19 00:55:39 +0000494 glRotatef( yrot, 0.0, 1.0, 0.0 );
495 glRotatef( xrot, 1.0, 0.0, 0.0 );
496}
497
498static void Benchmark( float xdiff, float ydiff )
499{
500 int startTime, endTime;
501 int draws;
502 double seconds, fps, triPerSecond;
503
504 printf("Benchmarking...\n");
505
506 draws = 0;
507 startTime = glutGet(GLUT_ELAPSED_TIME);
508 xrot = 0.0;
509 do {
510 xrot += xdiff;
511 yrot += ydiff;
512 set_matrix();
513 Display();
514 draws++;
515 endTime = glutGet(GLUT_ELAPSED_TIME);
516 } while (endTime - startTime < 5000); /* 5 seconds */
517
518 /* Results */
519 seconds = (double) (endTime - startTime) / 1000.0;
520 triPerSecond = (numverts - 2) * draws / seconds;
521 fps = draws / seconds;
522 printf("Result: triangles/sec: %g fps: %g\n", triPerSecond, fps);
523}
524
525
526static void InitMaterials(void)
527{
528 static float ambient[] = {0.1, 0.1, 0.1, 1.0};
529 static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
530 static float position0[] = {0.0, 0.0, 20.0, 0.0};
531 static float position1[] = {0.0, 0.0, -20.0, 0.0};
532 static float front_mat_shininess[] = {60.0};
533 static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
534 static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
535 /*
536 static float back_mat_shininess[] = {60.0};
537 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
538 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
539 */
540 static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
541 static float lmodel_twoside[] = {GL_FALSE};
542
543 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
544 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
545 glLightfv(GL_LIGHT0, GL_POSITION, position0);
546 glEnable(GL_LIGHT0);
547
548 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
549 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
550 glLightfv(GL_LIGHT1, GL_POSITION, position1);
551 glEnable(GL_LIGHT1);
552
553 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
554 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
555
556 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
557 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
558 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000559
560 glPolygonStipple (halftone);
jtgafb833d1999-08-19 00:55:39 +0000561}
562
563
564
565#define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
566#define CHANGED(o,n,mask) ((n&mask) && \
567 (n&mask) != (o&mask) ? UPDATE(o,n,mask) : 0)
568
569static void ModeMenu(int m)
570{
571 m &= allowed;
572
573 if (!m) return;
574
575 if (m==QUIT)
576 exit(0);
577
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000578 if (m==GLINFO) {
579 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
580 printf("GL_EXTENSIONS: %s\n", (char *) glGetString(GL_EXTENSIONS));
581 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
582 return;
583 }
584
jtgafb833d1999-08-19 00:55:39 +0000585 if (CHANGED(state, m, FILTER_MASK)) {
586 if (m & LINEAR_FILTER) {
587 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
588 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
589 } else {
590 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
591 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
592 }
593 }
594
595 if (CHANGED(state, m, LIGHT_MASK)) {
596 if (m & LIT)
597 glEnable(GL_LIGHTING);
598 else
599 glDisable(GL_LIGHTING);
600 }
601
602 if (CHANGED(state, m, SHADE_MASK)) {
603 if (m & SHADE_SMOOTH)
604 glShadeModel(GL_SMOOTH);
605 else
606 glShadeModel(GL_FLAT);
607 }
608
609
610 if (CHANGED(state, m, TEXTURE_MASK)) {
611 if (m & TEXTURE)
612 glEnable(GL_TEXTURE_2D);
613 else
614 glDisable(GL_TEXTURE_2D);
615 }
616
617 if (CHANGED(state, m, REFLECT_MASK)) {
618 if (m & REFLECT) {
619 glEnable(GL_TEXTURE_GEN_S);
620 glEnable(GL_TEXTURE_GEN_T);
621 } else {
622 glDisable(GL_TEXTURE_GEN_S);
623 glDisable(GL_TEXTURE_GEN_T);
624 }
625 }
626
627 if (CHANGED(state, m, CLIP_MASK)) {
628 if (m & USER_CLIP) {
629 glEnable(GL_CLIP_PLANE0);
630 } else {
631 glDisable(GL_CLIP_PLANE0);
632 }
633 }
634
Keith Whitwell44c73931999-09-03 14:56:40 +0000635 if (CHANGED(state, m, FOG_MASK)) {
636 if (m & FOG)
637 {
638 glEnable(GL_FOG);
639 printf("FOG enable\n");
640 }
641 else
642 {
643 glDisable(GL_FOG);
644 printf("FOG disable\n");
645 }
646 }
647
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000648 if (CHANGED(state, m, STIPPLE_MASK)) {
649 if (m & STIPPLE)
650 {
651 glEnable(GL_POLYGON_STIPPLE);
652 printf("STIPPLE enable\n");
653 }
654 else
655 {
656 glDisable(GL_POLYGON_STIPPLE);
657 printf("STIPPLE disable\n");
658 }
659 }
660
jtgafb833d1999-08-19 00:55:39 +0000661#ifdef GL_EXT_vertex_array
662 if (CHANGED(state, m, (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)))
663 {
Keith Whitwell44c73931999-09-03 14:56:40 +0000664 if ((m & (COMPILED_MASK|PRIMITIVE_MASK)) == (IMMEDIATE|STRIPS))
jtgafb833d1999-08-19 00:55:39 +0000665 {
666 glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numverts, data );
667 glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numverts, &data[0][3]);
668 }
669 else
670 {
671 glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numuniq,
672 compressed_data );
673 glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numuniq,
674 &compressed_data[0][3]);
675 }
676#ifdef GL_EXT_compiled_vertex_array
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000677 if (allowed & COMPILED) {
678 if (m & COMPILED) {
679 glLockArraysEXT( 0, numuniq );
680 } else {
681 glUnlockArraysEXT();
682 }
jtgafb833d1999-08-19 00:55:39 +0000683 }
684#endif
685 }
686#endif
687
688 if (m & (RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
689 UPDATE(state, m, (RENDER_STYLE_MASK|PRIMITIVE_MASK));
690 }
691
692 if (m & MATERIAL_MASK) {
693 UPDATE(state, m, MATERIAL_MASK);
694 }
695
696 glutPostRedisplay();
697}
698
699
700
Brian Paulac126091999-10-21 16:39:06 +0000701static void Init(int argc, char *argv[])
jtgafb833d1999-08-19 00:55:39 +0000702{
Keith Whitwell44c73931999-09-03 14:56:40 +0000703 GLfloat fogColor[4] = {0.5,1.0,0.5,1.0};
704
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000705 glClearColor(0.0, 0.0, 1.0, 0.0);
jtgafb833d1999-08-19 00:55:39 +0000706 glEnable( GL_DEPTH_TEST );
707 glEnable( GL_VERTEX_ARRAY_EXT );
708 glEnable( GL_NORMAL_ARRAY_EXT );
709
710 InitMaterials();
711
712 glMatrixMode(GL_PROJECTION);
713 glLoadIdentity();
714 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
715
716 glMatrixMode(GL_MODELVIEW);
717 glLoadIdentity();
718 glClipPlane(GL_CLIP_PLANE0, plane);
719
720 set_matrix();
721
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000722 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
jtgafb833d1999-08-19 00:55:39 +0000723 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
724
725 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
726 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
727
728 if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
729 printf("Error: couldn't load texture image\n");
730 exit(1);
731 }
732
Keith Whitwell44c73931999-09-03 14:56:40 +0000733 /* Green fog is easy to see */
734 glFogi(GL_FOG_MODE,GL_EXP2);
735 glFogfv(GL_FOG_COLOR,fogColor);
736 glFogf(GL_FOG_DENSITY,0.15);
737 glHint(GL_FOG_HINT,GL_DONT_CARE);
738
739
Brian Paul36ca6bd1999-09-08 22:14:31 +0000740 compactify_arrays();
741 make_tri_indices();
jtgafb833d1999-08-19 00:55:39 +0000742
Keith Whitwell44c73931999-09-03 14:56:40 +0000743 surf1 = BuildList( GL_COMPILE );
744
jtgafb833d1999-08-19 00:55:39 +0000745 ModeMenu(SHADE_SMOOTH|
746 LIT|
747 NO_TEXTURE|
748 NO_REFLECT|
749 POINT_FILTER|
Keith Whitwell44c73931999-09-03 14:56:40 +0000750 IMMEDIATE|
jtgafb833d1999-08-19 00:55:39 +0000751 NO_USER_CLIP|
752 NO_MATERIALS|
Keith Whitwell44c73931999-09-03 14:56:40 +0000753 NO_FOG|
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000754 NO_STIPPLE|
Keith Whitwell44c73931999-09-03 14:56:40 +0000755 GLVERTEX);
Brian Paulac126091999-10-21 16:39:06 +0000756
757 if (PrintInfo) {
758 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
759 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
760 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
761 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
762 }
jtgafb833d1999-08-19 00:55:39 +0000763}
764
765
766
767static void Reshape(int width, int height)
768{
769 glViewport(0, 0, (GLint)width, (GLint)height);
770}
771
772
773
774static void Key( unsigned char key, int x, int y )
775{
Brian Paul36ca6bd1999-09-08 22:14:31 +0000776 (void) x;
777 (void) y;
jtgafb833d1999-08-19 00:55:39 +0000778 switch (key) {
Keith Whitwell44c73931999-09-03 14:56:40 +0000779 case 27:
780 exit(0);
781 case 'f':
782 ModeMenu((state ^ FOG_MASK) & FOG_MASK);
783 break;
784 case 's':
785 ModeMenu((state ^ SHADE_MASK) & SHADE_MASK);
786 break;
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000787 case 't':
788 ModeMenu((state ^ STIPPLE_MASK) & STIPPLE_MASK);
789 break;
Keith Whitwell44c73931999-09-03 14:56:40 +0000790 case 'l':
791 ModeMenu((state ^ LIGHT_MASK) & LIGHT_MASK);
792 break;
793 case 'm':
794 ModeMenu((state ^ MATERIAL_MASK) & MATERIAL_MASK);
795 break;
796 case 'c':
797 ModeMenu((state ^ CLIP_MASK) & CLIP_MASK);
798 break;
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000799 case 'v':
800 if (allowed&COMPILED)
801 ModeMenu(COMPILED|DRAW_ARRAYS|TRIANGLES);
802 break;
803 case 'V':
804 ModeMenu(IMMEDIATE|GLVERTEX|STRIPS);
805 break;
Keith Whitwell44c73931999-09-03 14:56:40 +0000806 case 'b':
807 Benchmark(5.0, 0);
808 break;
809 case 'B':
810 Benchmark(0, 5.0);
811 break;
812 case 'i':
813 dist += .25;
814 set_matrix();
815 glutPostRedisplay();
816 break;
817 case 'I':
818 dist -= .25;
819 set_matrix();
820 glutPostRedisplay();
821 break;
822 case '-':
823 case '_':
824 plane[3] += 2.0;
825 glMatrixMode(GL_MODELVIEW);
826 glLoadIdentity();
827 glClipPlane(GL_CLIP_PLANE0, plane);
828 set_matrix();
829 glutPostRedisplay();
830 break;
831 case '+':
832 case '=':
833 plane[3] -= 2.0;
834 glMatrixMode(GL_MODELVIEW);
835 glLoadIdentity();
836 glClipPlane(GL_CLIP_PLANE0, plane);
837 set_matrix();
838 glutPostRedisplay();
839 break;
jtgafb833d1999-08-19 00:55:39 +0000840
841 }
842}
843
844
845static void SpecialKey( int key, int x, int y )
846{
Brian Paul36ca6bd1999-09-08 22:14:31 +0000847 (void) x;
848 (void) y;
jtgafb833d1999-08-19 00:55:39 +0000849 switch (key) {
850 case GLUT_KEY_LEFT:
851 yrot -= 15.0;
852 break;
853 case GLUT_KEY_RIGHT:
854 yrot += 15.0;
855 break;
856 case GLUT_KEY_UP:
857 xrot += 15.0;
858 break;
859 case GLUT_KEY_DOWN:
860 xrot -= 15.0;
861 break;
862 default:
863 return;
864 }
865 set_matrix();
866 glutPostRedisplay();
867}
868
869
870
871static GLint Args(int argc, char **argv)
872{
873 GLint i;
874 GLint mode = 0;
875
876 for (i = 1; i < argc; i++) {
877 if (strcmp(argv[i], "-sb") == 0) {
878 doubleBuffer = GL_FALSE;
879 }
880 else if (strcmp(argv[i], "-db") == 0) {
881 doubleBuffer = GL_TRUE;
882 }
Brian Paulac126091999-10-21 16:39:06 +0000883 else if (strcmp(argv[i], "-info") == 0) {
884 PrintInfo = GL_TRUE;
885 }
jtgafb833d1999-08-19 00:55:39 +0000886 else {
887 printf("%s (Bad option).\n", argv[i]);
888 return QUIT;
889 }
890 }
891
892 return mode;
893}
894
895int main(int argc, char **argv)
896{
897 GLenum type;
898 char *extensions;
899
900 GLuint arg_mode = Args(argc, argv);
901
902 if (arg_mode & QUIT)
903 exit(0);
904
905 read_surface( "isosurf.dat" );
906
907 glutInitWindowPosition(0, 0);
908 glutInitWindowSize(400, 400);
909
910 type = GLUT_DEPTH;
911 type |= GLUT_RGB;
912 type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
913 glutInitDisplayMode(type);
914
915 if (glutCreateWindow("Isosurface") <= 0) {
916 exit(0);
917 }
918
919 /* Make sure server supports the vertex array extension */
920 extensions = (char *) glGetString( GL_EXTENSIONS );
921
922 if (!strstr( extensions, "GL_EXT_vertex_array" ))
923 {
924 printf("Vertex arrays not supported by this renderer\n");
925 allowed &= ~(COMPILED|DRAW_ARRAYS|ARRAY_ELT);
926 }
927 else if (!strstr( extensions, "GL_EXT_compiled_vertex_array" ))
928 {
929 printf("Compiled vertex arrays not supported by this renderer\n");
930 allowed &= ~COMPILED;
931 }
932
Brian Paulac126091999-10-21 16:39:06 +0000933 Init(argc, argv);
jtgafb833d1999-08-19 00:55:39 +0000934 ModeMenu(arg_mode);
935
936 glutCreateMenu(ModeMenu);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000937 glutAddMenuEntry("GL info", GLINFO);
938 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +0000939 glutAddMenuEntry("Lit", LIT|NO_TEXTURE|NO_REFLECT);
940 glutAddMenuEntry("Unlit", UNLIT|NO_TEXTURE|NO_REFLECT);
941/* glutAddMenuEntry("Textured", TEXTURE); */
942 glutAddMenuEntry("Reflect", TEXTURE|REFLECT);
943 glutAddMenuEntry("", 0);
944 glutAddMenuEntry("Smooth", SHADE_SMOOTH);
945 glutAddMenuEntry("Flat", SHADE_FLAT);
946 glutAddMenuEntry("", 0);
Keith Whitwell44c73931999-09-03 14:56:40 +0000947 glutAddMenuEntry("Fog", FOG);
948 glutAddMenuEntry("No Fog", NO_FOG);
949 glutAddMenuEntry("", 0);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000950 glutAddMenuEntry("Stipple", STIPPLE);
951 glutAddMenuEntry("No Stipple", NO_STIPPLE);
952 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +0000953 glutAddMenuEntry("Point Filtered", POINT_FILTER);
954 glutAddMenuEntry("Linear Filtered", LINEAR_FILTER);
955 glutAddMenuEntry("", 0);
Keith Whitwell44c73931999-09-03 14:56:40 +0000956 glutAddMenuEntry("glVertex (STRIPS)", IMMEDIATE|GLVERTEX|STRIPS);
957 glutAddMenuEntry("glVertex (TRIANGLES)", IMMEDIATE|GLVERTEX|TRIANGLES);
958 glutAddMenuEntry("", 0);
959 glutAddMenuEntry("glVertex display list (STRIPS)",
960 DISPLAYLIST|GLVERTEX|STRIPS);
jtgafb833d1999-08-19 00:55:39 +0000961 glutAddMenuEntry("", 0);
962 if (allowed & DRAW_ARRAYS) {
963 glutAddMenuEntry("DrawArrays (STRIPS)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000964 IMMEDIATE|DRAW_ARRAYS|STRIPS);
jtgafb833d1999-08-19 00:55:39 +0000965 glutAddMenuEntry("ArrayElement (STRIPS)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000966 IMMEDIATE|ARRAY_ELT|STRIPS);
jtgafb833d1999-08-19 00:55:39 +0000967 glutAddMenuEntry("DrawElements (TRIANGLES)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000968 IMMEDIATE|DRAW_ARRAYS|TRIANGLES);
jtgafb833d1999-08-19 00:55:39 +0000969 glutAddMenuEntry("ArrayElement (TRIANGLES)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000970 IMMEDIATE|ARRAY_ELT|TRIANGLES);
jtgafb833d1999-08-19 00:55:39 +0000971 glutAddMenuEntry("", 0);
972
973 }
974 if (allowed & COMPILED) {
975 glutAddMenuEntry("Compiled DrawElements (TRIANGLES)",
976 COMPILED|DRAW_ARRAYS|TRIANGLES);
977 glutAddMenuEntry("Compiled DrawElements (STRIPS)",
978 COMPILED|DRAW_ARRAYS|STRIPS);
Keith Whitwell44c73931999-09-03 14:56:40 +0000979 glutAddMenuEntry("Compiled ArrayElement (TRIANGLES)",
980 COMPILED|ARRAY_ELT|TRIANGLES);
981 glutAddMenuEntry("Compiled ArrayElement (STRIPS)",
jtgafb833d1999-08-19 00:55:39 +0000982 COMPILED|ARRAY_ELT|STRIPS);
983 glutAddMenuEntry("", 0);
984 }
985 glutAddMenuEntry("Quit", QUIT);
986 glutAttachMenu(GLUT_RIGHT_BUTTON);
987
988 glutReshapeFunc(Reshape);
989 glutKeyboardFunc(Key);
990 glutSpecialFunc(SpecialKey);
991 glutDisplayFunc(Display);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000992
jtgafb833d1999-08-19 00:55:39 +0000993 glutMainLoop();
994 return 0;
995}