This is tess_demo.c in view mode; [Download] [Up]
/* tess_demo.c */ /* * A demo of the GLU polygon tesselation functions written by Bogdan Sikorski. * This demo isn't built by the Makefile because it needs GLUT. After you've * installed GLUT you can try this demo. * Here's the command for IRIX, for example: 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 */ #include <GL/gl.h> #include <GL/glu.h> #include <GL/glut.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_POINTS 200 #define MAX_CONTOURS 50 int menu; typedef enum{ QUIT, TESSELATE, CLEAR } menu_entries; typedef enum{ DEFINE, TESSELATED } mode_type; struct { GLint p[MAX_POINTS][2]; GLuint point_cnt; } contours[MAX_CONTOURS]; GLuint contour_cnt; GLsizei width,height; mode_type mode; struct { GLsizei no; GLfloat color[3]; GLint p[3][2]; GLclampf p_color[3][3]; } triangle; void my_error(GLenum err) { int len,i; char const *str; glColor3f(0.9,0.9,0.9); glRasterPos2i(5,5); str=gluErrorString(err); len=strlen(str); for(i=0;i<len;i++) glutBitmapCharacter(GLUT_BITMAP_9_BY_15,str[i]); } void begin_callback(GLenum mode) { triangle.no=0; } void edge_callback(GLenum flag) { if(flag==GL_TRUE) { triangle.color[0]=1.0; triangle.color[1]=1.0; triangle.color[2]=0.5; } else { triangle.color[0]=1.0; triangle.color[1]=0.0; triangle.color[2]=0.0; } } void end_callback() { glBegin(GL_LINES); glColor3f(triangle.p_color[0][0],triangle.p_color[0][1], triangle.p_color[0][2]); glVertex2i(triangle.p[0][0],triangle.p[0][1]); glVertex2i(triangle.p[1][0],triangle.p[1][1]); glColor3f(triangle.p_color[1][0],triangle.p_color[1][1], triangle.p_color[1][2]); glVertex2i(triangle.p[1][0],triangle.p[1][1]); glVertex2i(triangle.p[2][0],triangle.p[2][1]); glColor3f(triangle.p_color[2][0],triangle.p_color[2][1], triangle.p_color[2][2]); glVertex2i(triangle.p[2][0],triangle.p[2][1]); glVertex2i(triangle.p[0][0],triangle.p[0][1]); glEnd(); } void vertex_callback(void *data) { GLsizei no; GLint *p; p=(GLint *)data; no=triangle.no; triangle.p[no][0]=p[0]; triangle.p[no][1]=p[1]; triangle.p_color[no][0]=triangle.color[0]; triangle.p_color[no][1]=triangle.color[1]; triangle.p_color[no][2]=triangle.color[2]; ++(triangle.no); } void set_screen_wh(GLsizei w, GLsizei h) { width=w; height=h; } void tesse(void) { GLUtriangulatorObj *tobj; GLdouble data[3]; GLuint i,j,point_cnt; tobj=gluNewTess(); if(tobj!=NULL) { glClear(GL_COLOR_BUFFER_BIT); glColor3f (0.7, 0.7, 0.0); gluTessCallback(tobj,GLU_BEGIN,glBegin); gluTessCallback(tobj,GLU_END,glEnd); gluTessCallback(tobj,GLU_ERROR,my_error); gluTessCallback(tobj,GLU_VERTEX,glVertex2iv); gluBeginPolygon(tobj); for(j=0;j<=contour_cnt;j++) { point_cnt=contours[j].point_cnt; gluNextContour(tobj,GLU_UNKNOWN); for(i=0;i<point_cnt;i++) { data[0]=(GLdouble)(contours[j].p[i][0]); data[1]=(GLdouble)(contours[j].p[i][1]); data[2]=0.0; gluTessVertex(tobj,data,contours[j].p[i]); } } gluEndPolygon(tobj); glLineWidth(2.0); gluTessCallback(tobj,GLU_BEGIN,begin_callback); gluTessCallback(tobj,GLU_END,end_callback); gluTessCallback(tobj,GLU_VERTEX,vertex_callback); gluTessCallback(tobj,GLU_EDGEFLAG,edge_callback); gluBeginPolygon(tobj); for(j=0;j<=contour_cnt;j++) { point_cnt=contours[j].point_cnt; gluNextContour(tobj,GLU_UNKNOWN); for(i=0;i<point_cnt;i++) { data[0]=(GLdouble)(contours[j].p[i][0]); data[1]=(GLdouble)(contours[j].p[i][1]); data[2]=0.0; gluTessVertex(tobj,data,contours[j].p[i]); } } gluEndPolygon(tobj); gluDeleteTess(tobj); glutMouseFunc(NULL); glColor3f (1.0, 1.0, 0.0); glLineWidth(1.0); mode=TESSELATED; } } void left_down(int x1,int y1) { GLint P[2]; GLuint point_cnt; /* translate GLUT into GL coordinates */ P[0]=x1; P[1]=height-y1; point_cnt=contours[contour_cnt].point_cnt; contours[contour_cnt].p[point_cnt][0]=P[0]; contours[contour_cnt].p[point_cnt][1]=P[1]; glBegin(GL_LINES); if(point_cnt) { glVertex2iv(contours[contour_cnt].p[point_cnt-1]); glVertex2iv(P); } else { glVertex2iv(P); glVertex2iv(P); } glEnd(); glFinish(); ++(contours[contour_cnt].point_cnt); } void middle_down(int x1,int y1) { GLuint point_cnt; point_cnt=contours[contour_cnt].point_cnt; if(point_cnt>2) { glBegin(GL_LINES); glVertex2iv(contours[contour_cnt].p[0]); glVertex2iv(contours[contour_cnt].p[point_cnt-1]); contours[contour_cnt].p[point_cnt][0]= -1; glEnd(); glFinish(); contour_cnt++; contours[contour_cnt].point_cnt=0; } } void mouse_clicked(int button,int state,int x,int y) { x-= x%10; y-= y%10; switch(button) { case GLUT_LEFT_BUTTON: if(state==GLUT_DOWN) left_down(x,y); break; case GLUT_MIDDLE_BUTTON: if(state==GLUT_DOWN) middle_down(x,y); break; } } void display(void) { GLuint i,j; GLint P[2]; GLuint point_cnt; glClear(GL_COLOR_BUFFER_BIT); switch(mode) { case DEFINE: /* draw grid */ glColor3f (0.6,0.5,0.5); glBegin(GL_LINES); for(i=0;i<width;i+=10) for(j=0;j<height;j+=10) { glVertex2i(0,j); glVertex2i(width,j); glVertex2i(i,height); glVertex2i(i,0); } glColor3f (1.0, 1.0, 0.0); for(i=0;i<=contour_cnt;i++) { point_cnt=contours[i].point_cnt; glBegin(GL_LINES); switch(point_cnt) { case 0: break; case 1: glVertex2iv(contours[i].p[0]); glVertex2iv(contours[i].p[0]); break; case 2: glVertex2iv(contours[i].p[0]); glVertex2iv(contours[i].p[1]); break; default: --point_cnt; for(j=0;j<point_cnt;j++) { glVertex2iv(contours[i].p[j]); glVertex2iv(contours[i].p[j+1]); } if(contours[i].p[j+1][0]== -1) { glVertex2iv(contours[i].p[0]); glVertex2iv(contours[i].p[j]); } break; } glEnd(); } glFinish(); break; case TESSELATED: /* draw lines */ tesse(); break; } glColor3f (1.0, 1.0, 0.0); } void clear( void ) { contour_cnt=0; contours[0].point_cnt=0; glutMouseFunc(mouse_clicked); mode=DEFINE; display(); } void quit( void ) { exit(0); } void menu_selected(int entry) { switch(entry) { case CLEAR: clear(); break; case TESSELATE: tesse(); break; case QUIT: quit(); break; } } void key_pressed(unsigned char key,int x,int y) { switch(key) { case 't': case 'T': tesse(); glFinish(); break; case 'q': case 'Q': quit(); break; case 'c': case 'C': clear(); break; } } void myinit (void) { /* clear background to gray */ glClearColor (0.4, 0.4, 0.4, 0.0); glShadeModel (GL_FLAT); menu=glutCreateMenu(menu_selected); glutAddMenuEntry("clear",CLEAR); glutAddMenuEntry("tesselate",TESSELATE); glutAddMenuEntry("quit",QUIT); glutAttachMenu(GLUT_RIGHT_BUTTON); glutMouseFunc(mouse_clicked); glutKeyboardFunc(key_pressed); contour_cnt=0; glPolygonMode(GL_FRONT,GL_FILL); mode=DEFINE; } static void reshape(GLsizei w, GLsizei h) { glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, (GLdouble)w, 0.0, (GLdouble)h, -1.0, 1.0); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); set_screen_wh(w,h); } static void usage( void ) { printf("Use left mouse button to place vertices.\n"); printf("Press middle mouse button when done.\n"); printf("Select tesselate from the pop-up menu.\n"); } /* Main Loop * Open window with initial window size, title bar, * RGBA display mode, and handle input events. */ void main(int argc, char** argv) { usage(); glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize (400, 400); glutCreateWindow (argv[0]); myinit (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.