blob: d5b0ceb500ac8cf6a6abf937238bce7feded9137 [file] [log] [blame]
pescod1ff1f62000-12-24 22:53:54 +00001/* $Id: isosurf.c,v 1.7 2000/12/24 22:53:54 pesco 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#include <stdio.h>
29#include <string.h>
30#include <stdlib.h>
Brian Paulac126091999-10-21 16:39:06 +000031#include <string.h>
jtgafb833d1999-08-19 00:55:39 +000032#include <math.h>
Brian Paul02e8a032000-06-27 17:04:43 +000033#define GL_GLEXT_LEGACY
jtgafb833d1999-08-19 00:55:39 +000034#include "GL/glut.h"
35
pescod1ff1f62000-12-24 22:53:54 +000036#include "readtex.c" /* I know, this is a hack. KW: me too. */
jtgafb833d1999-08-19 00:55:39 +000037#define TEXTURE_FILE "../images/reflect.rgb"
38
39#define LIT 0x1
40#define UNLIT 0x2
41#define TEXTURE 0x4
42#define NO_TEXTURE 0x8
43#define REFLECT 0x10
44#define NO_REFLECT 0x20
45#define POINT_FILTER 0x40
46#define LINEAR_FILTER 0x80
Keith Whitwell44c73931999-09-03 14:56:40 +000047#define GLVERTEX 0x100
jtgafb833d1999-08-19 00:55:39 +000048#define DRAW_ARRAYS 0x200 /* or draw_elts, if compiled */
49#define ARRAY_ELT 0x400
50#define COMPILED 0x800
Keith Whitwell44c73931999-09-03 14:56:40 +000051#define IMMEDIATE 0x1000
jtgafb833d1999-08-19 00:55:39 +000052#define SHADE_SMOOTH 0x2000
53#define SHADE_FLAT 0x4000
54#define TRIANGLES 0x8000
55#define STRIPS 0x10000
56#define USER_CLIP 0x20000
57#define NO_USER_CLIP 0x40000
58#define MATERIALS 0x80000
59#define NO_MATERIALS 0x100000
Keith Whitwell44c73931999-09-03 14:56:40 +000060#define FOG 0x200000
61#define NO_FOG 0x400000
jtgafb833d1999-08-19 00:55:39 +000062#define QUIT 0x800000
Keith Whitwell44c73931999-09-03 14:56:40 +000063#define DISPLAYLIST 0x1000000
Keith Whitwell03b7aee2000-03-30 17:58:56 +000064#define GLINFO 0x2000000
65#define STIPPLE 0x4000000
66#define NO_STIPPLE 0x8000000
jtgafb833d1999-08-19 00:55:39 +000067
68#define LIGHT_MASK (LIT|UNLIT)
69#define TEXTURE_MASK (TEXTURE|NO_TEXTURE)
70#define REFLECT_MASK (REFLECT|NO_REFLECT)
71#define FILTER_MASK (POINT_FILTER|LINEAR_FILTER)
Keith Whitwell44c73931999-09-03 14:56:40 +000072#define RENDER_STYLE_MASK (GLVERTEX|DRAW_ARRAYS|ARRAY_ELT)
73#define COMPILED_MASK (COMPILED|IMMEDIATE|DISPLAYLIST)
jtgafb833d1999-08-19 00:55:39 +000074#define MATERIAL_MASK (MATERIALS|NO_MATERIALS)
75#define PRIMITIVE_MASK (TRIANGLES|STRIPS)
76#define CLIP_MASK (USER_CLIP|NO_USER_CLIP)
77#define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT)
Keith Whitwell44c73931999-09-03 14:56:40 +000078#define FOG_MASK (FOG|NO_FOG)
Keith Whitwell03b7aee2000-03-30 17:58:56 +000079#define STIPPLE_MASK (STIPPLE|NO_STIPPLE)
jtgafb833d1999-08-19 00:55:39 +000080
81#define MAXVERTS 10000
82static float data[MAXVERTS][6];
83static float compressed_data[MAXVERTS][6];
84static GLuint indices[MAXVERTS];
85static GLuint tri_indices[MAXVERTS*3];
86static GLfloat col[100][4];
87static GLint numverts, num_tri_verts, numuniq;
88
89static GLfloat xrot;
90static GLfloat yrot;
Keith Whitwell44c73931999-09-03 14:56:40 +000091static GLfloat dist = -6;
jtgafb833d1999-08-19 00:55:39 +000092static GLint state, allowed = ~0;
93static GLboolean doubleBuffer = GL_TRUE;
94static GLdouble plane[4] = {1.0, 0.0, -1.0, 0.0};
Keith Whitwell44c73931999-09-03 14:56:40 +000095static GLuint surf1;
jtgafb833d1999-08-19 00:55:39 +000096
Brian Paulac126091999-10-21 16:39:06 +000097static GLboolean PrintInfo = GL_FALSE;
98
Keith Whitwell03b7aee2000-03-30 17:58:56 +000099
100static GLubyte halftone[] = {
101 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
102 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
103 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
104 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
105 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
106 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
107 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
108 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
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};
112
Brian Paul36ca6bd1999-09-08 22:14:31 +0000113/* forward decl */
114int BuildList( int mode );
115
116
jtgafb833d1999-08-19 00:55:39 +0000117static void read_surface( char *filename )
118{
119 FILE *f;
120
121 f = fopen(filename,"r");
122 if (!f) {
123 printf("couldn't read %s\n", filename);
124 exit(1);
125 }
126
127 numverts = 0;
128 while (!feof(f) && numverts<MAXVERTS) {
129 fscanf( f, "%f %f %f %f %f %f",
130 &data[numverts][0], &data[numverts][1], &data[numverts][2],
131 &data[numverts][3], &data[numverts][4], &data[numverts][5] );
132 numverts++;
133 }
134 numverts--;
135
136 printf("%d vertices, %d triangles\n", numverts, numverts-2);
137 fclose(f);
138}
139
140
141
142
143struct data_idx {
144 float *data;
145 int idx;
146 int uniq_idx;
147};
148
149
150#define COMPARE_FUNC( AXIS ) \
Brian Paulac126091999-10-21 16:39:06 +0000151static int compare_axis_##AXIS( const void *a, const void *b ) \
jtgafb833d1999-08-19 00:55:39 +0000152{ \
153 float t = ( (*(struct data_idx *)a).data[AXIS] - \
154 (*(struct data_idx *)b).data[AXIS] ); \
155 \
156 if (t < 0) return -1; \
157 if (t > 0) return 1; \
158 return 0; \
159}
160
161COMPARE_FUNC(0)
162COMPARE_FUNC(1)
163COMPARE_FUNC(2)
164COMPARE_FUNC(3)
165COMPARE_FUNC(4)
166COMPARE_FUNC(5)
167COMPARE_FUNC(6)
168
169int (*(compare[7]))( const void *a, const void *b ) =
170{
171 compare_axis_0,
172 compare_axis_1,
173 compare_axis_2,
174 compare_axis_3,
175 compare_axis_4,
176 compare_axis_5,
177 compare_axis_6,
178};
179
180
181#define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i)
182
183static int sort_axis( int axis,
184 int vec_size,
185 int vec_stride,
186 struct data_idx *indices,
187 int start,
188 int finish,
189 float *out,
190 int uniq,
191 const float fudge )
192{
193 int i;
194
195 if (finish-start > 2)
196 {
197 qsort( indices+start, finish-start, sizeof(*indices), compare[axis] );
198 }
199 else if (indices[start].data[axis] > indices[start+1].data[axis])
200 {
201 struct data_idx tmp = indices[start];
202 indices[start] = indices[start+1];
203 indices[start+1] = tmp;
204 }
205
206 if (axis == vec_size-1) {
207 for (i = start ; i < finish ; ) {
208 float max = indices[i].data[axis] + fudge;
209 float *dest = VEC_ELT(out, vec_stride, uniq);
210 int j;
211
212 for (j = 0 ; j < vec_size ; j++)
213 dest[j] = indices[i].data[j];
214
215 for ( ; i < finish && max >= indices[i].data[axis]; i++)
216 indices[i].uniq_idx = uniq;
217
218 uniq++;
219 }
220 } else {
221 for (i = start ; i < finish ; ) {
222 int j = i + 1;
223 float max = indices[i].data[axis] + fudge;
224 while (j < finish && max >= indices[j].data[axis]) j++;
225 if (j == i+1) {
226 float *dest = VEC_ELT(out, vec_stride, uniq);
227 int k;
228
229 indices[i].uniq_idx = uniq;
230
231 for (k = 0 ; k < vec_size ; k++)
232 dest[k] = indices[i].data[k];
233
234 uniq++;
235 } else {
236 uniq = sort_axis( axis+1, vec_size, vec_stride,
237 indices, i, j, out, uniq, fudge );
238 }
239 i = j;
240 }
241 }
242
243 return uniq;
244}
245
246
247static void extract_indices1( const struct data_idx *in, unsigned int *out,
248 int n )
249{
250 int i;
251 for ( i = 0 ; i < n ; i++ ) {
252 out[in[i].idx] = in[i].uniq_idx;
253 }
254}
255
256
Brian Paul36ca6bd1999-09-08 22:14:31 +0000257static void compactify_arrays(void)
jtgafb833d1999-08-19 00:55:39 +0000258{
259 int i;
260 struct data_idx *ind;
261
262 ind = (struct data_idx *) malloc( sizeof(struct data_idx) * numverts );
263
264 for (i = 0 ; i < numverts ; i++) {
265 ind[i].idx = i;
266 ind[i].data = data[i];
267 }
268
269 numuniq = sort_axis(0,
270 sizeof(compressed_data[0])/sizeof(float),
271 sizeof(compressed_data[0]),
272 ind,
273 0,
274 numverts,
275 (float *)compressed_data,
276 0,
277 1e-6);
278
279 printf("Nr unique vertex/normal pairs: %d\n", numuniq);
280
281 extract_indices1( ind, indices, numverts );
282 free( ind );
283}
284
285static float myrand( float max )
286{
287 return max*rand()/(RAND_MAX+1.0);
288}
289
290
291static void make_tri_indices( void )
292{
293 unsigned int *v = tri_indices;
294 unsigned int parity = 0;
295 unsigned int i, j;
296
297 for (j=2;j<numverts;j++,parity^=1) {
298 if (parity) {
299 *v++ = indices[j-1];
300 *v++ = indices[j-2];
301 *v++ = indices[j];
302 } else {
303 *v++ = indices[j-2];
304 *v++ = indices[j-1];
305 *v++ = indices[j];
306 }
307 }
308
309 num_tri_verts = v - tri_indices;
310 printf("num_tri_verts: %d\n", num_tri_verts);
311
312 for (i = j = 0 ; i < num_tri_verts ; i += 600, j++) {
313 col[j][3] = 1;
314 col[j][2] = myrand(1);
315 col[j][1] = myrand(1);
316 col[j][0] = myrand(1);
317 }
318}
319
320#define MIN(x,y) (x < y) ? x : y
321
Keith Whitwell44c73931999-09-03 14:56:40 +0000322static void draw_surface( int with_state )
jtgafb833d1999-08-19 00:55:39 +0000323{
324 GLuint i, j;
325
Keith Whitwell44c73931999-09-03 14:56:40 +0000326 switch (with_state & (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
jtgafb833d1999-08-19 00:55:39 +0000327#ifdef GL_EXT_vertex_array
328
329 case (COMPILED|DRAW_ARRAYS|STRIPS):
330 glDrawElements( GL_TRIANGLE_STRIP, numverts, GL_UNSIGNED_INT, indices );
331 break;
332
333
334 case (COMPILED|ARRAY_ELT|STRIPS):
335 glBegin( GL_TRIANGLE_STRIP );
336 for (i = 0 ; i < numverts ; i++)
337 glArrayElement( indices[i] );
338 glEnd();
339 break;
340
341 case (COMPILED|DRAW_ARRAYS|TRIANGLES):
Keith Whitwell44c73931999-09-03 14:56:40 +0000342 case (IMMEDIATE|DRAW_ARRAYS|TRIANGLES):
343 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000344 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
345 GLuint nr = MIN(num_tri_verts-i, 600);
346 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
347 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
348 glDrawElements( GL_TRIANGLES, nr, GL_UNSIGNED_INT, tri_indices+i );
349 }
350 } else {
351 glDrawElements( GL_TRIANGLES, num_tri_verts, GL_UNSIGNED_INT,
352 tri_indices );
353 }
354
355 break;
356
357 /* Uses the original arrays (including duplicate elements):
358 */
Keith Whitwell44c73931999-09-03 14:56:40 +0000359 case (IMMEDIATE|DRAW_ARRAYS|STRIPS):
jtgafb833d1999-08-19 00:55:39 +0000360 glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
361 break;
362
363 /* Uses the original arrays (including duplicate elements):
364 */
Keith Whitwell44c73931999-09-03 14:56:40 +0000365 case (IMMEDIATE|ARRAY_ELT|STRIPS):
jtgafb833d1999-08-19 00:55:39 +0000366 glBegin( GL_TRIANGLE_STRIP );
367 for (i = 0 ; i < numverts ; i++)
368 glArrayElement( i );
369 glEnd();
370 break;
371
Keith Whitwell44c73931999-09-03 14:56:40 +0000372 case (IMMEDIATE|ARRAY_ELT|TRIANGLES):
jtgafb833d1999-08-19 00:55:39 +0000373 case (COMPILED|ARRAY_ELT|TRIANGLES):
Keith Whitwell44c73931999-09-03 14:56:40 +0000374 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000375 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
376 GLuint nr = MIN(num_tri_verts-i, 600);
377 GLuint k;
378 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
379 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
380 glBegin( GL_TRIANGLES );
381 for (k = 0 ; k < nr ; k++)
382 glArrayElement( tri_indices[i+k] );
383 glEnd();
384 }
385 } else {
386 glBegin( GL_TRIANGLES );
387 for (i = 0 ; i < num_tri_verts ; i++)
388 glArrayElement( tri_indices[i] );
Keith Whitwell44c73931999-09-03 14:56:40 +0000389
jtgafb833d1999-08-19 00:55:39 +0000390 glEnd();
391 }
392 break;
393
Keith Whitwell44c73931999-09-03 14:56:40 +0000394 case (IMMEDIATE|GLVERTEX|TRIANGLES):
395 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000396 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
397 GLuint nr = MIN(num_tri_verts-i, 600);
398 GLuint k;
399 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
400 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
401 glBegin( GL_TRIANGLES );
402 for (k = 0 ; k < nr ; k++) {
403 glNormal3fv( &compressed_data[tri_indices[i+k]][3] );
404 glVertex3fv( &compressed_data[tri_indices[i+k]][0] );
405 }
406 glEnd();
407 }
408 } else {
409 glBegin( GL_TRIANGLES );
410 for (i = 0 ; i < num_tri_verts ; i++) {
411 glNormal3fv( &compressed_data[tri_indices[i]][3] );
412 glVertex3fv( &compressed_data[tri_indices[i]][0] );
413 }
414 glEnd();
415 }
416 break;
417
Keith Whitwell44c73931999-09-03 14:56:40 +0000418 case (DISPLAYLIST|GLVERTEX|STRIPS):
419 if (!surf1)
420 surf1 = BuildList( GL_COMPILE_AND_EXECUTE );
421 else
422 glCallList(surf1);
423 break;
424
jtgafb833d1999-08-19 00:55:39 +0000425#endif
426
427 /* Uses the original arrays (including duplicate elements):
428 */
429 default:
430 glBegin( GL_TRIANGLE_STRIP );
431 for (i=0;i<numverts;i++) {
432 glNormal3fv( &data[i][3] );
433 glVertex3fv( &data[i][0] );
434 }
435 glEnd();
436 }
437}
438
439
440
441static void Display(void)
442{
443 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Keith Whitwell44c73931999-09-03 14:56:40 +0000444 draw_surface( state );
jtgafb833d1999-08-19 00:55:39 +0000445 glFlush();
446 if (doubleBuffer) glutSwapBuffers();
447}
448
Keith Whitwell44c73931999-09-03 14:56:40 +0000449int BuildList( int mode )
450{
451 int rv = glGenLists(1);
452 glNewList(rv, mode );
453 draw_surface( IMMEDIATE|GLVERTEX|STRIPS );
454 glEndList();
455 return rv;
456}
457
jtgafb833d1999-08-19 00:55:39 +0000458/* KW: only do this when necessary, so CVA can re-use results.
459 */
460static void set_matrix( void )
461{
462 glMatrixMode(GL_MODELVIEW);
463 glLoadIdentity();
Keith Whitwell44c73931999-09-03 14:56:40 +0000464 glTranslatef( 0.0, 0.0, dist );
jtgafb833d1999-08-19 00:55:39 +0000465 glRotatef( yrot, 0.0, 1.0, 0.0 );
466 glRotatef( xrot, 1.0, 0.0, 0.0 );
467}
468
469static void Benchmark( float xdiff, float ydiff )
470{
471 int startTime, endTime;
472 int draws;
473 double seconds, fps, triPerSecond;
474
475 printf("Benchmarking...\n");
476
477 draws = 0;
478 startTime = glutGet(GLUT_ELAPSED_TIME);
479 xrot = 0.0;
480 do {
481 xrot += xdiff;
482 yrot += ydiff;
483 set_matrix();
484 Display();
485 draws++;
486 endTime = glutGet(GLUT_ELAPSED_TIME);
487 } while (endTime - startTime < 5000); /* 5 seconds */
488
489 /* Results */
490 seconds = (double) (endTime - startTime) / 1000.0;
491 triPerSecond = (numverts - 2) * draws / seconds;
492 fps = draws / seconds;
493 printf("Result: triangles/sec: %g fps: %g\n", triPerSecond, fps);
494}
495
496
497static void InitMaterials(void)
498{
499 static float ambient[] = {0.1, 0.1, 0.1, 1.0};
500 static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
501 static float position0[] = {0.0, 0.0, 20.0, 0.0};
502 static float position1[] = {0.0, 0.0, -20.0, 0.0};
503 static float front_mat_shininess[] = {60.0};
504 static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
505 static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
506 /*
507 static float back_mat_shininess[] = {60.0};
508 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
509 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
510 */
511 static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
512 static float lmodel_twoside[] = {GL_FALSE};
513
514 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
515 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
516 glLightfv(GL_LIGHT0, GL_POSITION, position0);
517 glEnable(GL_LIGHT0);
518
519 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
520 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
521 glLightfv(GL_LIGHT1, GL_POSITION, position1);
522 glEnable(GL_LIGHT1);
523
524 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
525 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
526
527 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
528 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
529 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000530
531 glPolygonStipple (halftone);
jtgafb833d1999-08-19 00:55:39 +0000532}
533
534
535
536#define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
537#define CHANGED(o,n,mask) ((n&mask) && \
538 (n&mask) != (o&mask) ? UPDATE(o,n,mask) : 0)
539
540static void ModeMenu(int m)
541{
542 m &= allowed;
543
544 if (!m) return;
545
546 if (m==QUIT)
547 exit(0);
548
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000549 if (m==GLINFO) {
550 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
551 printf("GL_EXTENSIONS: %s\n", (char *) glGetString(GL_EXTENSIONS));
552 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
553 return;
554 }
555
jtgafb833d1999-08-19 00:55:39 +0000556 if (CHANGED(state, m, FILTER_MASK)) {
557 if (m & LINEAR_FILTER) {
558 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
559 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
560 } else {
561 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
562 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
563 }
564 }
565
566 if (CHANGED(state, m, LIGHT_MASK)) {
567 if (m & LIT)
568 glEnable(GL_LIGHTING);
569 else
570 glDisable(GL_LIGHTING);
571 }
572
573 if (CHANGED(state, m, SHADE_MASK)) {
574 if (m & SHADE_SMOOTH)
575 glShadeModel(GL_SMOOTH);
576 else
577 glShadeModel(GL_FLAT);
578 }
579
580
581 if (CHANGED(state, m, TEXTURE_MASK)) {
582 if (m & TEXTURE)
583 glEnable(GL_TEXTURE_2D);
584 else
585 glDisable(GL_TEXTURE_2D);
586 }
587
588 if (CHANGED(state, m, REFLECT_MASK)) {
589 if (m & REFLECT) {
590 glEnable(GL_TEXTURE_GEN_S);
591 glEnable(GL_TEXTURE_GEN_T);
592 } else {
593 glDisable(GL_TEXTURE_GEN_S);
594 glDisable(GL_TEXTURE_GEN_T);
595 }
596 }
597
598 if (CHANGED(state, m, CLIP_MASK)) {
599 if (m & USER_CLIP) {
600 glEnable(GL_CLIP_PLANE0);
601 } else {
602 glDisable(GL_CLIP_PLANE0);
603 }
604 }
605
Keith Whitwell44c73931999-09-03 14:56:40 +0000606 if (CHANGED(state, m, FOG_MASK)) {
607 if (m & FOG)
608 {
609 glEnable(GL_FOG);
610 printf("FOG enable\n");
611 }
612 else
613 {
614 glDisable(GL_FOG);
615 printf("FOG disable\n");
616 }
617 }
618
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000619 if (CHANGED(state, m, STIPPLE_MASK)) {
620 if (m & STIPPLE)
621 {
622 glEnable(GL_POLYGON_STIPPLE);
623 printf("STIPPLE enable\n");
624 }
625 else
626 {
627 glDisable(GL_POLYGON_STIPPLE);
628 printf("STIPPLE disable\n");
629 }
630 }
631
jtgafb833d1999-08-19 00:55:39 +0000632#ifdef GL_EXT_vertex_array
633 if (CHANGED(state, m, (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)))
634 {
Keith Whitwell44c73931999-09-03 14:56:40 +0000635 if ((m & (COMPILED_MASK|PRIMITIVE_MASK)) == (IMMEDIATE|STRIPS))
jtgafb833d1999-08-19 00:55:39 +0000636 {
637 glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numverts, data );
638 glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numverts, &data[0][3]);
639 }
640 else
641 {
642 glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numuniq,
643 compressed_data );
644 glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numuniq,
645 &compressed_data[0][3]);
646 }
647#ifdef GL_EXT_compiled_vertex_array
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000648 if (allowed & COMPILED) {
649 if (m & COMPILED) {
650 glLockArraysEXT( 0, numuniq );
651 } else {
652 glUnlockArraysEXT();
653 }
jtgafb833d1999-08-19 00:55:39 +0000654 }
655#endif
656 }
657#endif
658
659 if (m & (RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
660 UPDATE(state, m, (RENDER_STYLE_MASK|PRIMITIVE_MASK));
661 }
662
663 if (m & MATERIAL_MASK) {
664 UPDATE(state, m, MATERIAL_MASK);
665 }
666
667 glutPostRedisplay();
668}
669
670
671
Brian Paulac126091999-10-21 16:39:06 +0000672static void Init(int argc, char *argv[])
jtgafb833d1999-08-19 00:55:39 +0000673{
Keith Whitwell44c73931999-09-03 14:56:40 +0000674 GLfloat fogColor[4] = {0.5,1.0,0.5,1.0};
675
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000676 glClearColor(0.0, 0.0, 1.0, 0.0);
jtgafb833d1999-08-19 00:55:39 +0000677 glEnable( GL_DEPTH_TEST );
678 glEnable( GL_VERTEX_ARRAY_EXT );
679 glEnable( GL_NORMAL_ARRAY_EXT );
680
681 InitMaterials();
682
683 glMatrixMode(GL_PROJECTION);
684 glLoadIdentity();
685 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
686
687 glMatrixMode(GL_MODELVIEW);
688 glLoadIdentity();
689 glClipPlane(GL_CLIP_PLANE0, plane);
690
691 set_matrix();
692
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000693 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
jtgafb833d1999-08-19 00:55:39 +0000694 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
695
696 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
697 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
698
699 if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
700 printf("Error: couldn't load texture image\n");
701 exit(1);
702 }
703
Keith Whitwell44c73931999-09-03 14:56:40 +0000704 /* Green fog is easy to see */
705 glFogi(GL_FOG_MODE,GL_EXP2);
706 glFogfv(GL_FOG_COLOR,fogColor);
707 glFogf(GL_FOG_DENSITY,0.15);
708 glHint(GL_FOG_HINT,GL_DONT_CARE);
709
710
Brian Paul36ca6bd1999-09-08 22:14:31 +0000711 compactify_arrays();
712 make_tri_indices();
jtgafb833d1999-08-19 00:55:39 +0000713
Keith Whitwell44c73931999-09-03 14:56:40 +0000714 surf1 = BuildList( GL_COMPILE );
715
jtgafb833d1999-08-19 00:55:39 +0000716 ModeMenu(SHADE_SMOOTH|
717 LIT|
718 NO_TEXTURE|
719 NO_REFLECT|
720 POINT_FILTER|
Keith Whitwell44c73931999-09-03 14:56:40 +0000721 IMMEDIATE|
jtgafb833d1999-08-19 00:55:39 +0000722 NO_USER_CLIP|
723 NO_MATERIALS|
Keith Whitwell44c73931999-09-03 14:56:40 +0000724 NO_FOG|
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000725 NO_STIPPLE|
Keith Whitwell44c73931999-09-03 14:56:40 +0000726 GLVERTEX);
Brian Paulac126091999-10-21 16:39:06 +0000727
728 if (PrintInfo) {
729 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
730 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
731 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
732 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
733 }
jtgafb833d1999-08-19 00:55:39 +0000734}
735
736
737
738static void Reshape(int width, int height)
739{
740 glViewport(0, 0, (GLint)width, (GLint)height);
741}
742
743
744
745static void Key( unsigned char key, int x, int y )
746{
Brian Paul36ca6bd1999-09-08 22:14:31 +0000747 (void) x;
748 (void) y;
jtgafb833d1999-08-19 00:55:39 +0000749 switch (key) {
Keith Whitwell44c73931999-09-03 14:56:40 +0000750 case 27:
751 exit(0);
752 case 'f':
753 ModeMenu((state ^ FOG_MASK) & FOG_MASK);
754 break;
755 case 's':
756 ModeMenu((state ^ SHADE_MASK) & SHADE_MASK);
757 break;
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000758 case 't':
759 ModeMenu((state ^ STIPPLE_MASK) & STIPPLE_MASK);
760 break;
Keith Whitwell44c73931999-09-03 14:56:40 +0000761 case 'l':
762 ModeMenu((state ^ LIGHT_MASK) & LIGHT_MASK);
763 break;
764 case 'm':
765 ModeMenu((state ^ MATERIAL_MASK) & MATERIAL_MASK);
766 break;
767 case 'c':
768 ModeMenu((state ^ CLIP_MASK) & CLIP_MASK);
769 break;
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000770 case 'v':
771 if (allowed&COMPILED)
772 ModeMenu(COMPILED|DRAW_ARRAYS|TRIANGLES);
773 break;
774 case 'V':
775 ModeMenu(IMMEDIATE|GLVERTEX|STRIPS);
776 break;
Keith Whitwell44c73931999-09-03 14:56:40 +0000777 case 'b':
778 Benchmark(5.0, 0);
779 break;
780 case 'B':
781 Benchmark(0, 5.0);
782 break;
783 case 'i':
784 dist += .25;
785 set_matrix();
786 glutPostRedisplay();
787 break;
788 case 'I':
789 dist -= .25;
790 set_matrix();
791 glutPostRedisplay();
792 break;
793 case '-':
794 case '_':
795 plane[3] += 2.0;
796 glMatrixMode(GL_MODELVIEW);
797 glLoadIdentity();
798 glClipPlane(GL_CLIP_PLANE0, plane);
799 set_matrix();
800 glutPostRedisplay();
801 break;
802 case '+':
803 case '=':
804 plane[3] -= 2.0;
805 glMatrixMode(GL_MODELVIEW);
806 glLoadIdentity();
807 glClipPlane(GL_CLIP_PLANE0, plane);
808 set_matrix();
809 glutPostRedisplay();
810 break;
jtgafb833d1999-08-19 00:55:39 +0000811
812 }
813}
814
815
816static void SpecialKey( int key, int x, int y )
817{
Brian Paul36ca6bd1999-09-08 22:14:31 +0000818 (void) x;
819 (void) y;
jtgafb833d1999-08-19 00:55:39 +0000820 switch (key) {
821 case GLUT_KEY_LEFT:
822 yrot -= 15.0;
823 break;
824 case GLUT_KEY_RIGHT:
825 yrot += 15.0;
826 break;
827 case GLUT_KEY_UP:
828 xrot += 15.0;
829 break;
830 case GLUT_KEY_DOWN:
831 xrot -= 15.0;
832 break;
833 default:
834 return;
835 }
836 set_matrix();
837 glutPostRedisplay();
838}
839
840
841
842static GLint Args(int argc, char **argv)
843{
844 GLint i;
845 GLint mode = 0;
846
847 for (i = 1; i < argc; i++) {
848 if (strcmp(argv[i], "-sb") == 0) {
849 doubleBuffer = GL_FALSE;
850 }
851 else if (strcmp(argv[i], "-db") == 0) {
852 doubleBuffer = GL_TRUE;
853 }
Brian Paulac126091999-10-21 16:39:06 +0000854 else if (strcmp(argv[i], "-info") == 0) {
855 PrintInfo = GL_TRUE;
856 }
jtgafb833d1999-08-19 00:55:39 +0000857 else {
858 printf("%s (Bad option).\n", argv[i]);
859 return QUIT;
860 }
861 }
862
863 return mode;
864}
865
866int main(int argc, char **argv)
867{
868 GLenum type;
869 char *extensions;
870
871 GLuint arg_mode = Args(argc, argv);
872
873 if (arg_mode & QUIT)
874 exit(0);
875
876 read_surface( "isosurf.dat" );
877
878 glutInitWindowPosition(0, 0);
879 glutInitWindowSize(400, 400);
880
881 type = GLUT_DEPTH;
882 type |= GLUT_RGB;
883 type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
884 glutInitDisplayMode(type);
885
886 if (glutCreateWindow("Isosurface") <= 0) {
887 exit(0);
888 }
889
890 /* Make sure server supports the vertex array extension */
891 extensions = (char *) glGetString( GL_EXTENSIONS );
892
893 if (!strstr( extensions, "GL_EXT_vertex_array" ))
894 {
895 printf("Vertex arrays not supported by this renderer\n");
896 allowed &= ~(COMPILED|DRAW_ARRAYS|ARRAY_ELT);
897 }
898 else if (!strstr( extensions, "GL_EXT_compiled_vertex_array" ))
899 {
900 printf("Compiled vertex arrays not supported by this renderer\n");
901 allowed &= ~COMPILED;
902 }
903
Brian Paulac126091999-10-21 16:39:06 +0000904 Init(argc, argv);
jtgafb833d1999-08-19 00:55:39 +0000905 ModeMenu(arg_mode);
906
907 glutCreateMenu(ModeMenu);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000908 glutAddMenuEntry("GL info", GLINFO);
909 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +0000910 glutAddMenuEntry("Lit", LIT|NO_TEXTURE|NO_REFLECT);
911 glutAddMenuEntry("Unlit", UNLIT|NO_TEXTURE|NO_REFLECT);
912/* glutAddMenuEntry("Textured", TEXTURE); */
913 glutAddMenuEntry("Reflect", TEXTURE|REFLECT);
914 glutAddMenuEntry("", 0);
915 glutAddMenuEntry("Smooth", SHADE_SMOOTH);
916 glutAddMenuEntry("Flat", SHADE_FLAT);
917 glutAddMenuEntry("", 0);
Keith Whitwell44c73931999-09-03 14:56:40 +0000918 glutAddMenuEntry("Fog", FOG);
919 glutAddMenuEntry("No Fog", NO_FOG);
920 glutAddMenuEntry("", 0);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000921 glutAddMenuEntry("Stipple", STIPPLE);
922 glutAddMenuEntry("No Stipple", NO_STIPPLE);
923 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +0000924 glutAddMenuEntry("Point Filtered", POINT_FILTER);
925 glutAddMenuEntry("Linear Filtered", LINEAR_FILTER);
926 glutAddMenuEntry("", 0);
Keith Whitwell44c73931999-09-03 14:56:40 +0000927 glutAddMenuEntry("glVertex (STRIPS)", IMMEDIATE|GLVERTEX|STRIPS);
928 glutAddMenuEntry("glVertex (TRIANGLES)", IMMEDIATE|GLVERTEX|TRIANGLES);
929 glutAddMenuEntry("", 0);
930 glutAddMenuEntry("glVertex display list (STRIPS)",
931 DISPLAYLIST|GLVERTEX|STRIPS);
jtgafb833d1999-08-19 00:55:39 +0000932 glutAddMenuEntry("", 0);
933 if (allowed & DRAW_ARRAYS) {
934 glutAddMenuEntry("DrawArrays (STRIPS)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000935 IMMEDIATE|DRAW_ARRAYS|STRIPS);
jtgafb833d1999-08-19 00:55:39 +0000936 glutAddMenuEntry("ArrayElement (STRIPS)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000937 IMMEDIATE|ARRAY_ELT|STRIPS);
jtgafb833d1999-08-19 00:55:39 +0000938 glutAddMenuEntry("DrawElements (TRIANGLES)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000939 IMMEDIATE|DRAW_ARRAYS|TRIANGLES);
jtgafb833d1999-08-19 00:55:39 +0000940 glutAddMenuEntry("ArrayElement (TRIANGLES)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000941 IMMEDIATE|ARRAY_ELT|TRIANGLES);
jtgafb833d1999-08-19 00:55:39 +0000942 glutAddMenuEntry("", 0);
943
944 }
945 if (allowed & COMPILED) {
946 glutAddMenuEntry("Compiled DrawElements (TRIANGLES)",
947 COMPILED|DRAW_ARRAYS|TRIANGLES);
948 glutAddMenuEntry("Compiled DrawElements (STRIPS)",
949 COMPILED|DRAW_ARRAYS|STRIPS);
Keith Whitwell44c73931999-09-03 14:56:40 +0000950 glutAddMenuEntry("Compiled ArrayElement (TRIANGLES)",
951 COMPILED|ARRAY_ELT|TRIANGLES);
952 glutAddMenuEntry("Compiled ArrayElement (STRIPS)",
jtgafb833d1999-08-19 00:55:39 +0000953 COMPILED|ARRAY_ELT|STRIPS);
954 glutAddMenuEntry("", 0);
955 }
956 glutAddMenuEntry("Quit", QUIT);
957 glutAttachMenu(GLUT_RIGHT_BUTTON);
958
959 glutReshapeFunc(Reshape);
960 glutKeyboardFunc(Key);
961 glutSpecialFunc(SpecialKey);
962 glutDisplayFunc(Display);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000963
jtgafb833d1999-08-19 00:55:39 +0000964 glutMainLoop();
965 return 0;
966}