blob: 1ee738d17a293b8ba25a9e6af5b77eef0668b7a0 [file] [log] [blame]
jtgafb833d1999-08-19 00:55:39 +00001
2/*
Gareth Hughesc8516462001-01-06 20:38:03 +00003 * Display an isosurface of 3-D wind speed volume.
Keith Whitwell44c73931999-09-03 14:56:40 +00004 *
Brian Paulac126091999-10-21 16:39:06 +00005 * Command line options:
6 * -info print GL implementation information
7 *
jtgafb833d1999-08-19 00:55:39 +00008 * Brian Paul This file in public domain.
9 */
10
Keith Whitwell44c73931999-09-03 14:56:40 +000011
12/* Keys:
13 * =====
14 *
15 * - Arrow keys to rotate
16 * - 's' toggles smooth shading
17 * - 'l' toggles lighting
18 * - 'f' toggles fog
19 * - 'I' and 'i' zoom in and out
20 * - 'c' toggles a user clip plane
21 * - 'm' toggles colorful materials in GL_TRIANGLES modes.
22 * - '+' and '-' move the user clip plane
23 *
24 * Other options are available via the popup menu.
25 */
26
jtgafb833d1999-08-19 00:55:39 +000027#include <stdio.h>
28#include <string.h>
29#include <stdlib.h>
Brian Paulac126091999-10-21 16:39:06 +000030#include <string.h>
jtgafb833d1999-08-19 00:55:39 +000031#include <math.h>
Karl Schultzbffae582001-10-04 19:14:26 +000032#ifdef _WIN32
33#include <windows.h>
Karl Schultz53d30c52002-10-18 17:47:35 +000034#undef CLIP_MASK
Karl Schultzbffae582001-10-04 19:14:26 +000035#endif
Brian Paul02e8a032000-06-27 17:04:43 +000036#define GL_GLEXT_LEGACY
jtgafb833d1999-08-19 00:55:39 +000037#include "GL/glut.h"
Jouk Jansen054b5ae2003-09-05 09:37:32 +000038#include "GL/glext.h"
jtgafb833d1999-08-19 00:55:39 +000039
pescod1ff1f62000-12-24 22:53:54 +000040#include "readtex.c" /* I know, this is a hack. KW: me too. */
jtgafb833d1999-08-19 00:55:39 +000041#define TEXTURE_FILE "../images/reflect.rgb"
42
Gareth Hughes735d9202002-01-04 09:47:17 +000043#define LIT 0x00000001
44#define UNLIT 0x00000002
45#define REFLECT 0x00000004
46#define POINT_FILTER 0x00000008
47#define LINEAR_FILTER 0x00000010
48#define GLVERTEX 0x00000020
49#define DRAW_ELTS 0x00000040
50#define DRAW_ARRAYS 0x00000080
51#define ARRAY_ELT 0x00000100
52#define LOCKED 0x00000200
53#define UNLOCKED 0x00000400
54#define IMMEDIATE 0x00000800
55#define DISPLAYLIST 0x00001000
56#define SHADE_SMOOTH 0x00002000
57#define SHADE_FLAT 0x00004000
58#define TRIANGLES 0x00008000
59#define STRIPS 0x00010000
60#define POINTS 0x00020000
61#define USER_CLIP 0x00040000
62#define NO_USER_CLIP 0x00080000
63#define MATERIALS 0x00100000
64#define NO_MATERIALS 0x00200000
65#define FOG 0x00400000
66#define NO_FOG 0x00800000
67#define QUIT 0x01000000
68#define GLINFO 0x02000000
69#define STIPPLE 0x04000000
70#define NO_STIPPLE 0x08000000
71#define POLYGON_FILL 0x10000000
72#define POLYGON_LINE 0x20000000
jtgafb833d1999-08-19 00:55:39 +000073
Keith Whitwell5759f532001-05-11 12:08:15 +000074#define LIGHT_MASK (LIT|UNLIT|REFLECT)
Gareth Hughesc8516462001-01-06 20:38:03 +000075#define FILTER_MASK (POINT_FILTER|LINEAR_FILTER)
Keith Whitwell5759f532001-05-11 12:08:15 +000076#define RENDER_STYLE_MASK (GLVERTEX|DRAW_ARRAYS|DRAW_ELTS|ARRAY_ELT)
77#define DLIST_MASK (IMMEDIATE|DISPLAYLIST)
78#define LOCK_MASK (LOCKED|UNLOCKED)
Gareth Hughesc8516462001-01-06 20:38:03 +000079#define MATERIAL_MASK (MATERIALS|NO_MATERIALS)
80#define PRIMITIVE_MASK (TRIANGLES|STRIPS|POINTS)
81#define CLIP_MASK (USER_CLIP|NO_USER_CLIP)
82#define SHADE_MASK (SHADE_SMOOTH|SHADE_FLAT)
83#define FOG_MASK (FOG|NO_FOG)
84#define STIPPLE_MASK (STIPPLE|NO_STIPPLE)
Gareth Hughes735d9202002-01-04 09:47:17 +000085#define POLYGON_MASK (POLYGON_FILL|POLYGON_LINE)
jtgafb833d1999-08-19 00:55:39 +000086
87#define MAXVERTS 10000
Karl Schultz53d30c52002-10-18 17:47:35 +000088static GLint maxverts = MAXVERTS;
jtgafb833d1999-08-19 00:55:39 +000089static float data[MAXVERTS][6];
90static float compressed_data[MAXVERTS][6];
Keith Whitwell5759f532001-05-11 12:08:15 +000091static float expanded_data[MAXVERTS*3][6];
jtgafb833d1999-08-19 00:55:39 +000092static GLuint indices[MAXVERTS];
93static GLuint tri_indices[MAXVERTS*3];
Keith Whitwellb8f99802001-05-11 15:47:02 +000094static GLuint strip_indices[MAXVERTS];
jtgafb833d1999-08-19 00:55:39 +000095static GLfloat col[100][4];
96static GLint numverts, num_tri_verts, numuniq;
97
98static GLfloat xrot;
99static GLfloat yrot;
Keith Whitwell5759f532001-05-11 12:08:15 +0000100static GLfloat dist;
jtgafb833d1999-08-19 00:55:39 +0000101static GLint state, allowed = ~0;
102static GLboolean doubleBuffer = GL_TRUE;
Keith Whitwell5759f532001-05-11 12:08:15 +0000103static GLdouble plane[4];
104static GLuint surf1, dlist_state;
jtgafb833d1999-08-19 00:55:39 +0000105
Brian Paulac126091999-10-21 16:39:06 +0000106static GLboolean PrintInfo = GL_FALSE;
107
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000108
109static GLubyte halftone[] = {
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, 0xAA, 0xAA, 0xAA, 0xAA,
113 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
114 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
115 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
116 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
117 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
118 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA,
119 0x55, 0x55, 0x55, 0x55, 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55,
120 0xAA, 0xAA, 0xAA, 0xAA, 0x55, 0x55, 0x55, 0x55};
121
Brian Paul36ca6bd1999-09-08 22:14:31 +0000122
jtgafb833d1999-08-19 00:55:39 +0000123static void read_surface( char *filename )
124{
125 FILE *f;
126
127 f = fopen(filename,"r");
128 if (!f) {
129 printf("couldn't read %s\n", filename);
130 exit(1);
131 }
132
133 numverts = 0;
Keith Whitwell18acf6e2001-04-19 13:12:40 +0000134 while (!feof(f) && numverts<maxverts) {
jtgafb833d1999-08-19 00:55:39 +0000135 fscanf( f, "%f %f %f %f %f %f",
136 &data[numverts][0], &data[numverts][1], &data[numverts][2],
137 &data[numverts][3], &data[numverts][4], &data[numverts][5] );
138 numverts++;
139 }
140 numverts--;
141
142 printf("%d vertices, %d triangles\n", numverts, numverts-2);
143 fclose(f);
144}
145
146
147
Keith Whitwell5759f532001-05-11 12:08:15 +0000148static void print_flags( const char *msg, GLuint flags )
149{
150 fprintf(stderr,
Gareth Hughes735d9202002-01-04 09:47:17 +0000151 "%s (0x%x): %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
Keith Whitwell5759f532001-05-11 12:08:15 +0000152 msg, flags,
153 (flags & GLVERTEX) ? "glVertex, " : "",
154 (flags & DRAW_ARRAYS) ? "glDrawArrays, " : "",
155 (flags & DRAW_ELTS) ? "glDrawElements, " : "",
156 (flags & ARRAY_ELT) ? "glArrayElement, " : "",
157 (flags & LOCKED) ? "locked arrays, " : "",
158 (flags & TRIANGLES) ? "GL_TRIANGLES, " : "",
159 (flags & STRIPS) ? "GL_TRIANGLE_STRIP, " : "",
160 (flags & POINTS) ? "GL_POINTS, " : "",
161 (flags & DISPLAYLIST) ? "as a displaylist, " : "",
162 (flags & LIT) ? "lit, " : "",
163 (flags & UNLIT) ? "unlit, " : "",
164 (flags & REFLECT) ? "reflect, " : "",
165 (flags & SHADE_FLAT) ? "flat-shaded, " : "",
166 (flags & USER_CLIP) ? "user_clip, " : "",
167 (flags & MATERIALS) ? "materials, " : "",
168 (flags & FOG) ? "fog, " : "",
Gareth Hughes735d9202002-01-04 09:47:17 +0000169 (flags & STIPPLE) ? "stipple, " : "",
170 (flags & POLYGON_LINE) ? "polygon mode line, " : "");
Keith Whitwell5759f532001-05-11 12:08:15 +0000171}
172
173
jtgafb833d1999-08-19 00:55:39 +0000174
175struct data_idx {
176 float *data;
177 int idx;
178 int uniq_idx;
179};
180
181
182#define COMPARE_FUNC( AXIS ) \
Brian Paulac126091999-10-21 16:39:06 +0000183static int compare_axis_##AXIS( const void *a, const void *b ) \
jtgafb833d1999-08-19 00:55:39 +0000184{ \
185 float t = ( (*(struct data_idx *)a).data[AXIS] - \
186 (*(struct data_idx *)b).data[AXIS] ); \
187 \
188 if (t < 0) return -1; \
189 if (t > 0) return 1; \
190 return 0; \
191}
192
193COMPARE_FUNC(0)
194COMPARE_FUNC(1)
195COMPARE_FUNC(2)
196COMPARE_FUNC(3)
197COMPARE_FUNC(4)
198COMPARE_FUNC(5)
199COMPARE_FUNC(6)
200
201int (*(compare[7]))( const void *a, const void *b ) =
202{
203 compare_axis_0,
204 compare_axis_1,
205 compare_axis_2,
206 compare_axis_3,
207 compare_axis_4,
208 compare_axis_5,
209 compare_axis_6,
210};
211
212
213#define VEC_ELT(f, s, i) (float *)(((char *)f) + s * i)
214
Gareth Hughesc8516462001-01-06 20:38:03 +0000215static int sort_axis( int axis,
jtgafb833d1999-08-19 00:55:39 +0000216 int vec_size,
217 int vec_stride,
218 struct data_idx *indices,
219 int start,
220 int finish,
221 float *out,
222 int uniq,
223 const float fudge )
224{
225 int i;
226
Gareth Hughesc8516462001-01-06 20:38:03 +0000227 if (finish-start > 2)
jtgafb833d1999-08-19 00:55:39 +0000228 {
229 qsort( indices+start, finish-start, sizeof(*indices), compare[axis] );
Gareth Hughesc8516462001-01-06 20:38:03 +0000230 }
231 else if (indices[start].data[axis] > indices[start+1].data[axis])
jtgafb833d1999-08-19 00:55:39 +0000232 {
233 struct data_idx tmp = indices[start];
234 indices[start] = indices[start+1];
235 indices[start+1] = tmp;
236 }
Gareth Hughesc8516462001-01-06 20:38:03 +0000237
jtgafb833d1999-08-19 00:55:39 +0000238 if (axis == vec_size-1) {
239 for (i = start ; i < finish ; ) {
240 float max = indices[i].data[axis] + fudge;
241 float *dest = VEC_ELT(out, vec_stride, uniq);
242 int j;
Gareth Hughesc8516462001-01-06 20:38:03 +0000243
jtgafb833d1999-08-19 00:55:39 +0000244 for (j = 0 ; j < vec_size ; j++)
245 dest[j] = indices[i].data[j];
246
Gareth Hughesc8516462001-01-06 20:38:03 +0000247 for ( ; i < finish && max >= indices[i].data[axis]; i++)
jtgafb833d1999-08-19 00:55:39 +0000248 indices[i].uniq_idx = uniq;
249
250 uniq++;
251 }
252 } else {
253 for (i = start ; i < finish ; ) {
254 int j = i + 1;
255 float max = indices[i].data[axis] + fudge;
256 while (j < finish && max >= indices[j].data[axis]) j++;
257 if (j == i+1) {
258 float *dest = VEC_ELT(out, vec_stride, uniq);
259 int k;
260
261 indices[i].uniq_idx = uniq;
Gareth Hughesc8516462001-01-06 20:38:03 +0000262
jtgafb833d1999-08-19 00:55:39 +0000263 for (k = 0 ; k < vec_size ; k++)
264 dest[k] = indices[i].data[k];
265
266 uniq++;
267 } else {
268 uniq = sort_axis( axis+1, vec_size, vec_stride,
269 indices, i, j, out, uniq, fudge );
270 }
271 i = j;
272 }
273 }
274
275 return uniq;
276}
277
278
Gareth Hughesc8516462001-01-06 20:38:03 +0000279static void extract_indices1( const struct data_idx *in, unsigned int *out,
jtgafb833d1999-08-19 00:55:39 +0000280 int n )
281{
282 int i;
283 for ( i = 0 ; i < n ; i++ ) {
284 out[in[i].idx] = in[i].uniq_idx;
285 }
286}
287
288
Brian Paul36ca6bd1999-09-08 22:14:31 +0000289static void compactify_arrays(void)
jtgafb833d1999-08-19 00:55:39 +0000290{
291 int i;
292 struct data_idx *ind;
293
294 ind = (struct data_idx *) malloc( sizeof(struct data_idx) * numverts );
295
296 for (i = 0 ; i < numverts ; i++) {
297 ind[i].idx = i;
298 ind[i].data = data[i];
299 }
300
Gareth Hughesc8516462001-01-06 20:38:03 +0000301 numuniq = sort_axis(0,
302 sizeof(compressed_data[0])/sizeof(float),
jtgafb833d1999-08-19 00:55:39 +0000303 sizeof(compressed_data[0]),
Gareth Hughesc8516462001-01-06 20:38:03 +0000304 ind,
305 0,
306 numverts,
307 (float *)compressed_data,
jtgafb833d1999-08-19 00:55:39 +0000308 0,
309 1e-6);
310
311 printf("Nr unique vertex/normal pairs: %d\n", numuniq);
312
313 extract_indices1( ind, indices, numverts );
314 free( ind );
315}
316
Keith Whitwell5759f532001-05-11 12:08:15 +0000317static void expand_arrays(void)
318{
319 int i;
320 int parity = 0;
321 for (i = 2 ; i < numverts ; i++, parity ^= 1) {
322 int v0 = i-2+parity;
323 int v1 = i-1-parity;
324 int v2 = i;
325 memcpy( expanded_data[(i-2)*3+0], data[v0], sizeof(data[0]) );
326 memcpy( expanded_data[(i-2)*3+1], data[v1], sizeof(data[0]) );
327 memcpy( expanded_data[(i-2)*3+2], data[v2], sizeof(data[0]) );
328 }
329}
330
jtgafb833d1999-08-19 00:55:39 +0000331static float myrand( float max )
332{
333 return max*rand()/(RAND_MAX+1.0);
334}
335
336
337static void make_tri_indices( void )
338{
339 unsigned int *v = tri_indices;
340 unsigned int parity = 0;
Karl Schultz53d30c52002-10-18 17:47:35 +0000341 int i, j;
jtgafb833d1999-08-19 00:55:39 +0000342
343 for (j=2;j<numverts;j++,parity^=1) {
344 if (parity) {
345 *v++ = indices[j-1];
Gareth Hughesc8516462001-01-06 20:38:03 +0000346 *v++ = indices[j-2];
jtgafb833d1999-08-19 00:55:39 +0000347 *v++ = indices[j];
348 } else {
349 *v++ = indices[j-2];
350 *v++ = indices[j-1];
351 *v++ = indices[j];
352 }
353 }
Gareth Hughesc8516462001-01-06 20:38:03 +0000354
jtgafb833d1999-08-19 00:55:39 +0000355 num_tri_verts = v - tri_indices;
356 printf("num_tri_verts: %d\n", num_tri_verts);
357
358 for (i = j = 0 ; i < num_tri_verts ; i += 600, j++) {
359 col[j][3] = 1;
360 col[j][2] = myrand(1);
361 col[j][1] = myrand(1);
362 col[j][0] = myrand(1);
363 }
Keith Whitwellb8f99802001-05-11 15:47:02 +0000364
365 for (i = 0; i < numverts ; i++)
366 strip_indices[i] = i;
jtgafb833d1999-08-19 00:55:39 +0000367}
368
369#define MIN(x,y) (x < y) ? x : y
370
Karl Schultz53d30c52002-10-18 17:47:35 +0000371static void draw_surface( unsigned int with_state )
jtgafb833d1999-08-19 00:55:39 +0000372{
Karl Schultz53d30c52002-10-18 17:47:35 +0000373 GLint i, j;
Keith Whitwell5759f532001-05-11 12:08:15 +0000374
375 if (with_state & DISPLAYLIST) {
376 if ((with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK|MATERIAL_MASK)) !=
377 dlist_state) {
378 /*
379 */
380 fprintf(stderr, "rebuilding displaylist\n");
jtgafb833d1999-08-19 00:55:39 +0000381
Keith Whitwell5759f532001-05-11 12:08:15 +0000382 if (dlist_state)
383 glDeleteLists( surf1, 1 );
384
385 dlist_state = with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK|
386 MATERIAL_MASK);
387 surf1 = glGenLists(1);
388 glNewList(surf1, GL_COMPILE);
389 draw_surface( dlist_state );
390 glEndList();
391 }
392
393 glCallList( surf1 );
394 return;
395 }
396
397 switch (with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK)) {
jtgafb833d1999-08-19 00:55:39 +0000398#ifdef GL_EXT_vertex_array
399
Keith Whitwell5759f532001-05-11 12:08:15 +0000400 case (DRAW_ELTS|TRIANGLES):
Keith Whitwell44c73931999-09-03 14:56:40 +0000401 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000402 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
403 GLuint nr = MIN(num_tri_verts-i, 600);
404 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
405 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
406 glDrawElements( GL_TRIANGLES, nr, GL_UNSIGNED_INT, tri_indices+i );
407 }
408 } else {
Gareth Hughesc8516462001-01-06 20:38:03 +0000409 glDrawElements( GL_TRIANGLES, num_tri_verts, GL_UNSIGNED_INT,
jtgafb833d1999-08-19 00:55:39 +0000410 tri_indices );
411 }
jtgafb833d1999-08-19 00:55:39 +0000412 break;
413
Keith Whitwell5759f532001-05-11 12:08:15 +0000414 case (DRAW_ARRAYS|TRIANGLES):
415 glDrawArraysEXT( GL_TRIANGLES, 0, (numverts-2)*3 );
416 break;
417
418 case (ARRAY_ELT|TRIANGLES):
Keith Whitwell44c73931999-09-03 14:56:40 +0000419 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000420 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
421 GLuint nr = MIN(num_tri_verts-i, 600);
422 GLuint k;
423 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
424 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
425 glBegin( GL_TRIANGLES );
426 for (k = 0 ; k < nr ; k++)
427 glArrayElement( tri_indices[i+k] );
428 glEnd();
429 }
430 } else {
431 glBegin( GL_TRIANGLES );
432 for (i = 0 ; i < num_tri_verts ; i++)
433 glArrayElement( tri_indices[i] );
Gareth Hughesc8516462001-01-06 20:38:03 +0000434
jtgafb833d1999-08-19 00:55:39 +0000435 glEnd();
Gareth Hughesc8516462001-01-06 20:38:03 +0000436 }
jtgafb833d1999-08-19 00:55:39 +0000437 break;
438
Gareth Hughesc8516462001-01-06 20:38:03 +0000439
440 /* Uses the original arrays (including duplicate elements):
441 */
Keith Whitwell5759f532001-05-11 12:08:15 +0000442 case (DRAW_ARRAYS|STRIPS):
Gareth Hughesc8516462001-01-06 20:38:03 +0000443 glDrawArraysEXT( GL_TRIANGLE_STRIP, 0, numverts );
444 break;
Keith Whitwell5759f532001-05-11 12:08:15 +0000445 case (DRAW_ELTS|STRIPS):
Keith Whitwellb8f99802001-05-11 15:47:02 +0000446 glDrawElements( GL_TRIANGLE_STRIP, numverts,
447 GL_UNSIGNED_INT, strip_indices );
Gareth Hughesc8516462001-01-06 20:38:03 +0000448 break;
449
450 /* Uses the original arrays (including duplicate elements):
451 */
Keith Whitwell5759f532001-05-11 12:08:15 +0000452 case (ARRAY_ELT|STRIPS):
Gareth Hughesc8516462001-01-06 20:38:03 +0000453 glBegin( GL_TRIANGLE_STRIP );
454 for (i = 0 ; i < numverts ; i++)
455 glArrayElement( i );
456 glEnd();
457 break;
458
Keith Whitwell5759f532001-05-11 12:08:15 +0000459 case (DRAW_ARRAYS|POINTS):
Keith Whitwellabd51342001-06-04 15:34:31 +0000460 glDrawArraysEXT( GL_POINTS, 0, numuniq );
Gareth Hughesc8516462001-01-06 20:38:03 +0000461 break;
Keith Whitwell5759f532001-05-11 12:08:15 +0000462 case (DRAW_ELTS|POINTS):
Keith Whitwellabd51342001-06-04 15:34:31 +0000463 /* can use numuniq with strip_indices as strip_indices[i] == i.
464 */
465 glDrawElements( GL_POINTS, numuniq,
466 GL_UNSIGNED_INT, strip_indices );
Gareth Hughesc8516462001-01-06 20:38:03 +0000467 break;
Keith Whitwell5759f532001-05-11 12:08:15 +0000468 case (ARRAY_ELT|POINTS):
Keith Whitwellabd51342001-06-04 15:34:31 +0000469 /* just emit each unique element once:
470 */
Gareth Hughesc8516462001-01-06 20:38:03 +0000471 glBegin( GL_POINTS );
Keith Whitwellabd51342001-06-04 15:34:31 +0000472 for (i = 0 ; i < numuniq ; i++)
473 glArrayElement( i );
Gareth Hughesc8516462001-01-06 20:38:03 +0000474 glEnd();
475 break;
476#endif
477
Keith Whitwell5759f532001-05-11 12:08:15 +0000478 case (GLVERTEX|TRIANGLES):
Keith Whitwell44c73931999-09-03 14:56:40 +0000479 if (with_state & MATERIALS) {
jtgafb833d1999-08-19 00:55:39 +0000480 for (j = i = 0 ; i < num_tri_verts ; i += 600, j++) {
481 GLuint nr = MIN(num_tri_verts-i, 600);
482 GLuint k;
483 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, col[j]);
484 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, col[j]);
485 glBegin( GL_TRIANGLES );
486 for (k = 0 ; k < nr ; k++) {
487 glNormal3fv( &compressed_data[tri_indices[i+k]][3] );
488 glVertex3fv( &compressed_data[tri_indices[i+k]][0] );
489 }
490 glEnd();
491 }
492 } else {
493 glBegin( GL_TRIANGLES );
494 for (i = 0 ; i < num_tri_verts ; i++) {
495 glNormal3fv( &compressed_data[tri_indices[i]][3] );
496 glVertex3fv( &compressed_data[tri_indices[i]][0] );
497 }
498 glEnd();
Gareth Hughesc8516462001-01-06 20:38:03 +0000499 }
jtgafb833d1999-08-19 00:55:39 +0000500 break;
501
Keith Whitwell5759f532001-05-11 12:08:15 +0000502 case (GLVERTEX|POINTS):
Keith Whitwellabd51342001-06-04 15:34:31 +0000503 /* Renders all points, but not in strip order... Shouldn't be a
504 * problem, but people may be confused as to why points are so
505 * much faster in this demo... And why cva doesn't help them...
506 */
Gareth Hughesc8516462001-01-06 20:38:03 +0000507 glBegin( GL_POINTS );
Keith Whitwellabd51342001-06-04 15:34:31 +0000508 for ( i = 0 ; i < numuniq ; i++ ) {
509 glNormal3fv( &compressed_data[i][3] );
510 glVertex3fv( &compressed_data[i][0] );
Gareth Hughesc8516462001-01-06 20:38:03 +0000511 }
512 glEnd();
Keith Whitwell44c73931999-09-03 14:56:40 +0000513 break;
514
Keith Whitwell5759f532001-05-11 12:08:15 +0000515 case (GLVERTEX|STRIPS):
jtgafb833d1999-08-19 00:55:39 +0000516 glBegin( GL_TRIANGLE_STRIP );
517 for (i=0;i<numverts;i++) {
518 glNormal3fv( &data[i][3] );
519 glVertex3fv( &data[i][0] );
520 }
521 glEnd();
Keith Whitwell5759f532001-05-11 12:08:15 +0000522 break;
523
524 default:
525 fprintf(stderr, "unimplemented mode %x...\n",
526 (with_state & (RENDER_STYLE_MASK|PRIMITIVE_MASK)));
527 break;
jtgafb833d1999-08-19 00:55:39 +0000528 }
529}
530
531
532
533static void Display(void)
534{
535 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Keith Whitwell44c73931999-09-03 14:56:40 +0000536 draw_surface( state );
jtgafb833d1999-08-19 00:55:39 +0000537 glFlush();
Gareth Hughesc8516462001-01-06 20:38:03 +0000538 if (doubleBuffer) glutSwapBuffers();
jtgafb833d1999-08-19 00:55:39 +0000539}
540
Keith Whitwell18acf6e2001-04-19 13:12:40 +0000541
jtgafb833d1999-08-19 00:55:39 +0000542/* KW: only do this when necessary, so CVA can re-use results.
543 */
544static void set_matrix( void )
545{
546 glMatrixMode(GL_MODELVIEW);
547 glLoadIdentity();
Keith Whitwell44c73931999-09-03 14:56:40 +0000548 glTranslatef( 0.0, 0.0, dist );
jtgafb833d1999-08-19 00:55:39 +0000549 glRotatef( yrot, 0.0, 1.0, 0.0 );
550 glRotatef( xrot, 1.0, 0.0, 0.0 );
551}
552
553static void Benchmark( float xdiff, float ydiff )
554{
555 int startTime, endTime;
556 int draws;
557 double seconds, fps, triPerSecond;
558
559 printf("Benchmarking...\n");
560
561 draws = 0;
562 startTime = glutGet(GLUT_ELAPSED_TIME);
563 xrot = 0.0;
564 do {
565 xrot += xdiff;
566 yrot += ydiff;
567 set_matrix();
568 Display();
569 draws++;
570 endTime = glutGet(GLUT_ELAPSED_TIME);
571 } while (endTime - startTime < 5000); /* 5 seconds */
572
573 /* Results */
574 seconds = (double) (endTime - startTime) / 1000.0;
575 triPerSecond = (numverts - 2) * draws / seconds;
576 fps = draws / seconds;
577 printf("Result: triangles/sec: %g fps: %g\n", triPerSecond, fps);
578}
579
580
581static void InitMaterials(void)
582{
583 static float ambient[] = {0.1, 0.1, 0.1, 1.0};
584 static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
585 static float position0[] = {0.0, 0.0, 20.0, 0.0};
586 static float position1[] = {0.0, 0.0, -20.0, 0.0};
587 static float front_mat_shininess[] = {60.0};
588 static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
589 static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
590 /*
591 static float back_mat_shininess[] = {60.0};
592 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
593 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
594 */
595 static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
596 static float lmodel_twoside[] = {GL_FALSE};
597
598 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
599 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
600 glLightfv(GL_LIGHT0, GL_POSITION, position0);
601 glEnable(GL_LIGHT0);
Gareth Hughesc8516462001-01-06 20:38:03 +0000602
jtgafb833d1999-08-19 00:55:39 +0000603 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
604 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
605 glLightfv(GL_LIGHT1, GL_POSITION, position1);
606 glEnable(GL_LIGHT1);
Gareth Hughesc8516462001-01-06 20:38:03 +0000607
jtgafb833d1999-08-19 00:55:39 +0000608 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
609 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
610
611 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
612 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
613 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000614
615 glPolygonStipple (halftone);
jtgafb833d1999-08-19 00:55:39 +0000616}
617
618
619
620#define UPDATE(o,n,mask) (o&=~mask, o|=n&mask)
Keith Whitwell5759f532001-05-11 12:08:15 +0000621#define CHANGED(o,n,mask) ((n&mask) && (n&mask) != (o&mask) )
jtgafb833d1999-08-19 00:55:39 +0000622
623static void ModeMenu(int m)
624{
625 m &= allowed;
626
627 if (!m) return;
628
Gareth Hughesc8516462001-01-06 20:38:03 +0000629 if (m==QUIT)
jtgafb833d1999-08-19 00:55:39 +0000630 exit(0);
631
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000632 if (m==GLINFO) {
633 printf("GL_VERSION: %s\n", (char *) glGetString(GL_VERSION));
634 printf("GL_EXTENSIONS: %s\n", (char *) glGetString(GL_EXTENSIONS));
635 printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
636 return;
637 }
638
jtgafb833d1999-08-19 00:55:39 +0000639 if (CHANGED(state, m, FILTER_MASK)) {
Keith Whitwell5759f532001-05-11 12:08:15 +0000640 UPDATE(state, m, FILTER_MASK);
jtgafb833d1999-08-19 00:55:39 +0000641 if (m & LINEAR_FILTER) {
642 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
643 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
644 } else {
645 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
646 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
647 }
648 }
649
650 if (CHANGED(state, m, LIGHT_MASK)) {
Keith Whitwell5759f532001-05-11 12:08:15 +0000651 UPDATE(state, m, LIGHT_MASK);
652 if (m & LIT) {
jtgafb833d1999-08-19 00:55:39 +0000653 glEnable(GL_LIGHTING);
Keith Whitwell5759f532001-05-11 12:08:15 +0000654 glDisable(GL_TEXTURE_GEN_S);
655 glDisable(GL_TEXTURE_GEN_T);
656 glDisable(GL_TEXTURE_2D);
657 }
658 else if (m & UNLIT) {
jtgafb833d1999-08-19 00:55:39 +0000659 glDisable(GL_LIGHTING);
Keith Whitwell5759f532001-05-11 12:08:15 +0000660 glDisable(GL_TEXTURE_GEN_S);
661 glDisable(GL_TEXTURE_GEN_T);
662 glDisable(GL_TEXTURE_2D);
663 }
664 else if (m & REFLECT) {
665 glDisable(GL_LIGHTING);
666 glEnable(GL_TEXTURE_GEN_S);
667 glEnable(GL_TEXTURE_GEN_T);
668 glEnable(GL_TEXTURE_2D);
669 }
jtgafb833d1999-08-19 00:55:39 +0000670 }
671
672 if (CHANGED(state, m, SHADE_MASK)) {
Keith Whitwell5759f532001-05-11 12:08:15 +0000673 UPDATE(state, m, SHADE_MASK);
jtgafb833d1999-08-19 00:55:39 +0000674 if (m & SHADE_SMOOTH)
675 glShadeModel(GL_SMOOTH);
676 else
677 glShadeModel(GL_FLAT);
678 }
679
680
jtgafb833d1999-08-19 00:55:39 +0000681 if (CHANGED(state, m, CLIP_MASK)) {
Keith Whitwell5759f532001-05-11 12:08:15 +0000682 UPDATE(state, m, CLIP_MASK);
jtgafb833d1999-08-19 00:55:39 +0000683 if (m & USER_CLIP) {
684 glEnable(GL_CLIP_PLANE0);
685 } else {
686 glDisable(GL_CLIP_PLANE0);
687 }
688 }
689
Keith Whitwell44c73931999-09-03 14:56:40 +0000690 if (CHANGED(state, m, FOG_MASK)) {
Keith Whitwell5759f532001-05-11 12:08:15 +0000691 UPDATE(state, m, FOG_MASK);
Gareth Hughes735d9202002-01-04 09:47:17 +0000692 if (m & FOG) {
Keith Whitwell44c73931999-09-03 14:56:40 +0000693 glEnable(GL_FOG);
Gareth Hughesc8516462001-01-06 20:38:03 +0000694 }
Gareth Hughes735d9202002-01-04 09:47:17 +0000695 else {
Keith Whitwell44c73931999-09-03 14:56:40 +0000696 glDisable(GL_FOG);
Keith Whitwell44c73931999-09-03 14:56:40 +0000697 }
698 }
699
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000700 if (CHANGED(state, m, STIPPLE_MASK)) {
Keith Whitwell5759f532001-05-11 12:08:15 +0000701 UPDATE(state, m, STIPPLE_MASK);
Gareth Hughes735d9202002-01-04 09:47:17 +0000702 if (m & STIPPLE) {
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000703 glEnable(GL_POLYGON_STIPPLE);
Gareth Hughesc8516462001-01-06 20:38:03 +0000704 }
Gareth Hughes735d9202002-01-04 09:47:17 +0000705 else {
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000706 glDisable(GL_POLYGON_STIPPLE);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000707 }
708 }
709
Gareth Hughes735d9202002-01-04 09:47:17 +0000710 if (CHANGED(state, m, POLYGON_MASK)) {
711 UPDATE(state, m, POLYGON_MASK);
712 if (m & POLYGON_FILL) {
713 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
714 }
715 else {
716 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
717 }
718 }
719
jtgafb833d1999-08-19 00:55:39 +0000720#ifdef GL_EXT_vertex_array
Keith Whitwell5759f532001-05-11 12:08:15 +0000721 if (CHANGED(state, m, (LOCK_MASK|RENDER_STYLE_MASK|PRIMITIVE_MASK)))
jtgafb833d1999-08-19 00:55:39 +0000722 {
Keith Whitwell5759f532001-05-11 12:08:15 +0000723 if (m & (PRIMITIVE_MASK)) {
724 UPDATE(state, m, (PRIMITIVE_MASK));
725 }
726
727 if (m & (RENDER_STYLE_MASK)) {
728 UPDATE(state, m, (RENDER_STYLE_MASK));
729 }
730
731 if (m & LOCK_MASK) {
732 UPDATE(state, m, (LOCK_MASK));
733 }
734
735
736 print_flags("primitive", state & PRIMITIVE_MASK);
737 print_flags("render style", state & RENDER_STYLE_MASK);
738
Keith Whitwellabd51342001-06-04 15:34:31 +0000739 if ((state & PRIMITIVE_MASK) != STRIPS &&
740 ((state & RENDER_STYLE_MASK) == DRAW_ELTS ||
741 (state & RENDER_STYLE_MASK) == ARRAY_ELT ||
742 (state & PRIMITIVE_MASK) == POINTS))
jtgafb833d1999-08-19 00:55:39 +0000743 {
Keith Whitwell5759f532001-05-11 12:08:15 +0000744 fprintf(stderr, "enabling small arrays\n");
Keith Whitwellabd51342001-06-04 15:34:31 +0000745 /* Rendering any primitive with draw-element/array-element
746 * --> Can't do strips here as ordering has been lost in
747 * compaction process...
748 */
Gareth Hughesc8516462001-01-06 20:38:03 +0000749 glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numuniq,
jtgafb833d1999-08-19 00:55:39 +0000750 compressed_data );
Gareth Hughesc8516462001-01-06 20:38:03 +0000751 glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numuniq,
jtgafb833d1999-08-19 00:55:39 +0000752 &compressed_data[0][3]);
jtgafb833d1999-08-19 00:55:39 +0000753#ifdef GL_EXT_compiled_vertex_array
Keith Whitwell5759f532001-05-11 12:08:15 +0000754 if (allowed & LOCKED) {
755 if (state & LOCKED) {
756 glLockArraysEXT( 0, numuniq );
757 } else {
758 glUnlockArraysEXT();
759 }
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000760 }
jtgafb833d1999-08-19 00:55:39 +0000761#endif
Keith Whitwell5759f532001-05-11 12:08:15 +0000762 }
Keith Whitwellabd51342001-06-04 15:34:31 +0000763 else if ((state & PRIMITIVE_MASK) == TRIANGLES &&
764 (state & RENDER_STYLE_MASK) == DRAW_ARRAYS) {
Keith Whitwell5759f532001-05-11 12:08:15 +0000765 fprintf(stderr, "enabling big arrays\n");
Keith Whitwellabd51342001-06-04 15:34:31 +0000766 /* Only get here for TRIANGLES and drawarrays
Keith Whitwell5759f532001-05-11 12:08:15 +0000767 */
768 glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), (numverts-2) * 3,
769 expanded_data );
770 glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), (numverts-2) * 3,
771 &expanded_data[0][3]);
772
773#ifdef GL_EXT_compiled_vertex_array
774 if (allowed & LOCKED) {
775 if (state & LOCKED) {
776 glLockArraysEXT( 0, (numverts-2)*3 );
777 } else {
778 glUnlockArraysEXT();
779 }
780 }
781#endif
782 }
Keith Whitwellabd51342001-06-04 15:34:31 +0000783 else {
784 fprintf(stderr, "enabling normal arrays\n");
785 glVertexPointerEXT( 3, GL_FLOAT, sizeof(data[0]), numverts, data );
786 glNormalPointerEXT( GL_FLOAT, sizeof(data[0]), numverts, &data[0][3]);
787#ifdef GL_EXT_compiled_vertex_array
788 if (allowed & LOCKED) {
789 if (state & LOCKED) {
790 glLockArraysEXT( 0, numverts );
791 } else {
792 glUnlockArraysEXT();
793 }
794 }
795#endif
796 }
Keith Whitwell5759f532001-05-11 12:08:15 +0000797
jtgafb833d1999-08-19 00:55:39 +0000798 }
799#endif
800
Keith Whitwell5759f532001-05-11 12:08:15 +0000801
802 if (m & DLIST_MASK) {
803 UPDATE(state, m, DLIST_MASK);
jtgafb833d1999-08-19 00:55:39 +0000804 }
Gareth Hughesc8516462001-01-06 20:38:03 +0000805
jtgafb833d1999-08-19 00:55:39 +0000806 if (m & MATERIAL_MASK) {
807 UPDATE(state, m, MATERIAL_MASK);
808 }
809
Keith Whitwell5759f532001-05-11 12:08:15 +0000810 print_flags("new flags", state);
811
jtgafb833d1999-08-19 00:55:39 +0000812 glutPostRedisplay();
813}
814
815
816
Brian Paulac126091999-10-21 16:39:06 +0000817static void Init(int argc, char *argv[])
jtgafb833d1999-08-19 00:55:39 +0000818{
Keith Whitwell44c73931999-09-03 14:56:40 +0000819 GLfloat fogColor[4] = {0.5,1.0,0.5,1.0};
820
Keith Whitwell5759f532001-05-11 12:08:15 +0000821 xrot = 0;
822 yrot = 0;
823 dist = -6;
824 plane[0] = 1.0;
825 plane[1] = 0.0;
826 plane[2] = -1.0;
827 plane[3] = 0.0;
828
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000829 glClearColor(0.0, 0.0, 1.0, 0.0);
jtgafb833d1999-08-19 00:55:39 +0000830 glEnable( GL_DEPTH_TEST );
831 glEnable( GL_VERTEX_ARRAY_EXT );
832 glEnable( GL_NORMAL_ARRAY_EXT );
833
jtgafb833d1999-08-19 00:55:39 +0000834 glMatrixMode(GL_PROJECTION);
835 glLoadIdentity();
836 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
837
838 glMatrixMode(GL_MODELVIEW);
839 glLoadIdentity();
Gareth Hughesc8516462001-01-06 20:38:03 +0000840 glClipPlane(GL_CLIP_PLANE0, plane);
jtgafb833d1999-08-19 00:55:39 +0000841
Keith Whitwellb8f99802001-05-11 15:47:02 +0000842 InitMaterials();
843
jtgafb833d1999-08-19 00:55:39 +0000844 set_matrix();
845
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000846 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
jtgafb833d1999-08-19 00:55:39 +0000847 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
848
849 glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
850 glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
851
jtgafb833d1999-08-19 00:55:39 +0000852
Keith Whitwell44c73931999-09-03 14:56:40 +0000853 /* Green fog is easy to see */
854 glFogi(GL_FOG_MODE,GL_EXP2);
855 glFogfv(GL_FOG_COLOR,fogColor);
856 glFogf(GL_FOG_DENSITY,0.15);
857 glHint(GL_FOG_HINT,GL_DONT_CARE);
858
Keith Whitwell5759f532001-05-11 12:08:15 +0000859 {
860 static int firsttime = 1;
861 if (firsttime) {
862 firsttime = 0;
863 compactify_arrays();
864 expand_arrays();
865 make_tri_indices();
Keith Whitwell44c73931999-09-03 14:56:40 +0000866
Keith Whitwell5759f532001-05-11 12:08:15 +0000867 if (!LoadRGBMipmaps(TEXTURE_FILE, GL_RGB)) {
868 printf("Error: couldn't load texture image\n");
869 exit(1);
870 }
871 }
872 }
jtgafb833d1999-08-19 00:55:39 +0000873
874 ModeMenu(SHADE_SMOOTH|
875 LIT|
jtgafb833d1999-08-19 00:55:39 +0000876 POINT_FILTER|
jtgafb833d1999-08-19 00:55:39 +0000877 NO_USER_CLIP|
878 NO_MATERIALS|
Keith Whitwell44c73931999-09-03 14:56:40 +0000879 NO_FOG|
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000880 NO_STIPPLE|
Keith Whitwell5759f532001-05-11 12:08:15 +0000881 IMMEDIATE|
882 STRIPS|
883 UNLOCKED|
Keith Whitwell44c73931999-09-03 14:56:40 +0000884 GLVERTEX);
Brian Paulac126091999-10-21 16:39:06 +0000885
886 if (PrintInfo) {
887 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
888 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
889 printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
890 printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
891 }
jtgafb833d1999-08-19 00:55:39 +0000892}
893
894
895
896static void Reshape(int width, int height)
897{
898 glViewport(0, 0, (GLint)width, (GLint)height);
899}
900
901
902
903static void Key( unsigned char key, int x, int y )
904{
Brian Paul36ca6bd1999-09-08 22:14:31 +0000905 (void) x;
906 (void) y;
jtgafb833d1999-08-19 00:55:39 +0000907 switch (key) {
Keith Whitwell44c73931999-09-03 14:56:40 +0000908 case 27:
909 exit(0);
910 case 'f':
911 ModeMenu((state ^ FOG_MASK) & FOG_MASK);
912 break;
913 case 's':
914 ModeMenu((state ^ SHADE_MASK) & SHADE_MASK);
915 break;
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000916 case 't':
917 ModeMenu((state ^ STIPPLE_MASK) & STIPPLE_MASK);
918 break;
Keith Whitwell44c73931999-09-03 14:56:40 +0000919 case 'l':
Keith Whitwell5759f532001-05-11 12:08:15 +0000920 ModeMenu((state ^ LIGHT_MASK) & (LIT|UNLIT));
Keith Whitwell44c73931999-09-03 14:56:40 +0000921 break;
922 case 'm':
923 ModeMenu((state ^ MATERIAL_MASK) & MATERIAL_MASK);
924 break;
925 case 'c':
926 ModeMenu((state ^ CLIP_MASK) & CLIP_MASK);
927 break;
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000928 case 'v':
Keith Whitwell5759f532001-05-11 12:08:15 +0000929 ModeMenu((LOCKED|IMMEDIATE|DRAW_ELTS|TRIANGLES) & allowed);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000930 break;
931 case 'V':
Keith Whitwell5759f532001-05-11 12:08:15 +0000932 ModeMenu(UNLOCKED|IMMEDIATE|GLVERTEX|STRIPS);
Keith Whitwell03b7aee2000-03-30 17:58:56 +0000933 break;
Keith Whitwell44c73931999-09-03 14:56:40 +0000934 case 'b':
935 Benchmark(5.0, 0);
936 break;
937 case 'B':
938 Benchmark(0, 5.0);
939 break;
940 case 'i':
941 dist += .25;
942 set_matrix();
943 glutPostRedisplay();
944 break;
945 case 'I':
946 dist -= .25;
947 set_matrix();
948 glutPostRedisplay();
949 break;
950 case '-':
951 case '_':
952 plane[3] += 2.0;
953 glMatrixMode(GL_MODELVIEW);
954 glLoadIdentity();
955 glClipPlane(GL_CLIP_PLANE0, plane);
956 set_matrix();
957 glutPostRedisplay();
958 break;
959 case '+':
960 case '=':
961 plane[3] -= 2.0;
962 glMatrixMode(GL_MODELVIEW);
963 glLoadIdentity();
964 glClipPlane(GL_CLIP_PLANE0, plane);
965 set_matrix();
966 glutPostRedisplay();
967 break;
Keith Whitwell5759f532001-05-11 12:08:15 +0000968 case ' ':
969 Init(0,0);
970 break;
jtgafb833d1999-08-19 00:55:39 +0000971 }
972}
973
974
975static void SpecialKey( int key, int x, int y )
976{
Brian Paul36ca6bd1999-09-08 22:14:31 +0000977 (void) x;
978 (void) y;
jtgafb833d1999-08-19 00:55:39 +0000979 switch (key) {
980 case GLUT_KEY_LEFT:
981 yrot -= 15.0;
982 break;
983 case GLUT_KEY_RIGHT:
984 yrot += 15.0;
985 break;
986 case GLUT_KEY_UP:
987 xrot += 15.0;
988 break;
989 case GLUT_KEY_DOWN:
990 xrot -= 15.0;
991 break;
992 default:
993 return;
994 }
995 set_matrix();
996 glutPostRedisplay();
997}
998
999
1000
1001static GLint Args(int argc, char **argv)
1002{
1003 GLint i;
1004 GLint mode = 0;
1005
1006 for (i = 1; i < argc; i++) {
1007 if (strcmp(argv[i], "-sb") == 0) {
1008 doubleBuffer = GL_FALSE;
1009 }
1010 else if (strcmp(argv[i], "-db") == 0) {
1011 doubleBuffer = GL_TRUE;
1012 }
Brian Paulac126091999-10-21 16:39:06 +00001013 else if (strcmp(argv[i], "-info") == 0) {
1014 PrintInfo = GL_TRUE;
1015 }
Keith Whitwell18acf6e2001-04-19 13:12:40 +00001016 else if (strcmp(argv[i], "-10") == 0) {
1017 maxverts = 10;
1018 }
1019 else if (strcmp(argv[i], "-100") == 0) {
1020 maxverts = 100;
1021 }
1022 else if (strcmp(argv[i], "-1000") == 0) {
1023 maxverts = 1000;
1024 }
jtgafb833d1999-08-19 00:55:39 +00001025 else {
1026 printf("%s (Bad option).\n", argv[i]);
1027 return QUIT;
1028 }
1029 }
1030
1031 return mode;
1032}
1033
1034int main(int argc, char **argv)
1035{
1036 GLenum type;
1037 char *extensions;
1038
1039 GLuint arg_mode = Args(argc, argv);
1040
1041 if (arg_mode & QUIT)
1042 exit(0);
1043
1044 read_surface( "isosurf.dat" );
1045
1046 glutInitWindowPosition(0, 0);
1047 glutInitWindowSize(400, 400);
Gareth Hughesc8516462001-01-06 20:38:03 +00001048
jtgafb833d1999-08-19 00:55:39 +00001049 type = GLUT_DEPTH;
1050 type |= GLUT_RGB;
1051 type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
1052 glutInitDisplayMode(type);
1053
1054 if (glutCreateWindow("Isosurface") <= 0) {
1055 exit(0);
1056 }
1057
1058 /* Make sure server supports the vertex array extension */
1059 extensions = (char *) glGetString( GL_EXTENSIONS );
1060
Gareth Hughesc8516462001-01-06 20:38:03 +00001061 if (!strstr( extensions, "GL_EXT_vertex_array" ))
jtgafb833d1999-08-19 00:55:39 +00001062 {
1063 printf("Vertex arrays not supported by this renderer\n");
Keith Whitwell5759f532001-05-11 12:08:15 +00001064 allowed &= ~(LOCKED|DRAW_ARRAYS|DRAW_ELTS|ARRAY_ELT);
jtgafb833d1999-08-19 00:55:39 +00001065 }
Gareth Hughesc8516462001-01-06 20:38:03 +00001066 else if (!strstr( extensions, "GL_EXT_compiled_vertex_array" ))
jtgafb833d1999-08-19 00:55:39 +00001067 {
1068 printf("Compiled vertex arrays not supported by this renderer\n");
Keith Whitwell5759f532001-05-11 12:08:15 +00001069 allowed &= ~LOCKED;
jtgafb833d1999-08-19 00:55:39 +00001070 }
1071
Brian Paulac126091999-10-21 16:39:06 +00001072 Init(argc, argv);
jtgafb833d1999-08-19 00:55:39 +00001073 ModeMenu(arg_mode);
Gareth Hughesc8516462001-01-06 20:38:03 +00001074
jtgafb833d1999-08-19 00:55:39 +00001075 glutCreateMenu(ModeMenu);
Gareth Hughesc8516462001-01-06 20:38:03 +00001076 glutAddMenuEntry("GL info", GLINFO);
1077 glutAddMenuEntry("", 0);
Keith Whitwell5759f532001-05-11 12:08:15 +00001078 glutAddMenuEntry("Lit", LIT);
1079 glutAddMenuEntry("Unlit", UNLIT);
1080 glutAddMenuEntry("Reflect", REFLECT);
Gareth Hughesc8516462001-01-06 20:38:03 +00001081 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +00001082 glutAddMenuEntry("Smooth", SHADE_SMOOTH);
1083 glutAddMenuEntry("Flat", SHADE_FLAT);
Gareth Hughesc8516462001-01-06 20:38:03 +00001084 glutAddMenuEntry("", 0);
Keith Whitwell44c73931999-09-03 14:56:40 +00001085 glutAddMenuEntry("Fog", FOG);
1086 glutAddMenuEntry("No Fog", NO_FOG);
Gareth Hughesc8516462001-01-06 20:38:03 +00001087 glutAddMenuEntry("", 0);
Keith Whitwell03b7aee2000-03-30 17:58:56 +00001088 glutAddMenuEntry("Stipple", STIPPLE);
1089 glutAddMenuEntry("No Stipple", NO_STIPPLE);
Gareth Hughesc8516462001-01-06 20:38:03 +00001090 glutAddMenuEntry("", 0);
Gareth Hughes735d9202002-01-04 09:47:17 +00001091 glutAddMenuEntry("Polygon Mode Fill", POLYGON_FILL);
1092 glutAddMenuEntry("Polygon Mode Line", POLYGON_LINE);
1093 glutAddMenuEntry("", 0);
jtgafb833d1999-08-19 00:55:39 +00001094 glutAddMenuEntry("Point Filtered", POINT_FILTER);
1095 glutAddMenuEntry("Linear Filtered", LINEAR_FILTER);
Gareth Hughesc8516462001-01-06 20:38:03 +00001096 glutAddMenuEntry("", 0);
Keith Whitwell5759f532001-05-11 12:08:15 +00001097 glutAddMenuEntry("GL_TRIANGLES", TRIANGLES);
1098 glutAddMenuEntry("GL_TRIANGLE_STRIPS", STRIPS);
1099 glutAddMenuEntry("GL_POINTS", POINTS);
Gareth Hughesc8516462001-01-06 20:38:03 +00001100 glutAddMenuEntry("", 0);
Keith Whitwell5759f532001-05-11 12:08:15 +00001101 glutAddMenuEntry("Displaylist", DISPLAYLIST);
1102 glutAddMenuEntry("Immediate", IMMEDIATE);
Gareth Hughesc8516462001-01-06 20:38:03 +00001103 glutAddMenuEntry("", 0);
Keith Whitwell5759f532001-05-11 12:08:15 +00001104 if (allowed & LOCKED) {
1105 glutAddMenuEntry("Locked Arrays (CVA)", LOCKED);
1106 glutAddMenuEntry("Unlocked Arrays", UNLOCKED);
1107 glutAddMenuEntry("", 0);
1108 }
1109 glutAddMenuEntry("glVertex", GLVERTEX);
jtgafb833d1999-08-19 00:55:39 +00001110 if (allowed & DRAW_ARRAYS) {
Keith Whitwell5759f532001-05-11 12:08:15 +00001111 glutAddMenuEntry("glDrawElements", DRAW_ELTS);
1112 glutAddMenuEntry("glDrawArrays", DRAW_ARRAYS);
1113 glutAddMenuEntry("glArrayElement", ARRAY_ELT);
jtgafb833d1999-08-19 00:55:39 +00001114 }
Keith Whitwell5759f532001-05-11 12:08:15 +00001115 glutAddMenuEntry("", 0);
1116 glutAddMenuEntry("Quit", QUIT);
jtgafb833d1999-08-19 00:55:39 +00001117 glutAttachMenu(GLUT_RIGHT_BUTTON);
1118
1119 glutReshapeFunc(Reshape);
1120 glutKeyboardFunc(Key);
1121 glutSpecialFunc(SpecialKey);
1122 glutDisplayFunc(Display);
Keith Whitwell03b7aee2000-03-30 17:58:56 +00001123
jtgafb833d1999-08-19 00:55:39 +00001124 glutMainLoop();
1125 return 0;
1126}