diff options
Diffstat (limited to 'progs/demos/tessdemo.c')
-rw-r--r-- | progs/demos/tessdemo.c | 439 |
1 files changed, 439 insertions, 0 deletions
diff --git a/progs/demos/tessdemo.c b/progs/demos/tessdemo.c new file mode 100644 index 0000000000..497b105a88 --- /dev/null +++ b/progs/demos/tessdemo.c @@ -0,0 +1,439 @@ +/* $Id: tessdemo.c,v 1.1 1999/08/19 00:55:40 jtg Exp $ */ + +/* + * 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 + */ + + +/* + * $Log: tessdemo.c,v $ + * Revision 1.1 1999/08/19 00:55:40 jtg + * Initial revision + * + * Revision 3.5 1999/03/28 18:24:37 brianp + * minor clean-up + * + * Revision 3.4 1999/02/14 03:37:07 brianp + * fixed callback problem + * + * Revision 3.3 1998/07/26 01:25:26 brianp + * removed include of gl.h and glu.h + * + * Revision 3.2 1998/06/29 02:37:30 brianp + * minor changes for Windows (Ted Jump) + * + * Revision 3.1 1998/06/09 01:53:49 brianp + * main() should return an int + * + * Revision 3.0 1998/02/14 18:42:29 brianp + * initial rev + * + */ + + +#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; + + +#ifndef GLCALLBACK +#ifdef CALLBACK +#define GLCALLBACK CALLBACK +#else +#define GLCALLBACK +#endif +#endif + + +void GLCALLBACK my_error(GLenum err) +{ + int len,i; + char const *str; + + glColor3f(0.9,0.9,0.9); + glRasterPos2i(5,5); + str=(const char *)gluErrorString(err); + len=strlen(str); + for(i=0;i<len;i++) + glutBitmapCharacter(GLUT_BITMAP_9_BY_15,str[i]); +} + +void GLCALLBACK begin_callback(GLenum mode) +{ + triangle.no=0; +} + +void GLCALLBACK 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 GLCALLBACK 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 GLCALLBACK 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_EDGE_FLAG,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; + (void) x1; + (void) y1; + + 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; + 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) +{ + (void) x; + (void) 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. + */ +int 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(); + return 0; +} |