blob: a62f25b272408bc10aaaea2d936bbf94c2cfe3ab [file] [log] [blame]
Gareth Hughes24544292000-01-24 22:54:05 +00001/* $Id: tessdemo.c,v 1.5 2000/01/24 22:54:05 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 Hughes24544292000-01-24 22:54:05 +000017 * Revision 1.5 2000/01/24 22:54:05 gareth
18 * Removed '#if 0' from second pass.
19 *
Gareth Hughes3b7a75a2000-01-23 21:25:39 +000020 * Revision 1.4 2000/01/23 21:25:39 gareth
21 * Merged 3.2 updates, namely combine callback for intersecting
22 * contours.
23 *
24 * Revision 1.3.2.1 1999/11/16 11:09:09 gareth
25 * Added combine callback. Converted vertices from ints to floats.
26 *
Gareth Hugheseb459c61999-11-04 04:00:42 +000027 * Revision 1.3 1999/11/04 04:00:42 gareth
28 * Updated demo for new GLU 1.3 tessellation. Added optimized rendering
29 * by saving the output of the tessellation into display lists.
30 *
tannerbc34adf1999-09-19 20:09:00 +000031 * Revision 1.2 1999/09/19 20:09:00 tanner
32 *
33 * lots of autoconf updates
34 *
35 * Revision 1.1.1.1 1999/08/19 00:55:40 jtg
36 * Imported sources
jtgafb833d1999-08-19 00:55:39 +000037 *
38 * Revision 3.5 1999/03/28 18:24:37 brianp
39 * minor clean-up
40 *
41 * Revision 3.4 1999/02/14 03:37:07 brianp
42 * fixed callback problem
43 *
44 * Revision 3.3 1998/07/26 01:25:26 brianp
45 * removed include of gl.h and glu.h
46 *
47 * Revision 3.2 1998/06/29 02:37:30 brianp
48 * minor changes for Windows (Ted Jump)
49 *
50 * Revision 3.1 1998/06/09 01:53:49 brianp
51 * main() should return an int
52 *
53 * Revision 3.0 1998/02/14 18:42:29 brianp
54 * initial rev
55 *
56 */
57
58
59#include <GL/glut.h>
60#include <stdio.h>
61#include <stdlib.h>
62#include <string.h>
63
Gareth Hugheseb459c61999-11-04 04:00:42 +000064#define MAX_POINTS 256
65#define MAX_CONTOURS 32
66#define MAX_TRIANGLES 256
jtgafb833d1999-08-19 00:55:39 +000067
68#ifndef GLCALLBACK
69#ifdef CALLBACK
70#define GLCALLBACK CALLBACK
71#else
72#define GLCALLBACK
73#endif
74#endif
75
Gareth Hugheseb459c61999-11-04 04:00:42 +000076typedef enum{ QUIT, TESSELATE, CLEAR } menu_entries;
77typedef enum{ DEFINE, TESSELATED } mode_type;
jtgafb833d1999-08-19 00:55:39 +000078
Gareth Hugheseb459c61999-11-04 04:00:42 +000079static GLsizei width, height;
80static GLuint contour_cnt;
81static GLuint triangle_cnt;
82
83static mode_type mode;
84static int menu;
85
86static GLuint list_start;
87
88static GLfloat edge_color[3];
89
90static struct
jtgafb833d1999-08-19 00:55:39 +000091{
Gareth Hughes3b7a75a2000-01-23 21:25:39 +000092 GLfloat p[MAX_POINTS][2];
Gareth Hugheseb459c61999-11-04 04:00:42 +000093 GLuint point_cnt;
94} contours[MAX_CONTOURS];
jtgafb833d1999-08-19 00:55:39 +000095
Gareth Hugheseb459c61999-11-04 04:00:42 +000096static struct
97{
98 GLsizei no;
Gareth Hughes3b7a75a2000-01-23 21:25:39 +000099 GLfloat p[3][2];
Gareth Hugheseb459c61999-11-04 04:00:42 +0000100 GLclampf color[3][3];
101} triangles[MAX_TRIANGLES];
102
103
104
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000105void GLCALLBACK error_callback( GLenum err )
Gareth Hugheseb459c61999-11-04 04:00:42 +0000106{
107 int len, i;
108 char const *str;
109
110 glColor3f( 0.9, 0.9, 0.9 );
111 glRasterPos2i( 5, 5 );
112
113 str = (const char *) gluErrorString( err );
114 len = strlen( str );
115
116 for ( i = 0 ; i < len ; i++ ) {
117 glutBitmapCharacter( GLUT_BITMAP_9_BY_15, str[i] );
118 }
jtgafb833d1999-08-19 00:55:39 +0000119}
120
Gareth Hugheseb459c61999-11-04 04:00:42 +0000121void GLCALLBACK begin_callback( GLenum mode )
jtgafb833d1999-08-19 00:55:39 +0000122{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000123 /* Allow multiple triangles to be output inside the begin/end pair. */
124 triangle_cnt = 0;
125 triangles[triangle_cnt].no = 0;
jtgafb833d1999-08-19 00:55:39 +0000126}
127
Gareth Hugheseb459c61999-11-04 04:00:42 +0000128void GLCALLBACK edge_callback( GLenum flag )
jtgafb833d1999-08-19 00:55:39 +0000129{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000130 /* Persist the edge flag across triangles. */
131 if ( flag == GL_TRUE )
132 {
133 edge_color[0] = 1.0;
134 edge_color[1] = 1.0;
135 edge_color[2] = 0.5;
136 }
137 else
138 {
139 edge_color[0] = 1.0;
140 edge_color[1] = 0.0;
141 edge_color[2] = 0.0;
142 }
jtgafb833d1999-08-19 00:55:39 +0000143}
144
145void GLCALLBACK end_callback()
146{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000147 GLint i;
148
149 glBegin( GL_LINES );
150
151 /* Output the three edges of each triangle as lines colored
152 according to their edge flag. */
153 for ( i = 0 ; i < triangle_cnt ; i++ )
154 {
155 glColor3f( triangles[i].color[0][0],
156 triangles[i].color[0][1],
157 triangles[i].color[0][2] );
158
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000159 glVertex2f( triangles[i].p[0][0], triangles[i].p[0][1] );
160 glVertex2f( triangles[i].p[1][0], triangles[i].p[1][1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000161
162 glColor3f( triangles[i].color[1][0],
163 triangles[i].color[1][1],
164 triangles[i].color[1][2] );
165
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000166 glVertex2f( triangles[i].p[1][0], triangles[i].p[1][1] );
167 glVertex2f( triangles[i].p[2][0], triangles[i].p[2][1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000168
169 glColor3f( triangles[i].color[2][0],
170 triangles[i].color[2][1],
171 triangles[i].color[2][2] );
172
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000173 glVertex2f( triangles[i].p[2][0], triangles[i].p[2][1] );
174 glVertex2f( triangles[i].p[0][0], triangles[i].p[0][1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000175 }
176
177 glEnd();
jtgafb833d1999-08-19 00:55:39 +0000178}
179
Gareth Hugheseb459c61999-11-04 04:00:42 +0000180void GLCALLBACK vertex_callback( void *data )
jtgafb833d1999-08-19 00:55:39 +0000181{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000182 GLsizei no;
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000183 GLfloat *p;
jtgafb833d1999-08-19 00:55:39 +0000184
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000185 p = (GLfloat *) data;
Gareth Hugheseb459c61999-11-04 04:00:42 +0000186 no = triangles[triangle_cnt].no;
187
188 triangles[triangle_cnt].p[no][0] = p[0];
189 triangles[triangle_cnt].p[no][1] = p[1];
190
191 triangles[triangle_cnt].color[no][0] = edge_color[0];
192 triangles[triangle_cnt].color[no][1] = edge_color[1];
193 triangles[triangle_cnt].color[no][2] = edge_color[2];
194
195 /* After every three vertices, initialize the next triangle. */
196 if ( ++(triangles[triangle_cnt].no) == 3 )
197 {
198 triangle_cnt++;
199 triangles[triangle_cnt].no = 0;
200 }
jtgafb833d1999-08-19 00:55:39 +0000201}
202
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000203void GLCALLBACK combine_callback( GLdouble coords[3],
204 GLdouble *vertex_data[4],
205 GLfloat weight[4], void **data )
206{
207 GLfloat *vertex;
208 int i;
209
210 vertex = (GLfloat *) malloc( 2 * sizeof(GLfloat) );
211
212 vertex[0] = (GLfloat) coords[0];
213 vertex[1] = (GLfloat) coords[1];
214
215 *data = vertex;
216}
217
218
Gareth Hugheseb459c61999-11-04 04:00:42 +0000219void set_screen_wh( GLsizei w, GLsizei h )
jtgafb833d1999-08-19 00:55:39 +0000220{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000221 width = w;
222 height = h;
jtgafb833d1999-08-19 00:55:39 +0000223}
224
Gareth Hugheseb459c61999-11-04 04:00:42 +0000225void tesse( void )
jtgafb833d1999-08-19 00:55:39 +0000226{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000227 GLUtesselator *tobj;
228 GLdouble data[3];
229 GLuint i, j, point_cnt;
jtgafb833d1999-08-19 00:55:39 +0000230
Gareth Hugheseb459c61999-11-04 04:00:42 +0000231 list_start = glGenLists( 2 );
232
233 tobj = gluNewTess();
234
235 if ( tobj != NULL )
236 {
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000237 gluTessNormal( tobj, 0.0, 0.0, 1.0 );
238 gluTessCallback( tobj, GLU_TESS_BEGIN, glBegin );
239 gluTessCallback( tobj, GLU_TESS_VERTEX, glVertex2fv );
240 gluTessCallback( tobj, GLU_TESS_END, glEnd );
241 gluTessCallback( tobj, GLU_TESS_ERROR, error_callback );
242 gluTessCallback( tobj, GLU_TESS_COMBINE, combine_callback );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000243
244 glNewList( list_start, GL_COMPILE );
245 gluBeginPolygon( tobj );
246
247 for ( j = 0 ; j <= contour_cnt ; j++ )
248 {
249 point_cnt = contours[j].point_cnt;
250 gluNextContour( tobj, GLU_UNKNOWN );
251
252 for ( i = 0 ; i < point_cnt ; i++ )
253 {
254 data[0] = (GLdouble)( contours[j].p[i][0] );
255 data[1] = (GLdouble)( contours[j].p[i][1] );
256 data[2] = 0.0;
257 gluTessVertex( tobj, data, contours[j].p[i] );
258 }
259 }
260
261 gluEndPolygon( tobj );
262 glEndList();
263
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000264 gluTessCallback( tobj, GLU_TESS_BEGIN, begin_callback );
265 gluTessCallback( tobj, GLU_TESS_VERTEX, vertex_callback );
266 gluTessCallback( tobj, GLU_TESS_END, end_callback );
267 gluTessCallback( tobj, GLU_TESS_EDGE_FLAG, edge_callback );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000268
269 glNewList( list_start + 1, GL_COMPILE );
270 gluBeginPolygon( tobj );
271
272 for ( j = 0 ; j <= contour_cnt ; j++ )
273 {
274 point_cnt = contours[j].point_cnt;
275 gluNextContour( tobj, GLU_UNKNOWN );
276
277 for ( i = 0 ; i < point_cnt ; i++ )
278 {
279 data[0] = (GLdouble)( contours[j].p[i][0] );
280 data[1] = (GLdouble)( contours[j].p[i][1] );
281 data[2] = 0.0;
282 gluTessVertex( tobj, data, contours[j].p[i] );
283 }
284 }
285
286 gluEndPolygon( tobj );
287 glEndList();
288
289 gluDeleteTess( tobj );
290
291 glutMouseFunc( NULL );
292 mode = TESSELATED;
293 }
jtgafb833d1999-08-19 00:55:39 +0000294}
295
Gareth Hugheseb459c61999-11-04 04:00:42 +0000296void left_down( int x1, int y1 )
jtgafb833d1999-08-19 00:55:39 +0000297{
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000298 GLfloat P[2];
Gareth Hugheseb459c61999-11-04 04:00:42 +0000299 GLuint point_cnt;
jtgafb833d1999-08-19 00:55:39 +0000300
Gareth Hugheseb459c61999-11-04 04:00:42 +0000301 /* translate GLUT into GL coordinates */
302
303 P[0] = x1;
304 P[1] = height - y1;
305
306 point_cnt = contours[contour_cnt].point_cnt;
307
308 contours[contour_cnt].p[point_cnt][0] = P[0];
309 contours[contour_cnt].p[point_cnt][1] = P[1];
310
311 glBegin( GL_LINES );
312
313 if ( point_cnt )
314 {
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000315 glVertex2fv( contours[contour_cnt].p[point_cnt-1] );
316 glVertex2fv( P );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000317 }
318 else
319 {
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000320 glVertex2fv( P );
321 glVertex2fv( P );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000322 }
323
324 glEnd();
325 glFinish();
326
327 contours[contour_cnt].point_cnt++;
jtgafb833d1999-08-19 00:55:39 +0000328}
329
Gareth Hugheseb459c61999-11-04 04:00:42 +0000330void middle_down( int x1, int y1 )
jtgafb833d1999-08-19 00:55:39 +0000331{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000332 GLuint point_cnt;
333 (void) x1;
334 (void) y1;
jtgafb833d1999-08-19 00:55:39 +0000335
Gareth Hugheseb459c61999-11-04 04:00:42 +0000336 point_cnt = contours[contour_cnt].point_cnt;
337
338 if ( point_cnt > 2 )
339 {
340 glBegin( GL_LINES );
341
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000342 glVertex2fv( contours[contour_cnt].p[0] );
343 glVertex2fv( contours[contour_cnt].p[point_cnt-1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000344
345 contours[contour_cnt].p[point_cnt][0] = -1;
346
347 glEnd();
348 glFinish();
349
350 contour_cnt++;
351 contours[contour_cnt].point_cnt = 0;
352 }
jtgafb833d1999-08-19 00:55:39 +0000353}
354
Gareth Hugheseb459c61999-11-04 04:00:42 +0000355void mouse_clicked( int button, int state, int x, int y )
jtgafb833d1999-08-19 00:55:39 +0000356{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000357 x -= x%10;
358 y -= y%10;
359
360 switch ( button )
361 {
362 case GLUT_LEFT_BUTTON:
363 if ( state == GLUT_DOWN ) {
364 left_down( x, y );
365 }
366 break;
367 case GLUT_MIDDLE_BUTTON:
368 if ( state == GLUT_DOWN ) {
369 middle_down( x, y );
370 }
371 break;
372 }
jtgafb833d1999-08-19 00:55:39 +0000373}
374
Gareth Hugheseb459c61999-11-04 04:00:42 +0000375void display( void )
jtgafb833d1999-08-19 00:55:39 +0000376{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000377 GLuint i,j;
378 GLuint point_cnt;
jtgafb833d1999-08-19 00:55:39 +0000379
Gareth Hugheseb459c61999-11-04 04:00:42 +0000380 glClear( GL_COLOR_BUFFER_BIT );
jtgafb833d1999-08-19 00:55:39 +0000381
Gareth Hugheseb459c61999-11-04 04:00:42 +0000382 switch ( mode )
383 {
384 case DEFINE:
385 /* draw grid */
386 glColor3f( 0.6, 0.5, 0.5 );
387
388 glBegin( GL_LINES );
389
390 for ( i = 0 ; i < width ; i += 10 )
391 {
392 for ( j = 0 ; j < height ; j += 10 )
393 {
394 glVertex2i( 0, j );
395 glVertex2i( width, j );
396 glVertex2i( i, height );
397 glVertex2i( i, 0 );
398 }
399 }
400
401 glColor3f( 1.0, 1.0, 0.0 );
402
403 for ( i = 0 ; i <= contour_cnt ; i++ )
404 {
405 point_cnt = contours[i].point_cnt;
406
407 glBegin( GL_LINES );
408
409 switch ( point_cnt )
410 {
411 case 0:
412 break;
413 case 1:
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000414 glVertex2fv( contours[i].p[0] );
415 glVertex2fv( contours[i].p[0] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000416 break;
417 case 2:
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000418 glVertex2fv( contours[i].p[0] );
419 glVertex2fv( contours[i].p[1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000420 break;
421 default:
422 --point_cnt;
423 for ( j = 0 ; j < point_cnt ; j++ )
424 {
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000425 glVertex2fv( contours[i].p[j] );
426 glVertex2fv( contours[i].p[j+1] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000427 }
428 if ( contours[i].p[j+1][0] == -1 )
429 {
Gareth Hughes3b7a75a2000-01-23 21:25:39 +0000430 glVertex2fv( contours[i].p[0] );
431 glVertex2fv( contours[i].p[j] );
Gareth Hugheseb459c61999-11-04 04:00:42 +0000432 }
433 break;
434 }
435
436 glEnd();
437 }
438
439 glFinish();
440 break;
441
442 case TESSELATED:
443 /* draw triangles */
444 glColor3f( 0.7, 0.7, 0.0 );
445 glCallList( list_start );
446
447 glLineWidth( 2.0 );
448 glCallList( list_start + 1 );
449 glLineWidth( 1.0 );
450
451 glFlush();
452 break;
453 }
454
455 glColor3f( 1.0, 1.0, 0.0 );
jtgafb833d1999-08-19 00:55:39 +0000456}
457
458void clear( void )
459{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000460 contour_cnt = 0;
461 contours[0].point_cnt = 0;
462 triangle_cnt = 0;
463
464 glutMouseFunc( mouse_clicked );
465
466 mode = DEFINE;
467
468 glDeleteLists( list_start, 2 );
469 list_start = 0;
jtgafb833d1999-08-19 00:55:39 +0000470}
471
472void quit( void )
473{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000474 exit( 0 );
jtgafb833d1999-08-19 00:55:39 +0000475}
476
Gareth Hugheseb459c61999-11-04 04:00:42 +0000477void menu_selected( int entry )
jtgafb833d1999-08-19 00:55:39 +0000478{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000479 switch ( entry )
480 {
481 case CLEAR:
482 clear();
483 break;
484 case TESSELATE:
485 tesse();
486 break;
487 case QUIT:
488 quit();
489 break;
490 }
491
492 glutPostRedisplay();
jtgafb833d1999-08-19 00:55:39 +0000493}
494
Gareth Hugheseb459c61999-11-04 04:00:42 +0000495void key_pressed( unsigned char key, int x, int y )
jtgafb833d1999-08-19 00:55:39 +0000496{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000497 (void) x;
498 (void) y;
499
500 switch ( key )
501 {
502 case 'c':
503 case 'C':
504 clear();
505 break;
506 case 't':
507 case 'T':
508 tesse();
509 break;
510 case 'q':
511 case 'Q':
512 quit();
513 break;
514 }
515
516 glutPostRedisplay();
jtgafb833d1999-08-19 00:55:39 +0000517}
518
Gareth Hugheseb459c61999-11-04 04:00:42 +0000519void myinit( void )
jtgafb833d1999-08-19 00:55:39 +0000520{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000521 /* clear background to gray */
522 glClearColor( 0.4, 0.4, 0.4, 0.0 );
523 glShadeModel( GL_FLAT );
524 glPolygonMode( GL_FRONT, GL_FILL );
jtgafb833d1999-08-19 00:55:39 +0000525
Gareth Hugheseb459c61999-11-04 04:00:42 +0000526 menu = glutCreateMenu( menu_selected );
527
528 glutAddMenuEntry( "clear", CLEAR );
529 glutAddMenuEntry( "tesselate", TESSELATE );
530 glutAddMenuEntry( "quit", QUIT );
531
532 glutAttachMenu( GLUT_RIGHT_BUTTON );
533
534 glutMouseFunc( mouse_clicked );
535 glutKeyboardFunc( key_pressed );
536
537 contour_cnt = 0;
538 mode = DEFINE;
jtgafb833d1999-08-19 00:55:39 +0000539}
540
Gareth Hugheseb459c61999-11-04 04:00:42 +0000541static void reshape( GLsizei w, GLsizei h )
jtgafb833d1999-08-19 00:55:39 +0000542{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000543 glViewport( 0, 0, w, h );
544
545 glMatrixMode( GL_PROJECTION );
546 glLoadIdentity();
547 glOrtho( 0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0 );
548
549 glMatrixMode( GL_MODELVIEW );
550 glLoadIdentity();
551
552 set_screen_wh( w, h );
jtgafb833d1999-08-19 00:55:39 +0000553}
554
555
556static void usage( void )
557{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000558 printf( "Use left mouse button to place vertices.\n" );
559 printf( "Press middle mouse button when done.\n" );
560 printf( "Select tesselate from the pop-up menu.\n" );
jtgafb833d1999-08-19 00:55:39 +0000561}
562
563
Gareth Hugheseb459c61999-11-04 04:00:42 +0000564/*
565 * Main Loop
566 * Open window with initial window size, title bar,
567 * RGBA display mode, and handle input events.
jtgafb833d1999-08-19 00:55:39 +0000568 */
Gareth Hugheseb459c61999-11-04 04:00:42 +0000569int main( int argc, char **argv )
jtgafb833d1999-08-19 00:55:39 +0000570{
Gareth Hugheseb459c61999-11-04 04:00:42 +0000571 usage();
572
573 glutInit( &argc, argv );
574 glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
575 glutInitWindowSize( 400, 400 );
576 glutCreateWindow( argv[0] );
577
578 myinit();
579
580 glutDisplayFunc( display );
581 glutReshapeFunc( reshape );
582
583 glutMainLoop();
584
585 return 0;
jtgafb833d1999-08-19 00:55:39 +0000586}