home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / mesa-1.2.8 / demos / tess_demo.c < prev    next >
C/C++ Source or Header  |  1996-05-27  |  8KB  |  402 lines

  1. /* tess_demo.c */
  2.  
  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.  
  11.  
  12. #include <GL/gl.h>
  13. #include <GL/glu.h>
  14. #include <GL/glut.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18.  
  19. #define MAX_POINTS 200
  20. #define MAX_CONTOURS 50
  21.  
  22. int menu;
  23. typedef enum{ QUIT, TESSELATE, CLEAR } menu_entries;
  24. typedef enum{ DEFINE, TESSELATED } mode_type;
  25. struct
  26. {
  27.     GLint p[MAX_POINTS][2];
  28.     GLuint point_cnt;
  29. } contours[MAX_CONTOURS];
  30. GLuint contour_cnt;
  31. GLsizei width,height;
  32. mode_type mode;
  33.  
  34. struct
  35. {
  36.     GLsizei no;
  37.     GLfloat color[3];
  38.     GLint p[3][2];
  39.     GLclampf p_color[3][3];
  40. } triangle;
  41.  
  42. void my_error(GLenum err)
  43. {
  44.     int len,i;
  45.     char const *str;
  46.  
  47.     glColor3f(0.9,0.9,0.9);
  48.     glRasterPos2i(5,5);
  49.     str=gluErrorString(err);
  50.     len=strlen(str);
  51.     for(i=0;i<len;i++)
  52.         glutBitmapCharacter(GLUT_BITMAP_9_BY_15,str[i]);
  53. }
  54.  
  55. void begin_callback(GLenum mode)
  56. {
  57.     triangle.no=0;
  58. }
  59.  
  60. void edge_callback(GLenum flag)
  61. {
  62.     if(flag==GL_TRUE)
  63.     {
  64.         triangle.color[0]=1.0;
  65.         triangle.color[1]=1.0;
  66.         triangle.color[2]=0.5;
  67.     }
  68.     else
  69.     {
  70.         triangle.color[0]=1.0;
  71.         triangle.color[1]=0.0;
  72.         triangle.color[2]=0.0;
  73.     }
  74. }
  75.  
  76. void end_callback()
  77. {
  78.     glBegin(GL_LINES);
  79.     glColor3f(triangle.p_color[0][0],triangle.p_color[0][1],
  80.         triangle.p_color[0][2]);
  81.     glVertex2i(triangle.p[0][0],triangle.p[0][1]);
  82.     glVertex2i(triangle.p[1][0],triangle.p[1][1]);
  83.     glColor3f(triangle.p_color[1][0],triangle.p_color[1][1],
  84.         triangle.p_color[1][2]);
  85.     glVertex2i(triangle.p[1][0],triangle.p[1][1]);
  86.     glVertex2i(triangle.p[2][0],triangle.p[2][1]);
  87.     glColor3f(triangle.p_color[2][0],triangle.p_color[2][1],
  88.         triangle.p_color[2][2]);
  89.     glVertex2i(triangle.p[2][0],triangle.p[2][1]);
  90.     glVertex2i(triangle.p[0][0],triangle.p[0][1]);
  91.     glEnd();
  92. }
  93.  
  94. void vertex_callback(void *data)
  95. {
  96.     GLsizei no;
  97.     GLint *p;
  98.  
  99.     p=(GLint *)data;
  100.     no=triangle.no;
  101.     triangle.p[no][0]=p[0];
  102.     triangle.p[no][1]=p[1];
  103.     triangle.p_color[no][0]=triangle.color[0];
  104.     triangle.p_color[no][1]=triangle.color[1];
  105.     triangle.p_color[no][2]=triangle.color[2];
  106.     ++(triangle.no);
  107. }
  108.  
  109. void set_screen_wh(GLsizei w, GLsizei h)
  110. {
  111.     width=w;
  112.     height=h;
  113. }
  114.  
  115. void tesse(void)
  116. {
  117.     GLUtriangulatorObj *tobj;
  118.     GLdouble data[3];
  119.     GLuint i,j,point_cnt;
  120.  
  121.     tobj=gluNewTess();
  122.     if(tobj!=NULL)
  123.     {
  124.         glClear(GL_COLOR_BUFFER_BIT);
  125.         glColor3f (0.7, 0.7, 0.0);
  126.         gluTessCallback(tobj,GLU_BEGIN,glBegin);
  127.         gluTessCallback(tobj,GLU_END,glEnd);
  128.         gluTessCallback(tobj,GLU_ERROR,my_error);
  129.         gluTessCallback(tobj,GLU_VERTEX,glVertex2iv);
  130.         gluBeginPolygon(tobj);
  131.         for(j=0;j<=contour_cnt;j++)
  132.         {
  133.             point_cnt=contours[j].point_cnt;
  134.             gluNextContour(tobj,GLU_UNKNOWN);
  135.             for(i=0;i<point_cnt;i++)
  136.             {
  137.                 data[0]=(GLdouble)(contours[j].p[i][0]);
  138.                 data[1]=(GLdouble)(contours[j].p[i][1]);
  139.                 data[2]=0.0;
  140.                 gluTessVertex(tobj,data,contours[j].p[i]);
  141.             }
  142.         }
  143.         gluEndPolygon(tobj);
  144.         glLineWidth(2.0);
  145.         gluTessCallback(tobj,GLU_BEGIN,begin_callback);
  146.         gluTessCallback(tobj,GLU_END,end_callback);
  147.         gluTessCallback(tobj,GLU_VERTEX,vertex_callback);
  148.         gluTessCallback(tobj,GLU_EDGEFLAG,edge_callback);
  149.         gluBeginPolygon(tobj);
  150.         for(j=0;j<=contour_cnt;j++)
  151.         {
  152.             point_cnt=contours[j].point_cnt;
  153.             gluNextContour(tobj,GLU_UNKNOWN);
  154.             for(i=0;i<point_cnt;i++)
  155.             {
  156.                 data[0]=(GLdouble)(contours[j].p[i][0]);
  157.                 data[1]=(GLdouble)(contours[j].p[i][1]);
  158.                 data[2]=0.0;
  159.                 gluTessVertex(tobj,data,contours[j].p[i]);
  160.             }
  161.         }
  162.         gluEndPolygon(tobj);
  163.         gluDeleteTess(tobj);
  164.         glutMouseFunc(NULL);
  165.         glColor3f (1.0, 1.0, 0.0);
  166.         glLineWidth(1.0);
  167.         mode=TESSELATED;
  168.     }
  169. }
  170.  
  171. void left_down(int x1,int y1)
  172. {
  173.     GLint P[2];
  174.     GLuint point_cnt;
  175.  
  176.     /* translate GLUT into GL coordinates */
  177.     P[0]=x1;
  178.     P[1]=height-y1;
  179.     point_cnt=contours[contour_cnt].point_cnt;
  180.     contours[contour_cnt].p[point_cnt][0]=P[0];
  181.     contours[contour_cnt].p[point_cnt][1]=P[1];
  182.     glBegin(GL_LINES);
  183.     if(point_cnt)
  184.     {
  185.         glVertex2iv(contours[contour_cnt].p[point_cnt-1]);
  186.         glVertex2iv(P);
  187.     }
  188.     else
  189.     {
  190.         glVertex2iv(P);
  191.         glVertex2iv(P);
  192.     }
  193.     glEnd();
  194.     glFinish();
  195.     ++(contours[contour_cnt].point_cnt);
  196. }
  197.  
  198. void middle_down(int x1,int y1)
  199. {
  200.     GLuint point_cnt;
  201.  
  202.     point_cnt=contours[contour_cnt].point_cnt;
  203.     if(point_cnt>2)
  204.     {
  205.         glBegin(GL_LINES);
  206.         glVertex2iv(contours[contour_cnt].p[0]);
  207.         glVertex2iv(contours[contour_cnt].p[point_cnt-1]);
  208.         contours[contour_cnt].p[point_cnt][0]= -1;
  209.         glEnd();
  210.         glFinish();
  211.         contour_cnt++;
  212.         contours[contour_cnt].point_cnt=0;
  213.     }
  214. }
  215.  
  216. void mouse_clicked(int button,int state,int x,int y)
  217. {
  218.     x-= x%10;
  219.     y-= y%10;
  220.     switch(button)
  221.     {
  222.         case GLUT_LEFT_BUTTON:
  223.             if(state==GLUT_DOWN)
  224.                 left_down(x,y);
  225.             break;
  226.         case GLUT_MIDDLE_BUTTON:
  227.             if(state==GLUT_DOWN)
  228.                 middle_down(x,y);
  229.             break;
  230.     }
  231. }
  232.  
  233. void display(void)
  234. {
  235.     GLuint i,j;
  236.     GLint P[2];
  237.     GLuint point_cnt;
  238.  
  239.     glClear(GL_COLOR_BUFFER_BIT);
  240.     switch(mode)
  241.     {
  242.         case DEFINE:
  243.             /* draw grid */
  244.             glColor3f (0.6,0.5,0.5);
  245.             glBegin(GL_LINES);
  246.             for(i=0;i<width;i+=10)
  247.                 for(j=0;j<height;j+=10)
  248.                 {
  249.                     glVertex2i(0,j);
  250.                     glVertex2i(width,j);
  251.                     glVertex2i(i,height);
  252.                     glVertex2i(i,0);
  253.             }
  254.             glColor3f (1.0, 1.0, 0.0);
  255.             for(i=0;i<=contour_cnt;i++)
  256.             {
  257.                 point_cnt=contours[i].point_cnt;
  258.                 glBegin(GL_LINES);
  259.                 switch(point_cnt)
  260.                 {
  261.                     case 0:
  262.                         break;
  263.                     case 1:
  264.                         glVertex2iv(contours[i].p[0]);
  265.                         glVertex2iv(contours[i].p[0]);
  266.                         break;
  267.                     case 2:
  268.                         glVertex2iv(contours[i].p[0]);
  269.                         glVertex2iv(contours[i].p[1]);
  270.                         break;
  271.                     default:
  272.                         --point_cnt;
  273.                         for(j=0;j<point_cnt;j++)
  274.                         {
  275.                             glVertex2iv(contours[i].p[j]);
  276.                             glVertex2iv(contours[i].p[j+1]);
  277.                         }
  278.                         if(contours[i].p[j+1][0]== -1)
  279.                         {
  280.                             glVertex2iv(contours[i].p[0]);
  281.                             glVertex2iv(contours[i].p[j]);
  282.                         }
  283.                         break;
  284.                 }
  285.                 glEnd();
  286.             }
  287.             glFinish();
  288.             break;
  289.         case TESSELATED:
  290.             /* draw lines */
  291.             tesse();
  292.             break;
  293.     }
  294.  
  295.     glColor3f (1.0, 1.0, 0.0);
  296. }
  297.  
  298. void clear( void )
  299. {
  300.     contour_cnt=0;
  301.     contours[0].point_cnt=0;
  302.     glutMouseFunc(mouse_clicked);
  303.     mode=DEFINE;
  304.     display();
  305. }
  306.  
  307. void quit( void )
  308. {
  309.     exit(0);
  310. }
  311.  
  312. void menu_selected(int entry)
  313. {
  314.     switch(entry)
  315.     {
  316.         case CLEAR:
  317.             clear();
  318.             break;
  319.         case TESSELATE:
  320.             tesse();
  321.             break;
  322.         case QUIT:
  323.             quit();
  324.             break;
  325.     }
  326. }
  327.  
  328. void key_pressed(unsigned char key,int x,int y)
  329. {
  330.     switch(key)
  331.     {
  332.         case 't':
  333.         case 'T':
  334.             tesse();
  335.             glFinish();
  336.             break;
  337.         case 'q':
  338.         case 'Q':
  339.             quit();
  340.             break;
  341.         case 'c':
  342.         case 'C':
  343.             clear();
  344.             break;
  345.     }
  346. }
  347.  
  348. void myinit (void) 
  349. {
  350. /*  clear background to gray    */
  351.     glClearColor (0.4, 0.4, 0.4, 0.0);
  352.     glShadeModel (GL_FLAT);    
  353.  
  354.     menu=glutCreateMenu(menu_selected);
  355.     glutAddMenuEntry("clear",CLEAR);
  356.     glutAddMenuEntry("tesselate",TESSELATE);
  357.     glutAddMenuEntry("quit",QUIT);
  358.     glutAttachMenu(GLUT_RIGHT_BUTTON);
  359.     glutMouseFunc(mouse_clicked);
  360.     glutKeyboardFunc(key_pressed);
  361.     contour_cnt=0;
  362.     glPolygonMode(GL_FRONT,GL_FILL);
  363.     mode=DEFINE;
  364. }
  365.  
  366. static void reshape(GLsizei w, GLsizei h)
  367. {
  368.     glViewport(0, 0, w, h);
  369.     glMatrixMode(GL_PROJECTION);
  370.     glLoadIdentity();
  371.     glOrtho(0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0);
  372.     glMatrixMode(GL_MODELVIEW);
  373.     glLoadIdentity();
  374.     set_screen_wh(w,h);
  375. }
  376.  
  377.  
  378. static void usage( void )
  379. {
  380.    printf("Use left mouse button to place vertices.\n");
  381.    printf("Press middle mouse button when done.\n");
  382.    printf("Select tesselate from the pop-up menu.\n");
  383. }
  384.  
  385.  
  386. /*  Main Loop
  387.  *  Open window with initial window size, title bar, 
  388.  *  RGBA display mode, and handle input events.
  389.  */
  390. void main(int argc, char** argv)
  391. {
  392.    usage();
  393.     glutInit(&argc, argv);
  394.     glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
  395.     glutInitWindowSize (400, 400);
  396.     glutCreateWindow (argv[0]);
  397.     myinit ();
  398.     glutDisplayFunc(display);
  399.     glutReshapeFunc(reshape);
  400.     glutMainLoop();
  401. }
  402.