blob: 327d5a9b2f98f5a0a688998d58bc3f128492863c [file] [log] [blame]
Gareth Hughes3b7a75a2000-01-23 21:25:39 +00001/* $Id: tessdemo.c,v 1.4 2000/01/23 21:25:39 gareth Exp $ */
jtgafb833d1999-08-19 00:55:39 +00002
3/*
4 * A demo of the GLU polygon tesselation functions written by Bogdan Sikorski.
5 * This demo isn't built by the Makefile because it needs GLUT. After you've
6 * installed GLUT you can try this demo.
7 * Here's the command for IRIX, for example:
8 cc -g -ansi -prototypes -fullwarn -float -I../include -DSHM tess_demo.c -L../lib -lglut -lMesaGLU -lMesaGL -lm -lX11 -lXext -lXmu -lfpe -lXext -o tess_demo
9 */
10
Gareth Hugheseb459c61999-11-04 04:00:42 +000011/*
12 * Updated for GLU 1.3 tessellation by Gareth Hughes <garethh@bell-labs.com>
13 */
jtgafb833d1999-08-19 00:55:39 +000014
15/*
16 * $Log: tessdemo.c,v $
Gareth Hughes3b7a75a2000-01-23 21:25:39 +000017 * Revision 1.4 2000/01/23 21:25:39 gareth
18 * Merged 3.2 updates, namely combine callback for intersecting
19 * contours.
20 *
21 * Revision 1.3.2.1 1999/11/16 11:09:09 gareth
22 * Added combine callback. Converted vertices from ints to floats.
23 *
Gareth Hugheseb459c61999-11-04 04:00:42 +000024 * Revision 1.3 1999/11/04 04:00:42 gareth
25 * Updated demo for new GLU 1.3 tessellation. Added optimized rendering
26 * by saving the output of the tessellation into display lists.
27 *
tannerbc34adf1999-09-19 20:09:00 +000028 * Revision 1.2 1999/09/19 20:09:00 tanner
29 *
30 * lots of autoconf updates
31 *
32 * Revision 1.1.1.1 1999/08/19 00:55:40 jtg
33 * Imported sources
jtgafb833d1999-08-19 00:55:39 +000034 *
35 * Revision 3.5 1999/03/28 18:24:37 brianp
36 * minor clean-up
37 *
38 * Revision 3.4 1999/02/14 03:37:07 brianp
39 * fixed callback problem
40 *
41 * Revision 3.3 1998/07/26 01:25:26 brianp
42 * removed include of gl.h and glu.h
43 *
44 * Revision 3.2 1998/06/29 02:37:30 brianp
45 * minor changes for Windows (Ted Jump)
46 *
47 * Revision 3.1 1998/06/09 01:53:49 brianp
48 * main() should return an int
49 *
50 * Revision 3.0 1998/02/14 18:42:29 brianp
51 * initial rev
52 *
53 */
54
55
56#include <GL/glut.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <string.h>
60
Gareth Hugheseb459c61999-11-04 04:00:42 +000061#define MAX_POINTS 256
62#define MAX_CONTOURS 32
63#define MAX_TRIANGLES 256
jtgafb833d1999-08-19 00:55:39 +000064
65#ifndef GLCALLBACK
66#ifdef CALLBACK
67#define GLCALLBACK CALLBACK
68#else
69#define GLCALLBACK
70#endif
71#endif
72
Gareth Hugheseb459c61999-11-04 04:00:42 +000073typedef enum{ QUIT, TESSELATE, CLEAR } menu_entries;
74typedef enum{ DEFINE, TESSELATED } mode_type;
jtgafb833d1999-08-19 00:55:39 +000075
Gareth Hugheseb459c61999-11-04 04:00:42 +000076static GLsizei width, height;
77static GLuint contour_cnt;
78static GLuint triangle_cnt;
79
80static mode_type mode;
81static int menu;
82
83static GLuint list_start;
84
85static GLfloat edge_color[3];
86
87static struct
jtgafb833d1999-08-19 00:55:39 +000088{
Gareth Hughes3b7a75a2000-01-23 21:25:39 +000089 GLfloat p[MAX_POINTS][2];
Gareth Hugheseb459c61999-11-04 04:00:42 +000090 GLuint point_cnt;
91} contours[MAX_CONTOURS];
jtgafb833d1999-08-19 00:55:39 +000092
Gareth Hugheseb459c61999-11-04 04:00:42 +000093static struct
94{
95 GLsizei no;
Gareth Hughes3b7a75a2000-01-23 21:25:39 +000096 GLfloat p[3][2];
Gareth Hugheseb459c61999-11-04 04:00:42 +000097 GLclampf color[3][3];
98} triangles[MAX_TRIANGLES];
99
100
101
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000102void GLCALLBACK error_callback( GLenum err )
Gareth Hugheseb459c61999-11-04 04:00:42 +0000103{
104 int len, i;
105 char const *str;
106
107 glColor3f( 0.9, 0.9, 0.9 );
108 glRasterPos2i( 5, 5 );
109
110 str = (const char *) gluErrorString( err );
111 len = strlen( str );
112
113 for ( i = 0 ; i < len ; i++ ) {
114 glutBitmapCharacter( GLUT_BITMAP_9_BY_15, str[i] );
115 }
jtgafb833d1999-08-19 00:55:39 +0000116}
117
Gareth Hugheseb459c61999-11-04 04:00:42 +0000118void GLCALLBACK begin_callback( GLenum mode )
jtgafb833d1999-08-19 00:55:39 +0000119{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000120 /* Allow multiple triangles to be output inside the begin/end pair. */
121 triangle_cnt = 0;
122 triangles[triangle_cnt].no = 0;
jtgafb833d1999-08-19 00:55:39 +0000123}
124
Gareth Hugheseb459c61999-11-04 04:00:42 +0000125void GLCALLBACK edge_callback( GLenum flag )
jtgafb833d1999-08-19 00:55:39 +0000126{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000127 /* Persist the edge flag across triangles. */
128 if ( flag == GL_TRUE )
129 {
130 edge_color[0] = 1.0;
131 edge_color[1] = 1.0;
132 edge_color[2] = 0.5;
133 }
134 else
135 {
136 edge_color[0] = 1.0;
137 edge_color[1] = 0.0;
138 edge_color[2] = 0.0;
139 }
jtgafb833d1999-08-19 00:55:39 +0000140}
141
142void GLCALLBACK end_callback()
143{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000144 GLint i;
145
146 glBegin( GL_LINES );
147
148 /* Output the three edges of each triangle as lines colored
149 according to their edge flag. */
150 for ( i = 0 ; i < triangle_cnt ; i++ )
151 {
152 glColor3f( triangles[i].color[0][0],
153 triangles[i].color[0][1],
154 triangles[i].color[0][2] );
155
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000156 glVertex2f( triangles[i].p[0][0], triangles[i].p[0][1] );
157 glVertex2f( triangles[i].p[1][0], triangles[i].p[1][1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000158
159 glColor3f( triangles[i].color[1][0],
160 triangles[i].color[1][1],
161 triangles[i].color[1][2] );
162
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000163 glVertex2f( triangles[i].p[1][0], triangles[i].p[1][1] );
164 glVertex2f( triangles[i].p[2][0], triangles[i].p[2][1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000165
166 glColor3f( triangles[i].color[2][0],
167 triangles[i].color[2][1],
168 triangles[i].color[2][2] );
169
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000170 glVertex2f( triangles[i].p[2][0], triangles[i].p[2][1] );
171 glVertex2f( triangles[i].p[0][0], triangles[i].p[0][1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000172 }
173
174 glEnd();
jtgafb833d1999-08-19 00:55:39 +0000175}
176
Gareth Hugheseb459c61999-11-04 04:00:42 +0000177void GLCALLBACK vertex_callback( void *data )
jtgafb833d1999-08-19 00:55:39 +0000178{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000179 GLsizei no;
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000180 GLfloat *p;
jtgafb833d1999-08-19 00:55:39 +0000181
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000182 p = (GLfloat *) data;
Gareth Hugheseb459c61999-11-04 04:00:42 +0000183 no = triangles[triangle_cnt].no;
184
185 triangles[triangle_cnt].p[no][0] = p[0];
186 triangles[triangle_cnt].p[no][1] = p[1];
187
188 triangles[triangle_cnt].color[no][0] = edge_color[0];
189 triangles[triangle_cnt].color[no][1] = edge_color[1];
190 triangles[triangle_cnt].color[no][2] = edge_color[2];
191
192 /* After every three vertices, initialize the next triangle. */
193 if ( ++(triangles[triangle_cnt].no) == 3 )
194 {
195 triangle_cnt++;
196 triangles[triangle_cnt].no = 0;
197 }
jtgafb833d1999-08-19 00:55:39 +0000198}
199
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000200void GLCALLBACK combine_callback( GLdouble coords[3],
201 GLdouble *vertex_data[4],
202 GLfloat weight[4], void **data )
203{
204 GLfloat *vertex;
205 int i;
206
207 vertex = (GLfloat *) malloc( 2 * sizeof(GLfloat) );
208
209 vertex[0] = (GLfloat) coords[0];
210 vertex[1] = (GLfloat) coords[1];
211
212 *data = vertex;
213}
214
215
Gareth Hugheseb459c61999-11-04 04:00:42 +0000216void set_screen_wh( GLsizei w, GLsizei h )
jtgafb833d1999-08-19 00:55:39 +0000217{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000218 width = w;
219 height = h;
jtgafb833d1999-08-19 00:55:39 +0000220}
221
Gareth Hugheseb459c61999-11-04 04:00:42 +0000222void tesse( void )
jtgafb833d1999-08-19 00:55:39 +0000223{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000224 GLUtesselator *tobj;
225 GLdouble data[3];
226 GLuint i, j, point_cnt;
jtgafb833d1999-08-19 00:55:39 +0000227
Gareth Hugheseb459c61999-11-04 04:00:42 +0000228 list_start = glGenLists( 2 );
229
230 tobj = gluNewTess();
231
232 if ( tobj != NULL )
233 {
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000234 gluTessNormal( tobj, 0.0, 0.0, 1.0 );
235 gluTessCallback( tobj, GLU_TESS_BEGIN, glBegin );
236 gluTessCallback( tobj, GLU_TESS_VERTEX, glVertex2fv );
237 gluTessCallback( tobj, GLU_TESS_END, glEnd );
238 gluTessCallback( tobj, GLU_TESS_ERROR, error_callback );
239 gluTessCallback( tobj, GLU_TESS_COMBINE, combine_callback );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000240
241 glNewList( list_start, GL_COMPILE );
242 gluBeginPolygon( tobj );
243
244 for ( j = 0 ; j <= contour_cnt ; j++ )
245 {
246 point_cnt = contours[j].point_cnt;
247 gluNextContour( tobj, GLU_UNKNOWN );
248
249 for ( i = 0 ; i < point_cnt ; i++ )
250 {
251 data[0] = (GLdouble)( contours[j].p[i][0] );
252 data[1] = (GLdouble)( contours[j].p[i][1] );
253 data[2] = 0.0;
254 gluTessVertex( tobj, data, contours[j].p[i] );
255 }
256 }
257
258 gluEndPolygon( tobj );
259 glEndList();
260
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000261#if 0
262 gluTessCallback( tobj, GLU_TESS_BEGIN, begin_callback );
263 gluTessCallback( tobj, GLU_TESS_VERTEX, vertex_callback );
264 gluTessCallback( tobj, GLU_TESS_END, end_callback );
265 gluTessCallback( tobj, GLU_TESS_EDGE_FLAG, edge_callback );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000266
267 glNewList( list_start + 1, GL_COMPILE );
268 gluBeginPolygon( tobj );
269
270 for ( j = 0 ; j <= contour_cnt ; j++ )
271 {
272 point_cnt = contours[j].point_cnt;
273 gluNextContour( tobj, GLU_UNKNOWN );
274
275 for ( i = 0 ; i < point_cnt ; i++ )
276 {
277 data[0] = (GLdouble)( contours[j].p[i][0] );
278 data[1] = (GLdouble)( contours[j].p[i][1] );
279 data[2] = 0.0;
280 gluTessVertex( tobj, data, contours[j].p[i] );
281 }
282 }
283
284 gluEndPolygon( tobj );
285 glEndList();
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000286#endif
Gareth Hugheseb459c61999-11-04 04:00:42 +0000287
288 gluDeleteTess( tobj );
289
290 glutMouseFunc( NULL );
291 mode = TESSELATED;
292 }
jtgafb833d1999-08-19 00:55:39 +0000293}
294
Gareth Hugheseb459c61999-11-04 04:00:42 +0000295void left_down( int x1, int y1 )
jtgafb833d1999-08-19 00:55:39 +0000296{
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000297 GLfloat P[2];
Gareth Hugheseb459c61999-11-04 04:00:42 +0000298 GLuint point_cnt;
jtgafb833d1999-08-19 00:55:39 +0000299
Gareth Hugheseb459c61999-11-04 04:00:42 +0000300 /* translate GLUT into GL coordinates */
301
302 P[0] = x1;
303 P[1] = height - y1;
304
305 point_cnt = contours[contour_cnt].point_cnt;
306
307 contours[contour_cnt].p[point_cnt][0] = P[0];
308 contours[contour_cnt].p[point_cnt][1] = P[1];
309
310 glBegin( GL_LINES );
311
312 if ( point_cnt )
313 {
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000314 glVertex2fv( contours[contour_cnt].p[point_cnt-1] );
315 glVertex2fv( P );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000316 }
317 else
318 {
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000319 glVertex2fv( P );
320 glVertex2fv( P );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000321 }
322
323 glEnd();
324 glFinish();
325
326 contours[contour_cnt].point_cnt++;
jtgafb833d1999-08-19 00:55:39 +0000327}
328
Gareth Hugheseb459c61999-11-04 04:00:42 +0000329void middle_down( int x1, int y1 )
jtgafb833d1999-08-19 00:55:39 +0000330{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000331 GLuint point_cnt;
332 (void) x1;
333 (void) y1;
jtgafb833d1999-08-19 00:55:39 +0000334
Gareth Hugheseb459c61999-11-04 04:00:42 +0000335 point_cnt = contours[contour_cnt].point_cnt;
336
337 if ( point_cnt > 2 )
338 {
339 glBegin( GL_LINES );
340
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000341 glVertex2fv( contours[contour_cnt].p[0] );
342 glVertex2fv( contours[contour_cnt].p[point_cnt-1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000343
344 contours[contour_cnt].p[point_cnt][0] = -1;
345
346 glEnd();
347 glFinish();
348
349 contour_cnt++;
350 contours[contour_cnt].point_cnt = 0;
351 }
jtgafb833d1999-08-19 00:55:39 +0000352}
353
Gareth Hugheseb459c61999-11-04 04:00:42 +0000354void mouse_clicked( int button, int state, int x, int y )
jtgafb833d1999-08-19 00:55:39 +0000355{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000356 x -= x%10;
357 y -= y%10;
358
359 switch ( button )
360 {
361 case GLUT_LEFT_BUTTON:
362 if ( state == GLUT_DOWN ) {
363 left_down( x, y );
364 }
365 break;
366 case GLUT_MIDDLE_BUTTON:
367 if ( state == GLUT_DOWN ) {
368 middle_down( x, y );
369 }
370 break;
371 }
jtgafb833d1999-08-19 00:55:39 +0000372}
373
Gareth Hugheseb459c61999-11-04 04:00:42 +0000374void display( void )
jtgafb833d1999-08-19 00:55:39 +0000375{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000376 GLuint i,j;
377 GLuint point_cnt;
jtgafb833d1999-08-19 00:55:39 +0000378
Gareth Hugheseb459c61999-11-04 04:00:42 +0000379 glClear( GL_COLOR_BUFFER_BIT );
jtgafb833d1999-08-19 00:55:39 +0000380
Gareth Hugheseb459c61999-11-04 04:00:42 +0000381 switch ( mode )
382 {
383 case DEFINE:
384 /* draw grid */
385 glColor3f( 0.6, 0.5, 0.5 );
386
387 glBegin( GL_LINES );
388
389 for ( i = 0 ; i < width ; i += 10 )
390 {
391 for ( j = 0 ; j < height ; j += 10 )
392 {
393 glVertex2i( 0, j );
394 glVertex2i( width, j );
395 glVertex2i( i, height );
396 glVertex2i( i, 0 );
397 }
398 }
399
400 glColor3f( 1.0, 1.0, 0.0 );
401
402 for ( i = 0 ; i <= contour_cnt ; i++ )
403 {
404 point_cnt = contours[i].point_cnt;
405
406 glBegin( GL_LINES );
407
408 switch ( point_cnt )
409 {
410 case 0:
411 break;
412 case 1:
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000413 glVertex2fv( contours[i].p[0] );
414 glVertex2fv( contours[i].p[0] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000415 break;
416 case 2:
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000417 glVertex2fv( contours[i].p[0] );
418 glVertex2fv( contours[i].p[1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000419 break;
420 default:
421 --point_cnt;
422 for ( j = 0 ; j < point_cnt ; j++ )
423 {
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000424 glVertex2fv( contours[i].p[j] );
425 glVertex2fv( contours[i].p[j+1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000426 }
427 if ( contours[i].p[j+1][0] == -1 )
428 {
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000429 glVertex2fv( contours[i].p[0] );
430 glVertex2fv( contours[i].p[j] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000431 }
432 break;
433 }
434
435 glEnd();
436 }
437
438 glFinish();
439 break;
440
441 case TESSELATED:
442 /* draw triangles */
443 glColor3f( 0.7, 0.7, 0.0 );
444 glCallList( list_start );
445
446 glLineWidth( 2.0 );
447 glCallList( list_start + 1 );
448 glLineWidth( 1.0 );
449
450 glFlush();
451 break;
452 }
453
454 glColor3f( 1.0, 1.0, 0.0 );
jtgafb833d1999-08-19 00:55:39 +0000455}
456
457void clear( void )
458{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000459 contour_cnt = 0;
460 contours[0].point_cnt = 0;
461 triangle_cnt = 0;
462
463 glutMouseFunc( mouse_clicked );
464
465 mode = DEFINE;
466
467 glDeleteLists( list_start, 2 );
468 list_start = 0;
jtgafb833d1999-08-19 00:55:39 +0000469}
470
471void quit( void )
472{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000473 exit( 0 );
jtgafb833d1999-08-19 00:55:39 +0000474}
475
Gareth Hugheseb459c61999-11-04 04:00:42 +0000476void menu_selected( int entry )
jtgafb833d1999-08-19 00:55:39 +0000477{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000478 switch ( entry )
479 {
480 case CLEAR:
481 clear();
482 break;
483 case TESSELATE:
484 tesse();
485 break;
486 case QUIT:
487 quit();
488 break;
489 }
490
491 glutPostRedisplay();
jtgafb833d1999-08-19 00:55:39 +0000492}
493
Gareth Hugheseb459c61999-11-04 04:00:42 +0000494void key_pressed( unsigned char key, int x, int y )
jtgafb833d1999-08-19 00:55:39 +0000495{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000496 (void) x;
497 (void) y;
498
499 switch ( key )
500 {
501 case 'c':
502 case 'C':
503 clear();
504 break;
505 case 't':
506 case 'T':
507 tesse();
508 break;
509 case 'q':
510 case 'Q':
511 quit();
512 break;
513 }
514
515 glutPostRedisplay();
jtgafb833d1999-08-19 00:55:39 +0000516}
517
Gareth Hugheseb459c61999-11-04 04:00:42 +0000518void myinit( void )
jtgafb833d1999-08-19 00:55:39 +0000519{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000520 /* clear background to gray */
521 glClearColor( 0.4, 0.4, 0.4, 0.0 );
522 glShadeModel( GL_FLAT );
523 glPolygonMode( GL_FRONT, GL_FILL );
jtgafb833d1999-08-19 00:55:39 +0000524
Gareth Hugheseb459c61999-11-04 04:00:42 +0000525 menu = glutCreateMenu( menu_selected );
526
527 glutAddMenuEntry( "clear", CLEAR );
528 glutAddMenuEntry( "tesselate", TESSELATE );
529 glutAddMenuEntry( "quit", QUIT );
530
531 glutAttachMenu( GLUT_RIGHT_BUTTON );
532
533 glutMouseFunc( mouse_clicked );
534 glutKeyboardFunc( key_pressed );
535
536 contour_cnt = 0;
537 mode = DEFINE;
jtgafb833d1999-08-19 00:55:39 +0000538}
539
Gareth Hugheseb459c61999-11-04 04:00:42 +0000540static void reshape( GLsizei w, GLsizei h )
jtgafb833d1999-08-19 00:55:39 +0000541{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000542 glViewport( 0, 0, w, h );
543
544 glMatrixMode( GL_PROJECTION );
545 glLoadIdentity();
546 glOrtho( 0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0 );
547
548 glMatrixMode( GL_MODELVIEW );
549 glLoadIdentity();
550
551 set_screen_wh( w, h );
jtgafb833d1999-08-19 00:55:39 +0000552}
553
554
555static void usage( void )
556{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000557 printf( "Use left mouse button to place vertices.\n" );
558 printf( "Press middle mouse button when done.\n" );
559 printf( "Select tesselate from the pop-up menu.\n" );
jtgafb833d1999-08-19 00:55:39 +0000560}
561
562
Gareth Hugheseb459c61999-11-04 04:00:42 +0000563/*
564 * Main Loop
565 * Open window with initial window size, title bar,
566 * RGBA display mode, and handle input events.
jtgafb833d1999-08-19 00:55:39 +0000567 */
Gareth Hugheseb459c61999-11-04 04:00:42 +0000568int main( int argc, char **argv )
jtgafb833d1999-08-19 00:55:39 +0000569{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000570 usage();
571
572 glutInit( &argc, argv );
573 glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
574 glutInitWindowSize( 400, 400 );
575 glutCreateWindow( argv[0] );
576
577 myinit();
578
579 glutDisplayFunc( display );
580 glutReshapeFunc( reshape );
581
582 glutMainLoop();
583
584 return 0;
jtgafb833d1999-08-19 00:55:39 +0000585}