~ubuntu-branches/ubuntu/quantal/mesa-glw/quantal

« back to all changes in this revision

Viewing changes to progs/demos/tessdemo.c

  • Committer: Bazaar Package Importer
  • Author(s): Morten Kjeldgaard
  • Date: 2008-05-06 16:19:15 UTC
  • Revision ID: james.westby@ubuntu.com-20080506161915-uynz7nftmfixu6bq
Tags: upstream-7.0.3
ImportĀ upstreamĀ versionĀ 7.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/*
 
3
 * A demo of the GLU polygon tesselation functions written by Bogdan Sikorski.
 
4
 * Updated for GLU 1.3 tessellation by Gareth Hughes <gareth@valinux.com>
 
5
 */
 
6
 
 
7
#include <stdio.h>
 
8
#include <stdlib.h>
 
9
#include <string.h>
 
10
#include <GL/glut.h>
 
11
 
 
12
#define MAX_POINTS      256
 
13
#define MAX_CONTOURS    32
 
14
#define MAX_TRIANGLES   256
 
15
 
 
16
#ifndef GLCALLBACK
 
17
#ifdef CALLBACK
 
18
#define GLCALLBACK CALLBACK
 
19
#else
 
20
#define GLCALLBACK
 
21
#endif
 
22
#endif
 
23
 
 
24
#ifdef GLU_VERSION_1_2
 
25
 
 
26
typedef enum{ QUIT, TESSELATE, CLEAR } menu_entries;
 
27
typedef enum{ DEFINE, TESSELATED } mode_type;
 
28
 
 
29
static GLsizei          width, height;
 
30
static GLuint           contour_cnt;
 
31
static GLuint           triangle_cnt;
 
32
 
 
33
static mode_type        mode;
 
34
static int              menu;
 
35
 
 
36
static GLuint           list_start;
 
37
 
 
38
static GLfloat          edge_color[3];
 
39
 
 
40
static struct {
 
41
   GLfloat      p[MAX_POINTS][2];
 
42
   GLuint       point_cnt;
 
43
} contours[MAX_CONTOURS];
 
44
 
 
45
static struct {
 
46
   GLsizei      no;
 
47
   GLfloat      p[3][2];
 
48
   GLclampf     color[3][3];
 
49
} triangles[MAX_TRIANGLES];
 
50
 
 
51
 
 
52
 
 
53
static void GLCALLBACK error_callback( GLenum err )
 
54
{
 
55
   int          len, i;
 
56
   char const   *str;
 
57
 
 
58
   glColor3f( 0.9, 0.9, 0.9 );
 
59
   glRasterPos2i( 5, 5 );
 
60
 
 
61
   str = (const char *) gluErrorString( err );
 
62
   len = strlen( str );
 
63
 
 
64
   for ( i = 0 ; i < len ; i++ ) {
 
65
      glutBitmapCharacter( GLUT_BITMAP_9_BY_15, str[i] );
 
66
   }
 
67
}
 
68
 
 
69
static void GLCALLBACK begin_callback( GLenum mode )
 
70
{
 
71
   /* Allow multiple triangles to be output inside the begin/end pair. */
 
72
   triangle_cnt = 0;
 
73
   triangles[triangle_cnt].no = 0;
 
74
}
 
75
 
 
76
static void GLCALLBACK edge_callback( GLenum flag )
 
77
{
 
78
   /* Persist the edge flag across triangles. */
 
79
   if ( flag == GL_TRUE ) {
 
80
      edge_color[0] = 1.0;
 
81
      edge_color[1] = 1.0;
 
82
      edge_color[2] = 0.5;
 
83
   } else {
 
84
      edge_color[0] = 1.0;
 
85
      edge_color[1] = 0.0;
 
86
      edge_color[2] = 0.0;
 
87
   }
 
88
}
 
89
 
 
90
static void GLCALLBACK end_callback()
 
91
{
 
92
   GLuint       i;
 
93
 
 
94
   glBegin( GL_LINES );
 
95
 
 
96
   /* Output the three edges of each triangle as lines colored
 
97
      according to their edge flag. */
 
98
   for ( i = 0 ; i < triangle_cnt ; i++ ) {
 
99
      glColor3f( triangles[i].color[0][0],
 
100
                 triangles[i].color[0][1],
 
101
                 triangles[i].color[0][2] );
 
102
 
 
103
      glVertex2f( triangles[i].p[0][0], triangles[i].p[0][1] );
 
104
      glVertex2f( triangles[i].p[1][0], triangles[i].p[1][1] );
 
105
 
 
106
      glColor3f( triangles[i].color[1][0],
 
107
                 triangles[i].color[1][1],
 
108
                 triangles[i].color[1][2] );
 
109
 
 
110
      glVertex2f( triangles[i].p[1][0], triangles[i].p[1][1] );
 
111
      glVertex2f( triangles[i].p[2][0], triangles[i].p[2][1] );
 
112
 
 
113
      glColor3f( triangles[i].color[2][0],
 
114
                 triangles[i].color[2][1],
 
115
                 triangles[i].color[2][2] );
 
116
 
 
117
      glVertex2f( triangles[i].p[2][0], triangles[i].p[2][1] );
 
118
      glVertex2f( triangles[i].p[0][0], triangles[i].p[0][1] );
 
119
   }
 
120
 
 
121
   glEnd();
 
122
}
 
123
 
 
124
static void GLCALLBACK vertex_callback( void *data )
 
125
{
 
126
   GLsizei      no;
 
127
   GLfloat      *p;
 
128
 
 
129
   p = (GLfloat *) data;
 
130
   no = triangles[triangle_cnt].no;
 
131
 
 
132
   triangles[triangle_cnt].p[no][0] = p[0];
 
133
   triangles[triangle_cnt].p[no][1] = p[1];
 
134
 
 
135
   triangles[triangle_cnt].color[no][0] = edge_color[0];
 
136
   triangles[triangle_cnt].color[no][1] = edge_color[1];
 
137
   triangles[triangle_cnt].color[no][2] = edge_color[2];
 
138
 
 
139
   /* After every three vertices, initialize the next triangle. */
 
140
   if ( ++(triangles[triangle_cnt].no) == 3 ) {
 
141
      triangle_cnt++;
 
142
      triangles[triangle_cnt].no = 0;
 
143
   }
 
144
}
 
145
 
 
146
static void GLCALLBACK combine_callback( GLdouble coords[3],
 
147
                                         GLdouble *vertex_data[4],
 
148
                                         GLfloat weight[4], void **data )
 
149
{
 
150
   GLfloat      *vertex;
 
151
 
 
152
   vertex = (GLfloat *) malloc( 2 * sizeof(GLfloat) );
 
153
 
 
154
   vertex[0] = (GLfloat) coords[0];
 
155
   vertex[1] = (GLfloat) coords[1];
 
156
 
 
157
   *data = vertex;
 
158
}
 
159
 
 
160
 
 
161
static void set_screen_wh( GLsizei w, GLsizei h )
 
162
{
 
163
   width = w;
 
164
   height = h;
 
165
}
 
166
 
 
167
typedef void (GLAPIENTRY *callback_t)();
 
168
 
 
169
static void tesse( void )
 
170
{
 
171
   GLUtesselator        *tobj;
 
172
   GLdouble             data[3];
 
173
   GLuint               i, j, point_cnt;
 
174
 
 
175
   list_start = glGenLists( 2 );
 
176
 
 
177
   tobj = gluNewTess();
 
178
 
 
179
   if ( tobj != NULL ) {
 
180
      gluTessNormal( tobj, 0.0, 0.0, 1.0 );
 
181
      gluTessCallback( tobj, GLU_TESS_BEGIN, (callback_t) glBegin );
 
182
      gluTessCallback( tobj, GLU_TESS_VERTEX, (callback_t) glVertex2fv );
 
183
      gluTessCallback( tobj, GLU_TESS_END, (callback_t) glEnd );
 
184
      gluTessCallback( tobj, GLU_TESS_ERROR, (callback_t) error_callback );
 
185
      gluTessCallback( tobj, GLU_TESS_COMBINE, (callback_t) combine_callback );
 
186
 
 
187
      glNewList( list_start, GL_COMPILE );
 
188
      gluBeginPolygon( tobj );
 
189
 
 
190
      for ( j = 0 ; j <= contour_cnt ; j++ ) {
 
191
         point_cnt = contours[j].point_cnt;
 
192
         gluNextContour( tobj, GLU_UNKNOWN );
 
193
 
 
194
         for ( i = 0 ; i < point_cnt ; i++ ) {
 
195
            data[0] = (GLdouble)( contours[j].p[i][0] );
 
196
            data[1] = (GLdouble)( contours[j].p[i][1] );
 
197
            data[2] = 0.0;
 
198
            gluTessVertex( tobj, data, contours[j].p[i] );
 
199
         }
 
200
      }
 
201
 
 
202
      gluEndPolygon( tobj );
 
203
      glEndList();
 
204
 
 
205
      gluTessCallback( tobj, GLU_TESS_BEGIN, (callback_t) begin_callback );
 
206
      gluTessCallback( tobj, GLU_TESS_VERTEX, (callback_t) vertex_callback );
 
207
      gluTessCallback( tobj, GLU_TESS_END, (callback_t) end_callback );
 
208
      gluTessCallback( tobj, GLU_TESS_EDGE_FLAG, (callback_t) edge_callback );
 
209
 
 
210
      glNewList( list_start + 1, GL_COMPILE );
 
211
      gluBeginPolygon( tobj );
 
212
 
 
213
      for ( j = 0 ; j <= contour_cnt ; j++ ) {
 
214
         point_cnt = contours[j].point_cnt;
 
215
         gluNextContour( tobj, GLU_UNKNOWN );
 
216
 
 
217
         for ( i = 0 ; i < point_cnt ; i++ ) {
 
218
            data[0] = (GLdouble)( contours[j].p[i][0] );
 
219
            data[1] = (GLdouble)( contours[j].p[i][1] );
 
220
            data[2] = 0.0;
 
221
            gluTessVertex( tobj, data, contours[j].p[i] );
 
222
         }
 
223
      }
 
224
 
 
225
      gluEndPolygon( tobj );
 
226
      glEndList();
 
227
 
 
228
      gluDeleteTess( tobj );
 
229
 
 
230
      glutMouseFunc( NULL );
 
231
      mode = TESSELATED;
 
232
   }
 
233
}
 
234
 
 
235
static void left_down( int x1, int y1 )
 
236
{
 
237
   GLfloat      P[2];
 
238
   GLuint       point_cnt;
 
239
 
 
240
   /* translate GLUT into GL coordinates */
 
241
 
 
242
   P[0] = x1;
 
243
   P[1] = height - y1;
 
244
 
 
245
   point_cnt = contours[contour_cnt].point_cnt;
 
246
 
 
247
   contours[contour_cnt].p[point_cnt][0] = P[0];
 
248
   contours[contour_cnt].p[point_cnt][1] = P[1];
 
249
 
 
250
   glBegin( GL_LINES );
 
251
 
 
252
   if ( point_cnt ) {
 
253
      glVertex2fv( contours[contour_cnt].p[point_cnt-1] );
 
254
      glVertex2fv( P );
 
255
   } else {
 
256
      glVertex2fv( P );
 
257
      glVertex2fv( P );
 
258
   }
 
259
 
 
260
   glEnd();
 
261
   glFinish();
 
262
 
 
263
   contours[contour_cnt].point_cnt++;
 
264
}
 
265
 
 
266
static void middle_down( int x1, int y1 )
 
267
{
 
268
   GLuint       point_cnt;
 
269
   (void) x1;
 
270
   (void) y1;
 
271
 
 
272
   point_cnt = contours[contour_cnt].point_cnt;
 
273
 
 
274
   if ( point_cnt > 2 ) {
 
275
      glBegin( GL_LINES );
 
276
 
 
277
      glVertex2fv( contours[contour_cnt].p[0] );
 
278
      glVertex2fv( contours[contour_cnt].p[point_cnt-1] );
 
279
 
 
280
      contours[contour_cnt].p[point_cnt][0] = -1;
 
281
 
 
282
      glEnd();
 
283
      glFinish();
 
284
 
 
285
      contour_cnt++;
 
286
      contours[contour_cnt].point_cnt = 0;
 
287
   }
 
288
}
 
289
 
 
290
static void mouse_clicked( int button, int state, int x, int y )
 
291
{
 
292
   x -= x%10;
 
293
   y -= y%10;
 
294
 
 
295
   switch ( button ) {
 
296
   case GLUT_LEFT_BUTTON:
 
297
      if ( state == GLUT_DOWN ) {
 
298
         left_down( x, y );
 
299
      }
 
300
      break;
 
301
   case GLUT_MIDDLE_BUTTON:
 
302
      if ( state == GLUT_DOWN ) {
 
303
         middle_down( x, y );
 
304
      }
 
305
      break;
 
306
   }
 
307
}
 
308
 
 
309
static void display( void )
 
310
{
 
311
   GLuint i,j;
 
312
   GLsizei ii, jj;
 
313
   GLuint point_cnt;
 
314
 
 
315
   glClear( GL_COLOR_BUFFER_BIT );
 
316
 
 
317
   switch ( mode ) {
 
318
   case DEFINE:
 
319
      /* draw grid */
 
320
      glColor3f( 0.6, 0.5, 0.5 );
 
321
 
 
322
      glBegin( GL_LINES );
 
323
 
 
324
      for ( ii = 0 ; ii < width ; ii += 10 ) {
 
325
         for ( jj = 0 ; jj < height ; jj += 10 ) {
 
326
            glVertex2i( 0, jj );
 
327
            glVertex2i( width, jj );
 
328
            glVertex2i( ii, height );
 
329
            glVertex2i( ii, 0 );
 
330
         }
 
331
      }
 
332
 
 
333
      glEnd();
 
334
 
 
335
      glColor3f( 1.0, 1.0, 0.0 );
 
336
 
 
337
      for ( i = 0 ; i <= contour_cnt ; i++ ) {
 
338
         point_cnt = contours[i].point_cnt;
 
339
 
 
340
         glBegin( GL_LINES );
 
341
 
 
342
         switch ( point_cnt ) {
 
343
         case 0:
 
344
            break;
 
345
         case 1:
 
346
            glVertex2fv( contours[i].p[0] );
 
347
            glVertex2fv( contours[i].p[0] );
 
348
            break;
 
349
         case 2:
 
350
            glVertex2fv( contours[i].p[0] );
 
351
            glVertex2fv( contours[i].p[1] );
 
352
            break;
 
353
         default:
 
354
            --point_cnt;
 
355
            for ( j = 0 ; j < point_cnt ; j++ ) {
 
356
               glVertex2fv( contours[i].p[j] );
 
357
               glVertex2fv( contours[i].p[j+1] );
 
358
            }
 
359
            if ( contours[i].p[j+1][0] == -1 ) {
 
360
               glVertex2fv( contours[i].p[0] );
 
361
               glVertex2fv( contours[i].p[j] );
 
362
            }
 
363
            break;
 
364
         }
 
365
 
 
366
         glEnd();
 
367
      }
 
368
 
 
369
      glFinish();
 
370
      break;
 
371
 
 
372
   case TESSELATED:
 
373
      /* draw triangles */
 
374
      glColor3f( 0.7, 0.7, 0.0 );
 
375
      glCallList( list_start );
 
376
 
 
377
      glLineWidth( 2.0 );
 
378
      glCallList( list_start + 1 );
 
379
      glLineWidth( 1.0 );
 
380
 
 
381
      glFlush();
 
382
      break;
 
383
   }
 
384
 
 
385
   glColor3f( 1.0, 1.0, 0.0 );
 
386
}
 
387
 
 
388
static void clear( void )
 
389
{
 
390
   contour_cnt = 0;
 
391
   contours[0].point_cnt = 0;
 
392
   triangle_cnt = 0;
 
393
 
 
394
   glutMouseFunc( mouse_clicked );
 
395
 
 
396
   mode = DEFINE;
 
397
 
 
398
   glDeleteLists( list_start, 2 );
 
399
   list_start = 0;
 
400
}
 
401
 
 
402
static void quit( void )
 
403
{
 
404
   exit( 0 );
 
405
}
 
406
 
 
407
static void menu_selected( int entry )
 
408
{
 
409
   switch ( entry ) {
 
410
   case CLEAR:
 
411
      clear();
 
412
      break;
 
413
   case TESSELATE:
 
414
      tesse();
 
415
      break;
 
416
   case QUIT:
 
417
      quit();
 
418
      break;
 
419
   }
 
420
 
 
421
   glutPostRedisplay();
 
422
}
 
423
 
 
424
static void key_pressed( unsigned char key, int x, int y )
 
425
{
 
426
   (void) x;
 
427
   (void) y;
 
428
 
 
429
   switch ( key ) {
 
430
   case 'c':
 
431
   case 'C':
 
432
      clear();
 
433
      break;
 
434
   case 't':
 
435
   case 'T':
 
436
      tesse();
 
437
      break;
 
438
   case 27:
 
439
   case 'q':
 
440
   case 'Q':
 
441
      quit();
 
442
      break;
 
443
   }
 
444
 
 
445
   glutPostRedisplay();
 
446
}
 
447
 
 
448
static void myinit( void )
 
449
{
 
450
   /* clear background to gray */
 
451
   glClearColor( 0.4, 0.4, 0.4, 0.0 );
 
452
   glShadeModel( GL_FLAT );
 
453
   glPolygonMode( GL_FRONT, GL_FILL );
 
454
 
 
455
   menu = glutCreateMenu( menu_selected );
 
456
 
 
457
   glutAddMenuEntry( "clear", CLEAR );
 
458
   glutAddMenuEntry( "tesselate", TESSELATE );
 
459
   glutAddMenuEntry( "quit", QUIT );
 
460
 
 
461
   glutAttachMenu( GLUT_RIGHT_BUTTON );
 
462
 
 
463
   glutMouseFunc( mouse_clicked );
 
464
   glutKeyboardFunc( key_pressed );
 
465
 
 
466
   contour_cnt = 0;
 
467
   mode = DEFINE;
 
468
}
 
469
 
 
470
static void reshape( GLsizei w, GLsizei h )
 
471
{
 
472
   glViewport( 0, 0, w, h );
 
473
 
 
474
   glMatrixMode( GL_PROJECTION );
 
475
   glLoadIdentity();
 
476
   glOrtho( 0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0 );
 
477
 
 
478
   glMatrixMode( GL_MODELVIEW );
 
479
   glLoadIdentity();
 
480
 
 
481
   set_screen_wh( w, h );
 
482
}
 
483
 
 
484
#endif
 
485
 
 
486
 
 
487
static void usage( void )
 
488
{
 
489
   printf( "Use left mouse button to place vertices.\n" );
 
490
   printf( "Press middle mouse button when done.\n" );
 
491
   printf( "Select tesselate from the pop-up menu.\n" );
 
492
}
 
493
 
 
494
 
 
495
int main( int argc, char **argv )
 
496
{
 
497
   const char *version = (const char *) gluGetString( GLU_VERSION );
 
498
   printf( "GLU version string: %s\n", version );
 
499
   if ( strstr( version, "1.0" ) || strstr( version, "1.1" ) ) {
 
500
      fprintf( stderr, "Sorry, this demo reqiures GLU 1.2 or later.\n" );
 
501
      exit( 1 );
 
502
   }
 
503
 
 
504
   usage();
 
505
 
 
506
   glutInit( &argc, argv );
 
507
   glutInitDisplayMode( GLUT_SINGLE | GLUT_RGB );
 
508
   glutInitWindowPosition(0, 0);
 
509
   glutInitWindowSize( 400, 400 );
 
510
   glutCreateWindow( argv[0] );
 
511
 
 
512
   /* GH: Bit of a hack...
 
513
    */
 
514
#ifdef GLU_VERSION_1_2
 
515
   myinit();
 
516
 
 
517
   glutDisplayFunc( display );
 
518
   glutReshapeFunc( reshape );
 
519
 
 
520
   glutMainLoop();
 
521
#endif
 
522
 
 
523
   return 0;
 
524
}