/* Generate an extruded, capped part from a 2-D polyline. */ static void ExtrudePart(int n, GLfloat v[][2], float depth) { static GLUtriangulatorObj *tobj = NULL; int i; float z0 = 0.5 * depth; float z1 = -0.5 * depth; GLdouble vertex[3]; if (tobj == NULL) { tobj = gluNewTess(); /* create and initialize a GLU polygon * * tesselation object */ gluTessCallback(tobj, GLU_BEGIN, glBegin); gluTessCallback(tobj, GLU_VERTEX, glVertex2fv); /* semi-tricky */ gluTessCallback(tobj, GLU_END, glEnd); } /* +Z face */ glPushMatrix(); glTranslatef(0.0, 0.0, z0); glNormal3f(0.0, 0.0, 1.0); gluBeginPolygon(tobj); for (i = 0; i < n; i++) { vertex[0] = v[i][0]; vertex[1] = v[i][1]; vertex[2] = 0.0; gluTessVertex(tobj, vertex, v[i]); } gluEndPolygon(tobj); glPopMatrix(); /* -Z face */ glFrontFace(GL_CW); glPushMatrix(); glTranslatef(0.0, 0.0, z1); glNormal3f(0.0, 0.0, -1.0); gluBeginPolygon(tobj); for (i = 0; i < n; i++) { vertex[0] = v[i][0]; vertex[1] = v[i][1]; vertex[2] = z1; gluTessVertex(tobj, vertex, v[i]); } gluEndPolygon(tobj); glPopMatrix(); glFrontFace(GL_CCW); /* edge polygons */ glBegin(GL_TRIANGLE_STRIP); for (i = 0; i <= n; i++) { float x = v[i % n][0]; float y = v[i % n][1]; float dx = v[(i + 1) % n][0] - x; float dy = v[(i + 1) % n][1] - y; glVertex3f(x, y, z0); glVertex3f(x, y, z1); glNormal3f(dy, -dx, 0.0); } glEnd(); }
void extrudeSolidFromPolygon(GLfloat data[][2], unsigned int dataSize, GLdouble thickness, GLuint side, GLuint edge, GLuint whole) { static GLUtriangulatorObj *tobj = NULL; GLdouble vertex[3], dx, dy, len; int i; int count = dataSize / (int) (2 * sizeof(GLfloat)); if (tobj == NULL) { tobj = gluNewTess(); /* create and initialize a GLU polygon tesselation object */ gluTessCallback(tobj, GLU_BEGIN, glBegin); gluTessCallback(tobj, GLU_VERTEX, glVertex2fv); /* semi-tricky */ gluTessCallback(tobj, GLU_END, glEnd); } glNewList(side, GL_COMPILE); glShadeModel(GL_SMOOTH); /* smooth minimizes seeing tessellation */ gluBeginPolygon(tobj); for (i = 0; i < count; i++) { vertex[0] = data[i][0]; vertex[1] = data[i][1]; vertex[2] = 0; gluTessVertex(tobj, vertex, data[i]); } gluEndPolygon(tobj); glEndList(); glNewList(edge, GL_COMPILE); glShadeModel(GL_FLAT); /* flat shade keeps angular hands from being "smoothed" */ glBegin(GL_QUAD_STRIP); for (i = 0; i <= count; i++) { /* mod function handles closing the edge */ glVertex3f(data[i % count][0], data[i % count][1], 0.0); glVertex3f(data[i % count][0], data[i % count][1], thickness); /* Calculate a unit normal by dividing by Euclidean distance. We * could be lazy and use glEnable(GL_NORMALIZE) so we could pass in * arbitrary normals for a very slight performance hit. */ dx = data[(i + 1) % count][1] - data[i % count][1]; dy = data[i % count][0] - data[(i + 1) % count][0]; len = sqrt(dx * dx + dy * dy); glNormal3f(dx / len, dy / len, 0.0); } glEnd(); glEndList(); glNewList(whole, GL_COMPILE); glFrontFace(GL_CW); glCallList(edge); glNormal3f(0.0, 0.0, -1.0); /* constant normal for side */ glCallList(side); glPushMatrix(); glTranslatef(0.0, 0.0, thickness); glFrontFace(GL_CCW); glNormal3f(0.0, 0.0, 1.0); /* opposite normal for other side */ glCallList(side); glPopMatrix(); glEndList(); }
void draw_angle_style_front_cap (int ncp, /* number of contour points */ gleDouble bi[3], /* biscetor */ gleDouble point_array[][3]) /* polyline */ { int j; #ifdef OPENGL_10 GLUtriangulatorObj *tobj; #endif /* OPENGL_10 */ if (bi[2] < 0.0) { VEC_SCALE (bi, -1.0, bi); } #ifdef GL_32 /* old-style gl handles concave polygons no problem, so the code is * simple. New-style gl is a lot more tricky. */ /* draw the end cap */ BGNPOLYGON (); N3F (bi); for (j=0; j<ncp; j++) { V3F (point_array[j], j, FRONT_CAP); } ENDPOLYGON (); #endif /* GL_32 */ #ifdef OPENGL_10 N3F(bi); tobj = gluNewTess (); gluTessCallback (tobj, GLU_BEGIN, glBegin); gluTessCallback (tobj, GLU_VERTEX, glVertex3dv); gluTessCallback (tobj, GLU_END, glEnd); gluBeginPolygon (tobj); for (j=0; j<ncp; j++) { gluTessVertex (tobj, point_array[j], point_array[j]); } gluEndPolygon (tobj); gluDeleteTess (tobj); #endif /* OPENGL_10 */ }
static void draw_cut_style_cap_callback (int iloop, double cap[][3], float face_color[3], gleDouble cut_vector[3], gleDouble bisect_vector[3], double norms[][3], int frontwards) { #ifdef DELICATE_TESSELATOR int i; int is_colinear; double *previous_vertex = 0x0; double *first_vertex = 0x0; #endif /* DELICATE_TESSELATOR */ #ifdef OPENGL_10 GLUtriangulatorObj *tobj; tobj = gluNewTess (); gluTessCallback (tobj, GLU_BEGIN, glBegin); gluTessCallback (tobj, GLU_VERTEX, glVertex3dv); gluTessCallback (tobj, GLU_END, glEnd); #endif /* OPENGL_10 */ if (face_color != NULL) C3F (face_color); if (frontwards) { /* if lighting is on, specify the endcap normal */ if (cut_vector != NULL) { /* if normal pointing in wrong direction, flip it. */ if (cut_vector[2] < 0.0) { VEC_SCALE (cut_vector, -1.0, cut_vector); } N3F_D (cut_vector); } #ifdef GL_32 BGNPOLYGON(); for (i=0; i<iloop; i++) { V3F_D (cap[i], i, FRONT_CAP); } ENDPOLYGON(); #endif /* GL_32 */ #ifdef OPENGL_10 /* If you have a tesselator that is happy with anything, * including degenerate points, colinear segments, etc. * then define this. Otherwise, pick one of the others. * * I beleive that the stock SGI tesselator is "lenient", * despite explicit disclaimers in the documentation. * (circa 1995). * * The Mesa tesselator is not at all forgiving of * degenerate points. * (circa 1997-1998) */ #ifdef LENIENT_TESSELATOR gluBeginPolygon (tobj); for (i=0; i<iloop; i++) { gluTessVertex (tobj, cap[i], cap[i]); } gluEndPolygon (tobj); #endif /* LENIENT_TESSELATOR */ #ifdef DELICATE_TESSELATOR gluBeginPolygon (tobj); first_vertex = 0x0; previous_vertex = cap[iloop-1]; for (i=0; i<iloop-1; i++) { COLINEAR (is_colinear, previous_vertex, cap[i], cap[i+1]); if (!is_colinear) { gluTessVertex (tobj, cap[i], cap[i]); previous_vertex = cap[i]; if (!first_vertex) first_vertex = previous_vertex; } } if (!first_vertex) first_vertex = cap[0]; COLINEAR (is_colinear, previous_vertex, cap[iloop-1], first_vertex); if (!is_colinear) gluTessVertex (tobj, cap[iloop-1], cap[iloop-1]); gluEndPolygon (tobj); #endif /* DELICATE_TESSELATOR */ #endif /* OPENGL_10 */ } else { /* if lighting is on, specify the endcap normal */ if (cut_vector != NULL) { /* if normal pointing in wrong direction, flip it. */ if (cut_vector[2] > 0.0) { VEC_SCALE (cut_vector, -1.0, cut_vector); } N3F_D (cut_vector); } /* the sense of the loop is reversed for backfacing culling */ #ifdef GL_32 BGNPOLYGON(); for (i=iloop-1; i>-1; i--) { V3F_D (cap[i], i, BACK_CAP); } ENDPOLYGON(); #endif /* GL_32 */ #ifdef OPENGL_10 #ifdef LENIENT_TESSELATOR gluBeginPolygon (tobj); for (i=iloop-1; i>-1; i--) { gluTessVertex (tobj, cap[i], cap[i]); } gluEndPolygon (tobj); #endif /* LENIENT_TESSELATOR */ #ifdef DELICATE_TESSELATOR gluBeginPolygon (tobj); first_vertex = 0x0; previous_vertex = cap[0]; for (i=iloop-1; i>0; i--) { COLINEAR (is_colinear, previous_vertex, cap[i], cap[i-1]); if (!is_colinear) { gluTessVertex (tobj, cap[i], cap[i]); previous_vertex = cap[i]; if (!first_vertex) first_vertex = previous_vertex; } } if (!first_vertex) first_vertex = cap[iloop-1]; COLINEAR (is_colinear, previous_vertex, cap[0], first_vertex); if (!is_colinear) gluTessVertex (tobj, cap[0], cap[0]); gluEndPolygon (tobj); #endif /* DELICATE_TESSELATOR */ #endif /* OPENGL_10 */ } #ifdef OPENGL_10 gluDeleteTess (tobj); #endif /* OPENGL_10 */ }
/* Mark Kilgard's tessellation code from the "dino" demos. */ void extrudeSolidFromPolygon(GLfloat data[][3], unsigned int dataSize, GLdouble thickness, GLuint side, GLuint edge, GLuint whole) { GLdouble vertex[3], dx, dy, len; int i, k; int flag = 0; int count = dataSize / (3 * sizeof(GLfloat)); static GLUtriangulatorObj *tobj = NULL; if (tobj == NULL) { tobj = gluNewTess(); gluTessCallback(tobj, GLU_BEGIN, glBegin); gluTessCallback(tobj, GLU_VERTEX, glVertex3fv); gluTessCallback(tobj, GLU_END, glEnd); } glNewList(side, GL_COMPILE); glShadeModel(GL_SMOOTH); gluBeginPolygon(tobj); for(i = 0; i < count; i++) { /* This detects a new contour from a large number placed in the unused z coordinate of the vertex where the new contour starts. See the coordinates for letterO, above. The coordinate must be reset below for additional calls. */ if (data[i][2] > 1000.0) { data[i][2] = 0.0; flag = 1; k = i; gluNextContour(tobj, GLU_INTERIOR); } vertex[0] = data[i][0]; vertex[1] = data[i][1]; vertex[2] = 0.0; gluTessVertex(tobj, vertex, data[i]); } gluEndPolygon(tobj); glEndList(); /* Reset coordinate for new calls. */ if (flag == 1) { data[k][2] = 10000.0; flag = 0; } glNewList(edge, GL_COMPILE); glBegin(GL_QUAD_STRIP); for(i = 0; i <= count; i++) { glVertex3f(data[i % count][0], data[i % count][1], 0.0); glVertex3f(data[i % count][0], data[i % count][1], thickness); /* Normals */ dx = data[(i+ 1) % count][1] - data[i % count][1]; dy = data[i % count][0] - data[(i + 1) % count][0]; len = sqrt(dx * dx + dy * dy); glNormal3f(dx / len, dy / len, 0.0); } glEnd(); glEndList(); glNewList(whole, GL_COMPILE); glFrontFace(GL_CW); glMaterialfv(GL_FRONT, GL_DIFFUSE, edgeColor); glMaterialfv(GL_FRONT, GL_SHININESS, shininess); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glCallList(edge); glNormal3f(0.0, 0.0, -1.0); glCallList(side); glPushMatrix(); glTranslatef(0.0, 0.0, thickness); glFrontFace(GL_CCW); glNormal3f(0.0, 0.0, 1.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, sideColor); glMaterialfv(GL_FRONT, GL_SHININESS, shininess); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glCallList(side); glPopMatrix(); glEndList(); }
/* ARGSUSED4 */ static void draw_cut_style_cap_callback (int iloop, double cap[][3], float face_color[3], gleDouble cut_vector[3], gleDouble bisect_vector[3], double norms[][3], int frontwards) { int i; #ifdef OPENGL_10 GLUtriangulatorObj *tobj; tobj = gluNewTess (); gluTessCallback (tobj, GLU_BEGIN, (void (CALLBACK*)()) glBegin); gluTessCallback (tobj, GLU_VERTEX, (void (CALLBACK*)()) glVertex3dv); gluTessCallback (tobj, GLU_END, (void (CALLBACK*)()) glEnd); #endif /* OPENGL_10 */ if (face_color != NULL) C3F (face_color); if (frontwards) { /* if lighting is on, specify the endcap normal */ if (cut_vector != NULL) { /* if normal pointing in wrong direction, flip it. */ if (cut_vector[2] < 0.0) { VEC_SCALE (cut_vector, -1.0, cut_vector); } N3F_D (cut_vector); } #ifdef GL_32 BGNPOLYGON(); for (i=0; i<iloop; i++) { V3F_D (cap[i], i, FRONT_CAP); } ENDPOLYGON(); #endif /* GL_32 */ #ifdef OPENGL_10 gluBeginPolygon (tobj); for (i=0; i<iloop; i++) { gluTessVertex (tobj, cap[i], cap[i]); } gluEndPolygon (tobj); #endif /* OPENGL_10 */ } else { /* if lighting is on, specify the endcap normal */ if (cut_vector != NULL) { /* if normal pointing in wrong direction, flip it. */ if (cut_vector[2] > 0.0) { VEC_SCALE (cut_vector, -1.0, cut_vector); } N3F_D (cut_vector); } /* the sense of the loop is reversed for backfacing culling */ #ifdef GL_32 BGNPOLYGON(); for (i=iloop-1; i>-1; i--) { V3F_D (cap[i], i, BACK_CAP); } ENDPOLYGON(); #endif /* GL_32 */ #ifdef OPENGL_10 gluBeginPolygon (tobj); for (i=iloop-1; i>-1; i--) { gluTessVertex (tobj, cap[i], cap[i]); } gluEndPolygon (tobj); #endif /* OPENGL_10 */ } #ifdef OPENGL_10 gluDeleteTess (tobj); #endif /* OPENGL_10 */ }
void gluauxBeginPolygon (GLUtriangulatorObj* tessobj) { current(tessobj); gluBeginPolygon(tessobj); }
int Tesselate (Tcl_Interp *interp, int argc, char* argv []) { int result = TCL_OK; int icoord = 0; int edgeflags = 1; int iarg; GLUtriangulatorObj* obj; int dlist = -1; GLdouble coord [3]; GLfloat* vtx; GLfloat* vtxptr; globalinterp = interp; globalresult = TCL_OK; for (iarg = 2; iarg < argc; iarg++) { int len = (int)strlen (argv [iarg]); if (strncmp (argv [iarg], "-displaylist", len) == 0) { iarg++; if (iarg == argc) { Tcl_AppendResult (interp, "not enough arguments", (char*)NULL); return TCL_ERROR; } if (strcmp (argv [iarg], "none") == 0) { dlist = 0; } else if (Tcl_GetInt (interp, argv [iarg], &dlist) != TCL_OK) { Tcl_AppendResult (interp, "\nError parsing display list number", (char*) NULL); return TCL_ERROR; } } else if (strncmp (argv [iarg], "-noedgeflags", len) == 0) { edgeflags = 0; } else break; } if (argc - iarg < 9) { Tcl_AppendResult (interp, "Not enough vertices", (char*) NULL); return TCL_ERROR; } obj = gluNewTess(); vtx = (GLfloat*) malloc (sizeof (GLfloat) * (argc - iarg)); vtxptr = vtx; assert (vtx != NULL); gluTessCallback(obj, GLU_BEGIN, glBegin); gluTessCallback(obj, GLU_VERTEX, glVertex3fv); gluTessCallback(obj, GLU_END, glEnd); gluTessCallback(obj, GLU_ERROR, (TessCallback) TessError); if (edgeflags) gluTessCallback (obj, GLU_EDGE_FLAG, (TessCallback) glEdgeFlag); if (dlist == -1) dlist = glGenLists (1); if (dlist != 0) glNewList (dlist, GL_COMPILE); gluBeginPolygon (obj); for (; iarg < argc; iarg++) { int len = (int)strlen (argv [iarg]); if (strncmp (argv [iarg], "-contour", len) == 0) { gluNextContour (obj, GLU_UNKNOWN); } else { if (Tcl_GetDouble (interp, argv [iarg], &coord[icoord]) != TCL_OK) { Tcl_AppendResult (interp, "\nError parsing tesselation vertex coord", (char*) NULL); result = TCL_ERROR; break; } else { icoord = (icoord+1)%3; if (icoord == 0) { *(vtxptr) = (GLfloat)coord [0]; *(vtxptr+1) = (GLfloat)coord [1]; *(vtxptr+2) = (GLfloat)coord [2]; gluTessVertex (obj, coord, vtxptr); vtxptr += 3; } } } } gluEndPolygon (obj); gluDeleteTess (obj); free (vtx); if (dlist != 0) glEndList(); if (result != TCL_OK || globalresult != TCL_OK) { if (dlist != 0) glDeleteLists (dlist, 1); return TCL_ERROR; } if (dlist != 0) { char tmp[128]; sprintf (tmp, "%d", dlist); Tcl_SetResult(interp, tmp, TCL_VOLATILE); } return TCL_OK; }
void TglTessellator::doTessellate(GLTess &glTess, const TColorFunction *cf, const bool antiAliasing, TRegionOutline &outline) { QMutexLocker sl(&CombineDataGuard); Combine_data.clear(); assert(glTess.m_tess); gluTessCallback(glTess.m_tess, GLU_TESS_BEGIN, (GluCallback)glBegin); gluTessCallback(glTess.m_tess, GLU_TESS_END, (GluCallback)glEnd); gluTessCallback(glTess.m_tess, GLU_TESS_COMBINE, (GluCallback)myCombine); #ifdef GLU_VERSION_1_2 gluTessBeginPolygon(glTess.m_tess, NULL); gluTessProperty(glTess.m_tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE); #else #ifdef GLU_VERSION_1_1 gluBeginPolygon(glTess.m_tess); #else assert(false); #endif #endif for (TRegionOutline::Boundary::iterator poly_it = outline.m_exterior.begin(); poly_it != outline.m_exterior.end(); ++poly_it) { #ifdef GLU_VERSION_1_2 gluTessBeginContour(glTess.m_tess); #else #ifdef GLU_VERSION_1_1 gluNextContour(glTess.m_tess, GLU_EXTERIOR); #else assert(false); #endif #endif for (TRegionOutline::PointVector::iterator it = poly_it->begin(); it != poly_it->end(); ++it) gluTessVertex(glTess.m_tess, &(it->x), &(it->x)); #ifdef GLU_VERSION_1_2 gluTessEndContour(glTess.m_tess); #endif } int subRegionNumber = outline.m_interior.size(); if (subRegionNumber > 0) { for (TRegionOutline::Boundary::iterator poly_it = outline.m_interior.begin(); poly_it != outline.m_interior.end(); ++poly_it) { #ifdef GLU_VERSION_1_2 gluTessBeginContour(glTess.m_tess); #else #ifdef GLU_VERSION_1_1 gluNextContour(glTess.m_tess, GLU_INTERIOR); #else assert(false); #endif #endif for (TRegionOutline::PointVector::reverse_iterator rit = poly_it->rbegin(); rit != poly_it->rend(); ++rit) gluTessVertex(glTess.m_tess, &(rit->x), &(rit->x)); #ifdef GLU_VERSION_1_2 gluTessEndContour(glTess.m_tess); #endif } } #ifdef GLU_VERSION_1_2 gluTessEndPolygon(glTess.m_tess); #else #ifdef GLU_VERSION_1_1 gluEndPolygon(glTess.m_tess); #else assert(false); #endif #endif std::list<GLdouble *>::iterator beginIt, endIt; endIt = Combine_data.end(); beginIt = Combine_data.begin(); for (; beginIt != endIt; ++beginIt) delete[](*beginIt); }
void IceFloe::drawGeom() { int i, j; float h; h = height * TransIcelandicExpress::c_RoadLevel; // draw the sides sgVec3 edge, n, up; sgSetVec3( up, 0.0, 1.0, 0.0 ); glBegin( GL_QUADS ); for (j = npnts-1, i = 0; i < npnts; j=i++) { sgSetVec3( edge, pnts[j][0] - pnts[i][0], 0.0, pnts[j][2] - pnts[i][2] ); sgNormalizeVec3( edge ); sgVectorProductVec3( n, edge, up ); glNormal3f( n[0], n[1], n[2] ); glVertex3f( pnts[i][0], h, pnts[i][2] ); glVertex3f( pnts[j][0], h, pnts[j][2] ); glVertex3f( pnts[j][0], 0.0, pnts[j][2] ); glVertex3f( pnts[i][0], 0.0, pnts[i][2] ); } glEnd(); // tesselate the top if (!tess.size()) { if (!gluTess) { gluTess = gluNewTess(); gluTessCallback( gluTess, GLU_BEGIN, (void(__stdcall *)(void))tessBegin ); gluTessCallback( gluTess, GLU_END, (void(__stdcall *)(void))tessEnd ); gluTessCallback( gluTess, GLU_VERTEX, (void(__stdcall *)(void))tessVertex ); gluTessCallback( gluTess, GLU_ERROR, (void(__stdcall *)(void))tessError ); } printf("Tesselating polygon....\n"); floeToTess = this; gluBeginPolygon( gluTess ); GLdouble *v; for (i = 0; i < npnts; i++) { pnts[i][1] = h; v = new GLdouble[4]; v[0] = pnts[i][0]; v[1] = pnts[i][1]; v[2] = pnts[i][2]; printf("gluTessVertex %3.4f %3.4f %3.4f\n", v[0], v[1], v[2] ); gluTessVertex( gluTess, v, pnts[i] ); } printf("About to call end....\n"); gluEndPolygon( gluTess ); printf("Done.\n"); floeToTess = NULL; } // draw the top glNormal3f( 0.0, 1.0, 0.0 ); glBegin( GL_TRIANGLES ); for (std::vector<TessTri*>::iterator ti = tess.begin(); ti != tess.end(); ti++ ) { glVertex3f( (*ti)->a[0], (*ti)->a[1], (*ti)->a[2] ); glVertex3f( (*ti)->b[0], (*ti)->b[1], (*ti)->b[2] ); glVertex3f( (*ti)->c[0], (*ti)->c[1], (*ti)->c[2] ); } glEnd(); }