1 /* $Id: tessdemo.c,v 1.4 2000/01/23 21:25:39 gareth Exp $ */
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
12 * Updated for GLU 1.3 tessellation by Gareth Hughes <garethh@bell-labs.com>
16 * $Log: tessdemo.c,v $
17 * Revision 1.4 2000/01/23 21:25:39 gareth
18 * Merged 3.2 updates, namely combine callback for intersecting
21 * Revision 1.3.2.1 1999/11/16 11:09:09 gareth
22 * Added combine callback. Converted vertices from ints to floats.
24 * 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.
28 * Revision 1.2 1999/09/19 20:09:00 tanner
30 * lots of autoconf updates
32 * Revision 1.1.1.1 1999/08/19 00:55:40 jtg
35 * Revision 3.5 1999/03/28 18:24:37 brianp
38 * Revision 3.4 1999/02/14 03:37:07 brianp
39 * fixed callback problem
41 * Revision 3.3 1998/07/26 01:25:26 brianp
42 * removed include of gl.h and glu.h
44 * Revision 3.2 1998/06/29 02:37:30 brianp
45 * minor changes for Windows (Ted Jump)
47 * Revision 3.1 1998/06/09 01:53:49 brianp
48 * main() should return an int
50 * Revision 3.0 1998/02/14 18:42:29 brianp
61 #define MAX_POINTS 256
62 #define MAX_CONTOURS 32
63 #define MAX_TRIANGLES 256
67 #define GLCALLBACK CALLBACK
73 typedef enum{ QUIT
, TESSELATE
, CLEAR
} menu_entries
;
74 typedef enum{ DEFINE
, TESSELATED
} mode_type
;
76 static GLsizei width
, height
;
77 static GLuint contour_cnt
;
78 static GLuint triangle_cnt
;
80 static mode_type mode
;
83 static GLuint list_start
;
85 static GLfloat edge_color
[3];
89 GLfloat p
[MAX_POINTS
][2];
91 } contours
[MAX_CONTOURS
];
98 } triangles
[MAX_TRIANGLES
];
102 void GLCALLBACK
error_callback( GLenum err
)
107 glColor3f( 0.9, 0.9, 0.9 );
108 glRasterPos2i( 5, 5 );
110 str
= (const char *) gluErrorString( err
);
113 for ( i
= 0 ; i
< len
; i
++ ) {
114 glutBitmapCharacter( GLUT_BITMAP_9_BY_15
, str
[i
] );
118 void GLCALLBACK
begin_callback( GLenum mode
)
120 /* Allow multiple triangles to be output inside the begin/end pair. */
122 triangles
[triangle_cnt
].no
= 0;
125 void GLCALLBACK
edge_callback( GLenum flag
)
127 /* Persist the edge flag across triangles. */
128 if ( flag
== GL_TRUE
)
142 void GLCALLBACK
end_callback()
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
++ )
152 glColor3f( triangles
[i
].color
[0][0],
153 triangles
[i
].color
[0][1],
154 triangles
[i
].color
[0][2] );
156 glVertex2f( triangles
[i
].p
[0][0], triangles
[i
].p
[0][1] );
157 glVertex2f( triangles
[i
].p
[1][0], triangles
[i
].p
[1][1] );
159 glColor3f( triangles
[i
].color
[1][0],
160 triangles
[i
].color
[1][1],
161 triangles
[i
].color
[1][2] );
163 glVertex2f( triangles
[i
].p
[1][0], triangles
[i
].p
[1][1] );
164 glVertex2f( triangles
[i
].p
[2][0], triangles
[i
].p
[2][1] );
166 glColor3f( triangles
[i
].color
[2][0],
167 triangles
[i
].color
[2][1],
168 triangles
[i
].color
[2][2] );
170 glVertex2f( triangles
[i
].p
[2][0], triangles
[i
].p
[2][1] );
171 glVertex2f( triangles
[i
].p
[0][0], triangles
[i
].p
[0][1] );
177 void GLCALLBACK
vertex_callback( void *data
)
182 p
= (GLfloat
*) data
;
183 no
= triangles
[triangle_cnt
].no
;
185 triangles
[triangle_cnt
].p
[no
][0] = p
[0];
186 triangles
[triangle_cnt
].p
[no
][1] = p
[1];
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];
192 /* After every three vertices, initialize the next triangle. */
193 if ( ++(triangles
[triangle_cnt
].no
) == 3 )
196 triangles
[triangle_cnt
].no
= 0;
200 void GLCALLBACK
combine_callback( GLdouble coords
[3],
201 GLdouble
*vertex_data
[4],
202 GLfloat weight
[4], void **data
)
207 vertex
= (GLfloat
*) malloc( 2 * sizeof(GLfloat
) );
209 vertex
[0] = (GLfloat
) coords
[0];
210 vertex
[1] = (GLfloat
) coords
[1];
216 void set_screen_wh( GLsizei w
, GLsizei h
)
226 GLuint i
, j
, point_cnt
;
228 list_start
= glGenLists( 2 );
234 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
);
241 glNewList( list_start
, GL_COMPILE
);
242 gluBeginPolygon( tobj
);
244 for ( j
= 0 ; j
<= contour_cnt
; j
++ )
246 point_cnt
= contours
[j
].point_cnt
;
247 gluNextContour( tobj
, GLU_UNKNOWN
);
249 for ( i
= 0 ; i
< point_cnt
; i
++ )
251 data
[0] = (GLdouble
)( contours
[j
].p
[i
][0] );
252 data
[1] = (GLdouble
)( contours
[j
].p
[i
][1] );
254 gluTessVertex( tobj
, data
, contours
[j
].p
[i
] );
258 gluEndPolygon( tobj
);
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
);
267 glNewList( list_start
+ 1, GL_COMPILE
);
268 gluBeginPolygon( tobj
);
270 for ( j
= 0 ; j
<= contour_cnt
; j
++ )
272 point_cnt
= contours
[j
].point_cnt
;
273 gluNextContour( tobj
, GLU_UNKNOWN
);
275 for ( i
= 0 ; i
< point_cnt
; i
++ )
277 data
[0] = (GLdouble
)( contours
[j
].p
[i
][0] );
278 data
[1] = (GLdouble
)( contours
[j
].p
[i
][1] );
280 gluTessVertex( tobj
, data
, contours
[j
].p
[i
] );
284 gluEndPolygon( tobj
);
288 gluDeleteTess( tobj
);
290 glutMouseFunc( NULL
);
295 void left_down( int x1
, int y1
)
300 /* translate GLUT into GL coordinates */
305 point_cnt
= contours
[contour_cnt
].point_cnt
;
307 contours
[contour_cnt
].p
[point_cnt
][0] = P
[0];
308 contours
[contour_cnt
].p
[point_cnt
][1] = P
[1];
314 glVertex2fv( contours
[contour_cnt
].p
[point_cnt
-1] );
326 contours
[contour_cnt
].point_cnt
++;
329 void middle_down( int x1
, int y1
)
335 point_cnt
= contours
[contour_cnt
].point_cnt
;
341 glVertex2fv( contours
[contour_cnt
].p
[0] );
342 glVertex2fv( contours
[contour_cnt
].p
[point_cnt
-1] );
344 contours
[contour_cnt
].p
[point_cnt
][0] = -1;
350 contours
[contour_cnt
].point_cnt
= 0;
354 void mouse_clicked( int button
, int state
, int x
, int y
)
361 case GLUT_LEFT_BUTTON
:
362 if ( state
== GLUT_DOWN
) {
366 case GLUT_MIDDLE_BUTTON
:
367 if ( state
== GLUT_DOWN
) {
379 glClear( GL_COLOR_BUFFER_BIT
);
385 glColor3f( 0.6, 0.5, 0.5 );
389 for ( i
= 0 ; i
< width
; i
+= 10 )
391 for ( j
= 0 ; j
< height
; j
+= 10 )
394 glVertex2i( width
, j
);
395 glVertex2i( i
, height
);
400 glColor3f( 1.0, 1.0, 0.0 );
402 for ( i
= 0 ; i
<= contour_cnt
; i
++ )
404 point_cnt
= contours
[i
].point_cnt
;
413 glVertex2fv( contours
[i
].p
[0] );
414 glVertex2fv( contours
[i
].p
[0] );
417 glVertex2fv( contours
[i
].p
[0] );
418 glVertex2fv( contours
[i
].p
[1] );
422 for ( j
= 0 ; j
< point_cnt
; j
++ )
424 glVertex2fv( contours
[i
].p
[j
] );
425 glVertex2fv( contours
[i
].p
[j
+1] );
427 if ( contours
[i
].p
[j
+1][0] == -1 )
429 glVertex2fv( contours
[i
].p
[0] );
430 glVertex2fv( contours
[i
].p
[j
] );
443 glColor3f( 0.7, 0.7, 0.0 );
444 glCallList( list_start
);
447 glCallList( list_start
+ 1 );
454 glColor3f( 1.0, 1.0, 0.0 );
460 contours
[0].point_cnt
= 0;
463 glutMouseFunc( mouse_clicked
);
467 glDeleteLists( list_start
, 2 );
476 void menu_selected( int entry
)
494 void key_pressed( unsigned char key
, int x
, int y
)
520 /* clear background to gray */
521 glClearColor( 0.4, 0.4, 0.4, 0.0 );
522 glShadeModel( GL_FLAT
);
523 glPolygonMode( GL_FRONT
, GL_FILL
);
525 menu
= glutCreateMenu( menu_selected
);
527 glutAddMenuEntry( "clear", CLEAR
);
528 glutAddMenuEntry( "tesselate", TESSELATE
);
529 glutAddMenuEntry( "quit", QUIT
);
531 glutAttachMenu( GLUT_RIGHT_BUTTON
);
533 glutMouseFunc( mouse_clicked
);
534 glutKeyboardFunc( key_pressed
);
540 static void reshape( GLsizei w
, GLsizei h
)
542 glViewport( 0, 0, w
, h
);
544 glMatrixMode( GL_PROJECTION
);
546 glOrtho( 0.0, (GLdouble
)w
, 0.0, (GLdouble
)h
, -1.0, 1.0 );
548 glMatrixMode( GL_MODELVIEW
);
551 set_screen_wh( w
, h
);
555 static void usage( void )
557 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" );
565 * Open window with initial window size, title bar,
566 * RGBA display mode, and handle input events.
568 int main( int argc
, char **argv
)
572 glutInit( &argc
, argv
);
573 glutInitDisplayMode( GLUT_SINGLE
| GLUT_RGB
);
574 glutInitWindowSize( 400, 400 );
575 glutCreateWindow( argv
[0] );
579 glutDisplayFunc( display
);
580 glutReshapeFunc( reshape
);