/* tessellation.c - Jon McCormack, March 2004 */ /* Functions to demonstrate the use of tessellation using GLU. * Based on code found in the OpenGL programming guide. * */ /* Copyright 2004 Jon McCormack * Last modified 24 March 2004 * Updated: 29 March 2004: removed cross-platform warnings */ #include "tessellation.h" #include #include /* static instance of the tessellator - this is not visible outside this file */ static GLUtesselator *myTess = 0; /* internal callbacks */ static void tcbBegin(GLenum prim) { glBegin(prim); } static void tcbVertex(void * data) { glVertex3dv((GLdouble *)data); } static void tcbEnd() { glEnd(); } static void tcbError(GLenum errno) { fprintf(stderr,"performTess: GLU tessellation error: %s \n", gluErrorString(errno)); } static void tcbCombine(GLdouble c[3], void *d[4], GLfloat w[4], void **out) { GLdouble *nv = (GLdouble *) malloc(sizeof(GLdouble)*3); nv[0] = c[0]; nv[1] = c[1]; nv[2] = c[2]; *out = nv; } /* * initTessellator * * Alloc tessellator object, set up tessellator callbacks. * Note that the tessellator object should be deleted when tessellation * is completed. */ void initTessellator(int selfIntersecting) { finishTessellator(); /* clean-up if necessary */ /* create new tessellator object */ myTess = gluNewTess(); /* assign callbacks */ gluTessCallback(myTess, GLU_TESS_BEGIN, tcbBegin); gluTessCallback(myTess, GLU_TESS_VERTEX, tcbVertex); gluTessCallback(myTess, GLU_TESS_END, tcbEnd); gluTessCallback(myTess, GLU_TESS_ERROR, tcbError); /* this callback is only needed if the primative is self-intersecting */ if (selfIntersecting) gluTessCallback (myTess, GLU_TESS_COMBINE, tcbCombine); } /* * performTess * * perform tessellation on the supplied vertex list */ void performTess(GLdouble *vertices[3], int nverts) { register int i; if (!myTess) { fprintf(stderr,"performTess: error: you need to call initTessellator" "before calling this function\n"); return; } gluTessBeginPolygon(myTess, NULL); gluTessBeginContour(myTess); for (i=0; i