Clone of mesa.
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

tessdemo.c 12KB

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