blob: 9c78a474904ba4c8d7516e2a5b48c1a30d62bc76 [file] [log] [blame]
Gareth Hughesc8516462001-01-06 20:38:03 +00001/* $Id: isosurf.c,v 1.8 2001/01/06 20:38:03 gareth Exp $ */
jtgafb833d1999-08-19 00:55:39 +00002
3/*
Gareth Hughesc8516462001-01-06 20:38:03 +00004 * Display an isosurface of 3-D wind speed volume.
Keith Whitwell44c73931999-09-03 14:56:40 +00005 *
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
Gareth Hughesc8516462001-01-06 20:38:03 +000039#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
47#define GLVERTEX 0x100
48#define DRAW_ARRAYS 0x200 /* or draw_elts, if compiled */
49#define ARRAY_ELT 0x400
50#define COMPILED 0x800
51#define IMMEDIATE 0x1000
52#define SHADE_SMOOTH 0x2000
53#define SHADE_FLAT 0x4000
54#define TRIANGLES 0x8000
55#define STRIPS 0x10000
56#define POINTS 0x20000
57#define USER_CLIP 0x40000
58#define NO_USER_CLIP 0x80000
59#define MATERIALS 0x100000
60#define NO_MATERIALS 0x200000
61#define FOG 0x400000
62#define NO_FOG 0x800000
63#define QUIT 0x1000000
64#define DISPLAYLIST 0x2000000
65#define GLINFO 0x4000000
66#define STIPPLE 0x8000000
67#define NO_STIPPLE 0x10000000
jtgafb833d1999-08-19 00:55:39 +000068
Gareth Hughesc8516462001-01-06 20:38:03 +000069#define LIGHT_MASK (LIT|UNLIT)
70#define TEXTURE_MASK (TEXTURE|NO_TEXTURE)
71#define REFLECT_MASK (REFLECT|NO_REFLECT)
72#define FILTER_MASK (POINT_FILTER|LINEAR_FILTER)
73#define RENDER_STYLE_MASK (GLVERTEX|DRAW_ARRAYS|ARRAY_ELT)
74#define COMPILED_MASK (COMPILED|IMMEDIATE|DISPLAYLIST)
75#define MATERIAL_MASK (MATERIALS|NO_MATERIALS)
76#define PRIMITIVE_MASK (TRIANGLES|STRIPS|POINTS)
77#define CLIP_MASK (USER_CLIP|NO_USER_CLIP)
78#define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT)
79#define FOG_MASK (FOG|NO_FOG)
80#define STIPPLE_MASK (STIPPLE|NO_STIPPLE)
jtgafb833d1999-08-19 00:55:39 +000081
82#define MAXVERTS 10000
83static float data[MAXVERTS][6];
84static float compressed_data[MAXVERTS][6];
85static GLuint indices[MAXVERTS];
86static GLuint tri_indices[MAXVERTS*3];
87static GLfloat col[100][4];
88static GLint numverts, num_tri_verts, numuniq;
89
90static GLfloat xrot;
91static GLfloat yrot;
Keith Whitwell44c73931999-09-03 14:56:40 +000092static GLfloat dist = -6;
jtgafb833d1999-08-19 00:55:39 +000093static GLint state, allowed = ~0;
94static GLboolean doubleBuffer = GL_TRUE;
95static GLdouble plane[4] = {1.0, 0.0, -1.0, 0.0};
Keith Whitwell44c73931999-09-03 14:56:40 +000096static GLuint surf1;
jtgafb833d1999-08-19 00:55:39 +000097
Brian Paulac126091999-10-21 16:39:06 +000098static GLboolean PrintInfo = GL_FALSE;
99
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000100
101static GLubyte halftone[] = {
102 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
103 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
104 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
105 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
106 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
107 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
108 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
109 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
110 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
111 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
112 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
113
Brian Paul36ca6bd1999-09-08 22:14:31 +0000114/* forward decl */
115int BuildList( int mode );
116
117
jtgafb833d1999-08-19 00:55:39 +0000118static void read_surface( char *filename )
119{
120 FILE *f;
121
122 f = fopen(filename,"r");
123 if (!f) {
124 printf("couldn't read %s\n", filename);
125 exit(1);
126 }
127
128 numverts = 0;
129 while (!feof(f) && numverts<MAXVERTS) {
130 fscanf( f, "%f %f %f %f %f %f",
131 &data[numverts][0], &data[numverts][1], &data[numverts][2],
132 &data[numverts][3], &data[numverts][4], &data[numverts][5] );
133 numverts++;
134 }
135 numverts--;
136
137 printf("%d vertices, %d triangles\n", numverts, numverts-2);
138 fclose(f);
139}
140
141
142
143
144struct data_idx {
145 float *data;
146 int idx;
147 int uniq_idx;
148};
149
150
151#define COMPARE_FUNC( AXIS ) \
Brian Paulac126091999-10-21 16:39:06 +0000152static int compare_axis_##AXIS( const void *a, const void *b ) \
jtgafb833d1999-08-19 00:55:39 +0000153{ \
154 float t = ( (*(struct data_idx *)a).data[AXIS] - \
155 (*(struct data_idx *)b).data[AXIS] ); \
156 \
157 if (t < 0) return -1; \
158 if (t > 0) return 1; \
159 return 0; \
160}
161
162COMPARE_FUNC(0)
163COMPARE_FUNC(1)
164COMPARE_FUNC(2)
165COMPARE_FUNC(3)
166COMPARE_FUNC(4)
167COMPARE_FUNC(5)
168COMPARE_FUNC(6)
169
170int (*(compare[7]))( const void *a, const void *b ) =
171{
172 compare_axis_0,
173 compare_axis_1,
174 compare_axis_2,
175 compare_axis_3,
176 compare_axis_4,
177 compare_axis_5,
178 compare_axis_6,
179};
180
181
182#define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i)
183
Gareth Hughesc8516462001-01-06 20:38:03 +0000184static int sort_axis( int axis,
jtgafb833d1999-08-19 00:55:39 +0000185 int vec_size,
186 int vec_stride,
187 struct data_idx *indices,
188 int start,
189 int finish,
190 float *out,
191 int uniq,
192 const float fudge )
193{
194 int i;
195
Gareth Hughesc8516462001-01-06 20:38:03 +0000196 if (finish-start > 2)
jtgafb833d1999-08-19 00:55:39 +0000197 {
198 qsort( indices+start, finish-start, sizeof(*indices), compare[axis] );
Gareth Hughesc8516462001-01-06 20:38:03 +0000199 }
200 else if (indices[start].data[axis] > indices[start+1].data[axis])
jtgafb833d1999-08-19 00:55:39 +0000201 {
202 struct data_idx tmp = indices[start];
203 indices[start] = indices[start+1];
204 indices[start+1] = tmp;
205 }
Gareth Hughesc8516462001-01-06 20:38:03 +0000206
jtgafb833d1999-08-19 00:55:39 +0000207 if (axis == vec_size-1) {
208 for (i = start ; i < finish ; ) {
209 float max = indices[i].data[axis] + fudge;
210 float *dest = VEC_ELT(out, vec_stride, uniq);
211 int j;
Gareth Hughesc8516462001-01-06 20:38:03 +0000212
jtgafb833d1999-08-19 00:55:39 +0000213 for (j = 0 ; j < vec_size ; j++)
214 dest[j] = indices[i].data[j];
215
Gareth Hughesc8516462001-01-06 20:38:03 +0000216 for ( ; i < finish && max >= indices[i].data[axis]; i++)
jtgafb833d1999-08-19 00:55:39 +0000217 indices[i].uniq_idx = uniq;
218
219 uniq++;
220 }
221 } else {
222 for (i = start ; i < finish ; ) {
223 int j = i + 1;
224 float max = indices[i].data[axis] + fudge;
225 while (j < finish && max >= indices[j].data[axis]) j++;
226 if (j == i+1) {
227 float *dest = VEC_ELT(out, vec_stride, uniq);
228 int k;
229
230 indices[i].uniq_idx = uniq;
Gareth Hughesc8516462001-01-06 20:38:03 +0000231
jtgafb833d1999-08-19 00:55:39 +0000232 for (k = 0 ; k < vec_size ; k++)
233 dest[k] = indices[i].data[k];
234
235 uniq++;
236 } else {
237 uniq = sort_axis( axis+1, vec_size, vec_stride,
238 indices, i, j, out, uniq, fudge );
239 }
240 i = j;
241 }
242 }
243
244 return uniq;
245}
246
247
Gareth Hughesc8516462001-01-06 20:38:03 +0000248static void extract_indices1( const struct data_idx *in, unsigned int *out,
jtgafb833d1999-08-19 00:55:39 +0000249 int n )
250{
251 int i;
252 for ( i = 0 ; i < n ; i++ ) {
253 out[in[i].idx] = in[i].uniq_idx;
254 }
255}
256
257
Brian Paul36ca6bd1999-09-08 22:14:31 +0000258static void compactify_arrays(void)
jtgafb833d1999-08-19 00:55:39 +0000259{
260 int i;
261 struct data_idx *ind;
262
263 ind = (struct data_idx *) malloc( sizeof(struct data_idx) * numverts );
264
265 for (i = 0 ; i < numverts ; i++) {
266 ind[i].idx = i;
267 ind[i].data = data[i];
268 }
269
Gareth Hughesc8516462001-01-06 20:38:03 +0000270 numuniq = sort_axis(0,
271 sizeof(compressed_data[0])/sizeof(float),
jtgafb833d1999-08-19 00:55:39 +0000272 sizeof(compressed_data[0]),
Gareth Hughesc8516462001-01-06 20:38:03 +0000273 ind,
274 0,
275 numverts,
276 (float *)compressed_data,
jtgafb833d1999-08-19 00:55:39 +0000277 0,
278 1e-6);
279
280 printf("Nr unique vertex/normal pairs: %d\n", numuniq);
281
282 extract_indices1( ind, indices, numverts );
283 free( ind );
284}
285
286static float myrand( float max )
287{
288 return max*rand()/(RAND_MAX+1.0);
289}
290
291
292static void make_tri_indices( void )
293{
294 unsigned int *v = tri_indices;
295 unsigned int parity = 0;
296 unsigned int i, j;
297
298 for (j=2;j<numverts;j++,parity^=1) {
299 if (parity) {
300 *v++ = indices[j-1];
Gareth Hughesc8516462001-01-06 20:38:03 +0000301 *v++ = indices[j-2];
jtgafb833d1999-08-19 00:55:39 +0000302 *v++ = indices[j];
303 } else {
304 *v++ = indices[j-2];
305 *v++ = indices[j-1];
306 *v++ = indices[j];
307 }
308 }
Gareth Hughesc8516462001-01-06 20:38:03 +0000309
jtgafb833d1999-08-19 00:55:39 +0000310 num_tri_verts = v - tri_indices;
311 printf("num_tri_verts: %d\n", num_tri_verts);
312
313 for (i = j = 0 ; i < num_tri_verts ; i += 600, j++) {
314 col[j][3] = 1;
315 col[j][2] = myrand(1);
316 col[j][1] = myrand(1);
317 col[j][0] = myrand(1);
318 }
319}
320
321#define MIN(x,y) (x < y) ? x : y
322
Keith Whitwell44c73931999-09-03 14:56:40 +0000323static void draw_surface( int with_state )
jtgafb833d1999-08-19 00:55:39 +0000324{
325 GLuint i, j;
326
Keith Whitwell44c73931999-09-03 14:56:40 +0000327 switch (with_state & (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
jtgafb833d1999-08-19 00:55:39 +0000328#ifdef GL_EXT_vertex_array
329
Keith Whitwell44c73931999-09-03 14:56:40 +0000330 case (IMMEDIATE|DRAW_ARRAYS|TRIANGLES):
Gareth Hughesc8516462001-01-06 20:38:03 +0000331 case (COMPILED|DRAW_ARRAYS|TRIANGLES):
Keith Whitwell44c73931999-09-03 14:56:40 +0000332 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000333 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
334 GLuint nr = MIN(num_tri_verts-i, 600);
335 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
336 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
337 glDrawElements( GL_TRIANGLES, nr, GL_UNSIGNED_INT, tri_indices+i );
338 }
339 } else {
Gareth Hughesc8516462001-01-06 20:38:03 +0000340 glDrawElements( GL_TRIANGLES, num_tri_verts, GL_UNSIGNED_INT,
jtgafb833d1999-08-19 00:55:39 +0000341 tri_indices );
342 }
jtgafb833d1999-08-19 00:55:39 +0000343 break;
344
Keith Whitwell44c73931999-09-03 14:56:40 +0000345 case (IMMEDIATE|ARRAY_ELT|TRIANGLES):
jtgafb833d1999-08-19 00:55:39 +0000346 case (COMPILED|ARRAY_ELT|TRIANGLES):
Keith Whitwell44c73931999-09-03 14:56:40 +0000347 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000348 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
349 GLuint nr = MIN(num_tri_verts-i, 600);
350 GLuint k;
351 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
352 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
353 glBegin( GL_TRIANGLES );
354 for (k = 0 ; k < nr ; k++)
355 glArrayElement( tri_indices[i+k] );
356 glEnd();
357 }
358 } else {
359 glBegin( GL_TRIANGLES );
360 for (i = 0 ; i < num_tri_verts ; i++)
361 glArrayElement( tri_indices[i] );
Gareth Hughesc8516462001-01-06 20:38:03 +0000362
jtgafb833d1999-08-19 00:55:39 +0000363 glEnd();
Gareth Hughesc8516462001-01-06 20:38:03 +0000364 }
jtgafb833d1999-08-19 00:55:39 +0000365 break;
366
Gareth Hughesc8516462001-01-06 20:38:03 +0000367
368 /* Uses the original arrays (including duplicate elements):
369 */
370 case (IMMEDIATE|DRAW_ARRAYS|STRIPS):
371 glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
372 break;
373 case (COMPILED|DRAW_ARRAYS|STRIPS):
374 glDrawElements( GL_TRIANGLE_STRIP, numverts, GL_UNSIGNED_INT, indices );
375 break;
376
377 /* Uses the original arrays (including duplicate elements):
378 */
379 case (IMMEDIATE|ARRAY_ELT|STRIPS):
380 glBegin( GL_TRIANGLE_STRIP );
381 for (i = 0 ; i < numverts ; i++)
382 glArrayElement( i );
383 glEnd();
384 break;
385
386 case (COMPILED|ARRAY_ELT|STRIPS):
387 glBegin( GL_TRIANGLE_STRIP );
388 for (i = 0 ; i < numverts ; i++)
389 glArrayElement( indices[i] );
390 glEnd();
391 break;
392
393 case (DISPLAYLIST|GLVERTEX|STRIPS):
394 if (!surf1)
395 surf1 = BuildList( GL_COMPILE_AND_EXECUTE );
396 else
397 glCallList(surf1);
398 break;
399
400
401 case (IMMEDIATE|DRAW_ARRAYS|POINTS):
402 glDrawArraysEXT( GL_POINTS, 0, numverts );
403 break;
404 case (COMPILED|DRAW_ARRAYS|POINTS):
405 glDrawElements( GL_POINTS, numverts, GL_UNSIGNED_INT, indices );
406 break;
407 case (IMMEDIATE|ARRAY_ELT|POINTS):
408 case (COMPILED|ARRAY_ELT|POINTS):
409 glBegin( GL_POINTS );
410 for (i = 0 ; i < numverts ; i++)
411 glArrayElement( indices[i] );
412 glEnd();
413 break;
414#endif
415
Keith Whitwell44c73931999-09-03 14:56:40 +0000416 case (IMMEDIATE|GLVERTEX|TRIANGLES):
417 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000418 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
419 GLuint nr = MIN(num_tri_verts-i, 600);
420 GLuint k;
421 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
422 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
423 glBegin( GL_TRIANGLES );
424 for (k = 0 ; k < nr ; k++) {
425 glNormal3fv( &compressed_data[tri_indices[i+k]][3] );
426 glVertex3fv( &compressed_data[tri_indices[i+k]][0] );
427 }
428 glEnd();
429 }
430 } else {
431 glBegin( GL_TRIANGLES );
432 for (i = 0 ; i < num_tri_verts ; i++) {
433 glNormal3fv( &compressed_data[tri_indices[i]][3] );
434 glVertex3fv( &compressed_data[tri_indices[i]][0] );
435 }
436 glEnd();
Gareth Hughesc8516462001-01-06 20:38:03 +0000437 }
jtgafb833d1999-08-19 00:55:39 +0000438 break;
439
Gareth Hughesc8516462001-01-06 20:38:03 +0000440 case (IMMEDIATE|GLVERTEX|POINTS):
441 glBegin( GL_POINTS );
442 for ( i = 0 ; i < numverts ; i++ ) {
443 glNormal3fv( &data[i][3] );
444 glVertex3fv( &data[i][0] );
445 }
446 glEnd();
Keith Whitwell44c73931999-09-03 14:56:40 +0000447 break;
448
jtgafb833d1999-08-19 00:55:39 +0000449 /* Uses the original arrays (including duplicate elements):
450 */
451 default:
452 glBegin( GL_TRIANGLE_STRIP );
453 for (i=0;i<numverts;i++) {
454 glNormal3fv( &data[i][3] );
455 glVertex3fv( &data[i][0] );
456 }
457 glEnd();
458 }
459}
460
461
462
463static void Display(void)
464{
465 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Keith Whitwell44c73931999-09-03 14:56:40 +0000466 draw_surface( state );
jtgafb833d1999-08-19 00:55:39 +0000467 glFlush();
Gareth Hughesc8516462001-01-06 20:38:03 +0000468 if (doubleBuffer) glutSwapBuffers();
jtgafb833d1999-08-19 00:55:39 +0000469}
470
Keith Whitwell44c73931999-09-03 14:56:40 +0000471int BuildList( int mode )
472{
473 int rv = glGenLists(1);
474 glNewList(rv, mode );
475 draw_surface( IMMEDIATE|GLVERTEX|STRIPS );
476 glEndList();
477 return rv;
478}
479
jtgafb833d1999-08-19 00:55:39 +0000480/* KW: only do this when necessary, so CVA can re-use results.
481 */
482static void set_matrix( void )
483{
484 glMatrixMode(GL_MODELVIEW);
485 glLoadIdentity();
Keith Whitwell44c73931999-09-03 14:56:40 +0000486 glTranslatef( 0.0, 0.0, dist );
jtgafb833d1999-08-19 00:55:39 +0000487 glRotatef( yrot, 0.0, 1.0, 0.0 );
488 glRotatef( xrot, 1.0, 0.0, 0.0 );
489}
490
491static void Benchmark( float xdiff, float ydiff )
492{
493 int startTime, endTime;
494 int draws;
495 double seconds, fps, triPerSecond;
496
497 printf("Benchmarking...\n");
498
499 draws = 0;
500 startTime = glutGet(GLUT_ELAPSED_TIME);
501 xrot = 0.0;
502 do {
503 xrot += xdiff;
504 yrot += ydiff;
505 set_matrix();
506 Display();
507 draws++;
508 endTime = glutGet(GLUT_ELAPSED_TIME);
509 } while (endTime - startTime < 5000); /* 5 seconds */
510
511 /* Results */
512 seconds = (double) (endTime - startTime) / 1000.0;
513 triPerSecond = (numverts - 2) * draws / seconds;
514 fps = draws / seconds;
515 printf("Result: triangles/sec: %g fps: %g\n", triPerSecond, fps);
516}
517
518
519static void InitMaterials(void)
520{
521 static float ambient[] = {0.1, 0.1, 0.1, 1.0};
522 static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
523 static float position0[] = {0.0, 0.0, 20.0, 0.0};
524 static float position1[] = {0.0, 0.0, -20.0, 0.0};
525 static float front_mat_shininess[] = {60.0};
526 static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
527 static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
528 /*
529 static float back_mat_shininess[] = {60.0};
530 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
531 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
532 */
533 static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
534 static float lmodel_twoside[] = {GL_FALSE};
535
536 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
537 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
538 glLightfv(GL_LIGHT0, GL_POSITION, position0);
539 glEnable(GL_LIGHT0);
Gareth Hughesc8516462001-01-06 20:38:03 +0000540
jtgafb833d1999-08-19 00:55:39 +0000541 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
542 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
543 glLightfv(GL_LIGHT1, GL_POSITION, position1);
544 glEnable(GL_LIGHT1);
Gareth Hughesc8516462001-01-06 20:38:03 +0000545
jtgafb833d1999-08-19 00:55:39 +0000546 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
547 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
548
549 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
550 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
551 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000552
553 glPolygonStipple (halftone);
jtgafb833d1999-08-19 00:55:39 +0000554}
555
556
557
558#define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
559#define CHANGED(o,n,mask) ((n&mask) && \
560 (n&mask) != (o&mask) ? UPDATE(o,n,mask) : 0)
561
562static void ModeMenu(int m)
563{
564 m &= allowed;
565
566 if (!m) return;
567
Gareth Hughesc8516462001-01-06 20:38:03 +0000568 if (m==QUIT)
jtgafb833d1999-08-19 00:55:39 +0000569 exit(0);
570
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000571 if (m==GLINFO) {
572 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
573 printf("GL_EXTENSIONS: %s\n", (char *) glGetString(GL_EXTENSIONS));
574 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
575 return;
576 }
577
jtgafb833d1999-08-19 00:55:39 +0000578 if (CHANGED(state, m, FILTER_MASK)) {
579 if (m & LINEAR_FILTER) {
580 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
581 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
582 } else {
583 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
584 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
585 }
586 }
587
588 if (CHANGED(state, m, LIGHT_MASK)) {
589 if (m & LIT)
590 glEnable(GL_LIGHTING);
591 else
592 glDisable(GL_LIGHTING);
593 }
594
595 if (CHANGED(state, m, SHADE_MASK)) {
596 if (m & SHADE_SMOOTH)
597 glShadeModel(GL_SMOOTH);
598 else
599 glShadeModel(GL_FLAT);
600 }
601
602
603 if (CHANGED(state, m, TEXTURE_MASK)) {
Gareth Hughesc8516462001-01-06 20:38:03 +0000604 if (m & TEXTURE)
jtgafb833d1999-08-19 00:55:39 +0000605 glEnable(GL_TEXTURE_2D);
606 else
607 glDisable(GL_TEXTURE_2D);
608 }
609
610 if (CHANGED(state, m, REFLECT_MASK)) {
611 if (m & REFLECT) {
612 glEnable(GL_TEXTURE_GEN_S);
613 glEnable(GL_TEXTURE_GEN_T);
614 } else {
615 glDisable(GL_TEXTURE_GEN_S);
616 glDisable(GL_TEXTURE_GEN_T);
617 }
618 }
619
620 if (CHANGED(state, m, CLIP_MASK)) {
621 if (m & USER_CLIP) {
622 glEnable(GL_CLIP_PLANE0);
623 } else {
624 glDisable(GL_CLIP_PLANE0);
625 }
626 }
627
Keith Whitwell44c73931999-09-03 14:56:40 +0000628 if (CHANGED(state, m, FOG_MASK)) {
Gareth Hughesc8516462001-01-06 20:38:03 +0000629 if (m & FOG)
Keith Whitwell44c73931999-09-03 14:56:40 +0000630 {
631 glEnable(GL_FOG);
632 printf("FOG enable\n");
Gareth Hughesc8516462001-01-06 20:38:03 +0000633 }
634 else
Keith Whitwell44c73931999-09-03 14:56:40 +0000635 {
636 glDisable(GL_FOG);
637 printf("FOG disable\n");
638 }
639 }
640
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000641 if (CHANGED(state, m, STIPPLE_MASK)) {
Gareth Hughesc8516462001-01-06 20:38:03 +0000642 if (m & STIPPLE)
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000643 {
644 glEnable(GL_POLYGON_STIPPLE);
645 printf("STIPPLE enable\n");
Gareth Hughesc8516462001-01-06 20:38:03 +0000646 }
647 else
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000648 {
649 glDisable(GL_POLYGON_STIPPLE);
650 printf("STIPPLE disable\n");
651 }
652 }
653
jtgafb833d1999-08-19 00:55:39 +0000654#ifdef GL_EXT_vertex_array
Gareth Hughesc8516462001-01-06 20:38:03 +0000655 if (CHANGED(state, m, (COMPILED_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)))
jtgafb833d1999-08-19 00:55:39 +0000656 {
Keith Whitwell44c73931999-09-03 14:56:40 +0000657 if ((m & (COMPILED_MASK|PRIMITIVE_MASK)) == (IMMEDIATE|STRIPS))
jtgafb833d1999-08-19 00:55:39 +0000658 {
659 glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numverts, data );
660 glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numverts, &data[0][3]);
661 }
Gareth Hughesc8516462001-01-06 20:38:03 +0000662 else
jtgafb833d1999-08-19 00:55:39 +0000663 {
Gareth Hughesc8516462001-01-06 20:38:03 +0000664 glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numuniq,
jtgafb833d1999-08-19 00:55:39 +0000665 compressed_data );
Gareth Hughesc8516462001-01-06 20:38:03 +0000666 glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numuniq,
jtgafb833d1999-08-19 00:55:39 +0000667 &compressed_data[0][3]);
668 }
669#ifdef GL_EXT_compiled_vertex_array
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000670 if (allowed & COMPILED) {
671 if (m & COMPILED) {
672 glLockArraysEXT( 0, numuniq );
673 } else {
674 glUnlockArraysEXT();
675 }
jtgafb833d1999-08-19 00:55:39 +0000676 }
677#endif
678 }
679#endif
680
681 if (m & (RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
682 UPDATE(state, m, (RENDER_STYLE_MASK|PRIMITIVE_MASK));
683 }
Gareth Hughesc8516462001-01-06 20:38:03 +0000684
jtgafb833d1999-08-19 00:55:39 +0000685 if (m & MATERIAL_MASK) {
686 UPDATE(state, m, MATERIAL_MASK);
687 }
688
689 glutPostRedisplay();
690}
691
692
693
Brian Paulac126091999-10-21 16:39:06 +0000694static void Init(int argc, char *argv[])
jtgafb833d1999-08-19 00:55:39 +0000695{
Keith Whitwell44c73931999-09-03 14:56:40 +0000696 GLfloat fogColor[4] = {0.5,1.0,0.5,1.0};
697
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000698 glClearColor(0.0, 0.0, 1.0, 0.0);
jtgafb833d1999-08-19 00:55:39 +0000699 glEnable( GL_DEPTH_TEST );
700 glEnable( GL_VERTEX_ARRAY_EXT );
701 glEnable( GL_NORMAL_ARRAY_EXT );
702
703 InitMaterials();
704
705 glMatrixMode(GL_PROJECTION);
706 glLoadIdentity();
707 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
708
709 glMatrixMode(GL_MODELVIEW);
710 glLoadIdentity();
Gareth Hughesc8516462001-01-06 20:38:03 +0000711 glClipPlane(GL_CLIP_PLANE0, plane);
jtgafb833d1999-08-19 00:55:39 +0000712
713 set_matrix();
714
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000715 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
jtgafb833d1999-08-19 00:55:39 +0000716 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
717
718 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
719 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
720
721 if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
722 printf("Error: couldn't load texture image\n");
723 exit(1);
724 }
725
Keith Whitwell44c73931999-09-03 14:56:40 +0000726 /* Green fog is easy to see */
727 glFogi(GL_FOG_MODE,GL_EXP2);
728 glFogfv(GL_FOG_COLOR,fogColor);
729 glFogf(GL_FOG_DENSITY,0.15);
730 glHint(GL_FOG_HINT,GL_DONT_CARE);
731
732
Brian Paul36ca6bd1999-09-08 22:14:31 +0000733 compactify_arrays();
734 make_tri_indices();
jtgafb833d1999-08-19 00:55:39 +0000735
Keith Whitwell44c73931999-09-03 14:56:40 +0000736 surf1 = BuildList( GL_COMPILE );
737
jtgafb833d1999-08-19 00:55:39 +0000738 ModeMenu(SHADE_SMOOTH|
739 LIT|
740 NO_TEXTURE|
741 NO_REFLECT|
742 POINT_FILTER|
Keith Whitwell44c73931999-09-03 14:56:40 +0000743 IMMEDIATE|
jtgafb833d1999-08-19 00:55:39 +0000744 NO_USER_CLIP|
745 NO_MATERIALS|
Keith Whitwell44c73931999-09-03 14:56:40 +0000746 NO_FOG|
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000747 NO_STIPPLE|
Keith Whitwell44c73931999-09-03 14:56:40 +0000748 GLVERTEX);
Brian Paulac126091999-10-21 16:39:06 +0000749
750 if (PrintInfo) {
751 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
752 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
753 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
754 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
755 }
jtgafb833d1999-08-19 00:55:39 +0000756}
757
758
759
760static void Reshape(int width, int height)
761{
762 glViewport(0, 0, (GLint)width, (GLint)height);
763}
764
765
766
767static void Key( unsigned char key, int x, int y )
768{
Brian Paul36ca6bd1999-09-08 22:14:31 +0000769 (void) x;
770 (void) y;
jtgafb833d1999-08-19 00:55:39 +0000771 switch (key) {
Keith Whitwell44c73931999-09-03 14:56:40 +0000772 case 27:
773 exit(0);
774 case 'f':
775 ModeMenu((state ^ FOG_MASK) & FOG_MASK);
776 break;
777 case 's':
778 ModeMenu((state ^ SHADE_MASK) & SHADE_MASK);
779 break;
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000780 case 't':
781 ModeMenu((state ^ STIPPLE_MASK) & STIPPLE_MASK);
782 break;
Keith Whitwell44c73931999-09-03 14:56:40 +0000783 case 'l':
784 ModeMenu((state ^ LIGHT_MASK) & LIGHT_MASK);
785 break;
786 case 'm':
787 ModeMenu((state ^ MATERIAL_MASK) & MATERIAL_MASK);
788 break;
789 case 'c':
790 ModeMenu((state ^ CLIP_MASK) & CLIP_MASK);
791 break;
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000792 case 'v':
793 if (allowed&COMPILED)
794 ModeMenu(COMPILED|DRAW_ARRAYS|TRIANGLES);
795 break;
796 case 'V':
797 ModeMenu(IMMEDIATE|GLVERTEX|STRIPS);
798 break;
Keith Whitwell44c73931999-09-03 14:56:40 +0000799 case 'b':
800 Benchmark(5.0, 0);
801 break;
802 case 'B':
803 Benchmark(0, 5.0);
804 break;
805 case 'i':
806 dist += .25;
807 set_matrix();
808 glutPostRedisplay();
809 break;
810 case 'I':
811 dist -= .25;
812 set_matrix();
813 glutPostRedisplay();
814 break;
815 case '-':
816 case '_':
817 plane[3] += 2.0;
818 glMatrixMode(GL_MODELVIEW);
819 glLoadIdentity();
820 glClipPlane(GL_CLIP_PLANE0, plane);
821 set_matrix();
822 glutPostRedisplay();
823 break;
824 case '+':
825 case '=':
826 plane[3] -= 2.0;
827 glMatrixMode(GL_MODELVIEW);
828 glLoadIdentity();
829 glClipPlane(GL_CLIP_PLANE0, plane);
830 set_matrix();
831 glutPostRedisplay();
832 break;
jtgafb833d1999-08-19 00:55:39 +0000833
834 }
835}
836
837
838static void SpecialKey( int key, int x, int y )
839{
Brian Paul36ca6bd1999-09-08 22:14:31 +0000840 (void) x;
841 (void) y;
jtgafb833d1999-08-19 00:55:39 +0000842 switch (key) {
843 case GLUT_KEY_LEFT:
844 yrot -= 15.0;
845 break;
846 case GLUT_KEY_RIGHT:
847 yrot += 15.0;
848 break;
849 case GLUT_KEY_UP:
850 xrot += 15.0;
851 break;
852 case GLUT_KEY_DOWN:
853 xrot -= 15.0;
854 break;
855 default:
856 return;
857 }
858 set_matrix();
859 glutPostRedisplay();
860}
861
862
863
864static GLint Args(int argc, char **argv)
865{
866 GLint i;
867 GLint mode = 0;
868
869 for (i = 1; i < argc; i++) {
870 if (strcmp(argv[i], "-sb") == 0) {
871 doubleBuffer = GL_FALSE;
872 }
873 else if (strcmp(argv[i], "-db") == 0) {
874 doubleBuffer = GL_TRUE;
875 }
Brian Paulac126091999-10-21 16:39:06 +0000876 else if (strcmp(argv[i], "-info") == 0) {
877 PrintInfo = GL_TRUE;
878 }
jtgafb833d1999-08-19 00:55:39 +0000879 else {
880 printf("%s (Bad option).\n", argv[i]);
881 return QUIT;
882 }
883 }
884
885 return mode;
886}
887
888int main(int argc, char **argv)
889{
890 GLenum type;
891 char *extensions;
892
893 GLuint arg_mode = Args(argc, argv);
894
895 if (arg_mode & QUIT)
896 exit(0);
897
898 read_surface( "isosurf.dat" );
899
900 glutInitWindowPosition(0, 0);
901 glutInitWindowSize(400, 400);
Gareth Hughesc8516462001-01-06 20:38:03 +0000902
jtgafb833d1999-08-19 00:55:39 +0000903 type = GLUT_DEPTH;
904 type |= GLUT_RGB;
905 type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
906 glutInitDisplayMode(type);
907
908 if (glutCreateWindow("Isosurface") <= 0) {
909 exit(0);
910 }
911
912 /* Make sure server supports the vertex array extension */
913 extensions = (char *) glGetString( GL_EXTENSIONS );
914
Gareth Hughesc8516462001-01-06 20:38:03 +0000915 if (!strstr( extensions, "GL_EXT_vertex_array" ))
jtgafb833d1999-08-19 00:55:39 +0000916 {
917 printf("Vertex arrays not supported by this renderer\n");
918 allowed &= ~(COMPILED|DRAW_ARRAYS|ARRAY_ELT);
919 }
Gareth Hughesc8516462001-01-06 20:38:03 +0000920 else if (!strstr( extensions, "GL_EXT_compiled_vertex_array" ))
jtgafb833d1999-08-19 00:55:39 +0000921 {
922 printf("Compiled vertex arrays not supported by this renderer\n");
923 allowed &= ~COMPILED;
924 }
925
Brian Paulac126091999-10-21 16:39:06 +0000926 Init(argc, argv);
jtgafb833d1999-08-19 00:55:39 +0000927 ModeMenu(arg_mode);
Gareth Hughesc8516462001-01-06 20:38:03 +0000928
jtgafb833d1999-08-19 00:55:39 +0000929 glutCreateMenu(ModeMenu);
Gareth Hughesc8516462001-01-06 20:38:03 +0000930 glutAddMenuEntry("GL info", GLINFO);
931 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +0000932 glutAddMenuEntry("Lit", LIT|NO_TEXTURE|NO_REFLECT);
933 glutAddMenuEntry("Unlit", UNLIT|NO_TEXTURE|NO_REFLECT);
934/* glutAddMenuEntry("Textured", TEXTURE); */
935 glutAddMenuEntry("Reflect", TEXTURE|REFLECT);
Gareth Hughesc8516462001-01-06 20:38:03 +0000936 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +0000937 glutAddMenuEntry("Smooth", SHADE_SMOOTH);
938 glutAddMenuEntry("Flat", SHADE_FLAT);
Gareth Hughesc8516462001-01-06 20:38:03 +0000939 glutAddMenuEntry("", 0);
Keith Whitwell44c73931999-09-03 14:56:40 +0000940 glutAddMenuEntry("Fog", FOG);
941 glutAddMenuEntry("No Fog", NO_FOG);
Gareth Hughesc8516462001-01-06 20:38:03 +0000942 glutAddMenuEntry("", 0);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000943 glutAddMenuEntry("Stipple", STIPPLE);
944 glutAddMenuEntry("No Stipple", NO_STIPPLE);
Gareth Hughesc8516462001-01-06 20:38:03 +0000945 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +0000946 glutAddMenuEntry("Point Filtered", POINT_FILTER);
947 glutAddMenuEntry("Linear Filtered", LINEAR_FILTER);
Gareth Hughesc8516462001-01-06 20:38:03 +0000948 glutAddMenuEntry("", 0);
949 glutAddMenuEntry("glVertex (TRIANGLES)", IMMEDIATE|GLVERTEX|TRIANGLES);
950 glutAddMenuEntry("glVertex (STRIPS)", IMMEDIATE|GLVERTEX|STRIPS);
951 glutAddMenuEntry("glVertex (POINTS)", IMMEDIATE|GLVERTEX|POINTS);
952 glutAddMenuEntry("", 0);
953 glutAddMenuEntry("glVertex display list (STRIPS)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000954 DISPLAYLIST|GLVERTEX|STRIPS);
Gareth Hughesc8516462001-01-06 20:38:03 +0000955 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +0000956 if (allowed & DRAW_ARRAYS) {
Gareth Hughesc8516462001-01-06 20:38:03 +0000957 glutAddMenuEntry("DrawElements (TRIANGLES)",
958 IMMEDIATE|DRAW_ARRAYS|TRIANGLES);
jtgafb833d1999-08-19 00:55:39 +0000959 glutAddMenuEntry("DrawArrays (STRIPS)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000960 IMMEDIATE|DRAW_ARRAYS|STRIPS);
Gareth Hughesc8516462001-01-06 20:38:03 +0000961 glutAddMenuEntry("DrawArrays (POINTS)",
962 IMMEDIATE|DRAW_ARRAYS|POINTS);
963 glutAddMenuEntry("ArrayElement (TRIANGLES)",
Keith Whitwell44c73931999-09-03 14:56:40 +0000964 IMMEDIATE|ARRAY_ELT|TRIANGLES);
Gareth Hughesc8516462001-01-06 20:38:03 +0000965 glutAddMenuEntry("ArrayElement (STRIPS)",
966 IMMEDIATE|ARRAY_ELT|STRIPS);
967 glutAddMenuEntry("ArrayElement (POINTS)",
968 IMMEDIATE|ARRAY_ELT|POINTS);
969 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +0000970
971 }
972 if (allowed & COMPILED) {
Gareth Hughesc8516462001-01-06 20:38:03 +0000973 glutAddMenuEntry("Compiled DrawElements (TRIANGLES)",
jtgafb833d1999-08-19 00:55:39 +0000974 COMPILED|DRAW_ARRAYS|TRIANGLES);
Gareth Hughesc8516462001-01-06 20:38:03 +0000975 glutAddMenuEntry("Compiled DrawElements (STRIPS)",
jtgafb833d1999-08-19 00:55:39 +0000976 COMPILED|DRAW_ARRAYS|STRIPS);
Gareth Hughesc8516462001-01-06 20:38:03 +0000977 glutAddMenuEntry("Compiled DrawElements (POINTS)",
978 COMPILED|DRAW_ARRAYS|POINTS);
979 glutAddMenuEntry("Compiled ArrayElement (TRIANGLES)",
980 COMPILED|ARRAY_ELT|TRIANGLES);
981 glutAddMenuEntry("Compiled ArrayElement (STRIPS)",
982 COMPILED|ARRAY_ELT|STRIPS);
983 glutAddMenuEntry("Compiled ArrayElement (POINTS)",
984 COMPILED|ARRAY_ELT|POINTS);
985 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +0000986 }
987 glutAddMenuEntry("Quit", QUIT);
988 glutAttachMenu(GLUT_RIGHT_BUTTON);
989
990 glutReshapeFunc(Reshape);
991 glutKeyboardFunc(Key);
992 glutSpecialFunc(SpecialKey);
993 glutDisplayFunc(Display);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000994
jtgafb833d1999-08-19 00:55:39 +0000995 glutMainLoop();
996 return 0;
997}