void init(void) { GLUtesselator *tobj; GLdouble rect[4][3] = { { 50.0, 50.0, 0.0}, {200.0, 50.0, 0.0}, {200.0, 200.0, 0.0}, { 50.0, 200.0, 0.0} }; GLdouble tri[3][3] = { { 75.0, 75.0, 0.0}, {125.0, 175.0, 0.0}, {175.0, 75.0, 0.0} }; GLdouble star[5][6] = { {250.0, 50.0, 0.0, 1.0, 0.0, 1.0}, {325.0, 200.0, 0.0, 1.0, 1.0, 0.0}, {400.0, 50.0, 0.0, 0.0, 1.0, 1.0}, {250.0, 150.0, 0.0, 1.0, 0.0, 0.0}, {400.0, 150.0, 0.0, 0.0, 1.0, 0.0} }; glClearColor(0.0, 0.0, 0.0, 0.0); startList = glGenLists(2); tobj = gluNewTess(); gluTessCallback(tobj, GLU_TESS_VERTEX, glVertex3dv); gluTessCallback(tobj, GLU_TESS_BEGIN, beginCallback); gluTessCallback(tobj, GLU_TESS_END, endCallback); gluTessCallback(tobj, GLU_TESS_ERROR, errorCallback); // Rectangle with a triangular hole inside. glNewList(startList, GL_COMPILE); glShadeModel(GL_FLAT); gluTessBeginPolygon(tobj, NULL); gluTessBeginContour(tobj); gluTessVertex(tobj, rect[0], rect[0]); gluTessVertex(tobj, rect[1], rect[1]); gluTessVertex(tobj, rect[2], rect[2]); gluTessVertex(tobj, rect[3], rect[3]); gluTessEndContour(tobj); gluTessBeginContour(tobj); gluTessVertex(tobj, tri[0], tri[0]); gluTessVertex(tobj, tri[1], tri[1]); gluTessVertex(tobj, tri[2], tri[2]); gluTessEndContour(tobj); gluTessEndPolygon(tobj); glEndList(); gluTessCallback(tobj, GLU_TESS_VERTEX, vertexCallback); gluTessCallback(tobj, GLU_TESS_BEGIN, beginCallback); gluTessCallback(tobj, GLU_TESS_END, endCallback); gluTessCallback(tobj, GLU_TESS_ERROR, errorCallback); gluTessCallback(tobj, GLU_TESS_COMBINE, combineCallback); // Smooth shaded, self-intersecting star. glNewList(startList + 1, GL_COMPILE); glShadeModel(GL_SMOOTH); gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE); gluTessBeginPolygon(tobj, NULL); gluTessBeginContour(tobj); gluTessVertex(tobj, star[0], star[0]); gluTessVertex(tobj, star[1], star[1]); gluTessVertex(tobj, star[2], star[2]); gluTessVertex(tobj, star[3], star[3]); gluTessVertex(tobj, star[4], star[4]); gluTessEndContour(tobj); gluTessEndPolygon(tobj); glEndList(); gluDeleteTess(tobj); }
void DrawPolygon(clipper::Polygons &pgs) { glColor4f(0.0f, 0.0f, 0.0f, 0.4f); GLUtesselator* tess = gluNewTess(); gluTessCallback(tess, GLU_TESS_BEGIN, (void (CALLBACK*)())&BeginCallback); gluTessCallback(tess, GLU_TESS_VERTEX, (void (CALLBACK*)())&VertexCallback); gluTessCallback(tess, GLU_TESS_END, (void (CALLBACK*)())&EndCallback); gluTessCallback(tess, GLU_TESS_COMBINE, (void (CALLBACK*)())&CombineCallback); gluTessCallback(tess, GLU_TESS_ERROR, (void (CALLBACK*)())&ErrorCallback); gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO); gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); gluTessBeginPolygon(tess, NULL); for (clipper::Polygons::size_type i = 0; i < pgs.size(); ++i) { gluTessBeginContour(tess); for (clipper::Polygon::size_type j = 0; j < pgs[i].size(); ++j) { GLdouble *vert = new GLdouble[3]; vert[0] = (GLdouble)pgs[i][j].X; vert[1] = (GLdouble)pgs[i][j].Y; vert[2] = 0; AddToCleanup(vert); gluTessVertex(tess, vert, vert); } gluTessEndContour(tess); } gluTessEndPolygon(tess); DoCleanup(); glColor4f(0.0f, 0.0f, 0.0f, 0.4f); glLineWidth(1.2f); gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE); //GL_FALSE gluTessBeginPolygon(tess, NULL); for (clipper::Polygons::size_type i = 0; i < pgs.size(); ++i) { gluTessBeginContour(tess); for (clipper::Polygon::size_type j = 0; j < pgs[i].size(); ++j) { GLdouble *vert = new GLdouble[3]; vert[0] = (GLdouble)pgs[i][j].X; vert[1] = (GLdouble)pgs[i][j].Y; vert[2] = 0; AddToCleanup(vert); gluTessVertex(tess, vert, vert); } gluTessEndContour(tess); } gluTessEndPolygon(tess); //final cleanup ... gluDeleteTess(tess); DoCleanup(); }
void Slice::drawPolygon(Polygons &pgs, int layer){ glColor4f(0.0f, 1.0f, 0.0f, 0.25f); GLUtesselator* tess = gluNewTess(); gluTessCallback(tess, GLU_TESS_BEGIN, (GLvoid (__stdcall *) ())&BeginCallback); gluTessCallback(tess, GLU_TESS_VERTEX, (GLvoid (__stdcall *) ())&VertexCallback); gluTessCallback(tess, GLU_TESS_END, (GLvoid (__stdcall *) ())&EndCallback); gluTessCallback(tess, GLU_TESS_COMBINE, (GLvoid (__stdcall *) ())&CombineCallback); gluTessCallback(tess, GLU_TESS_ERROR, (GLvoid (__stdcall *) ())&ErrorCallback); gluTessNormal(tess, 0.0, 0.0, 1.0); gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); //GL_FALSE gluTessBeginPolygon(tess, NULL); glPushMatrix(); glTranslated(0.0,0.0,this->layerHeight*layer); for (Polygons::size_type i = 0; i < pgs.size(); ++i) { gluTessBeginContour(tess); for (ClipperLib::Polygon::size_type j = 0; j < pgs[i].size(); ++j) { GLdouble *vert = NewVector((GLdouble)pgs[i][j].X/1000, (GLdouble)pgs[i][j].Y/1000); gluTessVertex(tess, vert, vert); } gluTessEndContour(tess); } gluTessEndPolygon(tess); ClearVectors(); glColor4f(0.0f, 0.6f, 1.0f, 0.5f); glLineWidth(1.8f); gluTessProperty(tess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); gluTessProperty(tess, GLU_TESS_BOUNDARY_ONLY, GL_TRUE); for (Polygons::size_type i = 0; i < pgs.size(); ++i) { gluTessBeginPolygon(tess, NULL); gluTessBeginContour(tess); for (ClipperLib::Polygon::size_type j = 0; j < pgs[i].size(); ++j) { GLdouble *vert = NewVector((GLdouble)pgs[i][j].X/1000, (GLdouble)pgs[i][j].Y/1000); gluTessVertex(tess, vert, vert); } glColor4f(0.0f, 0.0f, 0.8f, 0.5f); gluTessEndContour(tess); gluTessEndPolygon(tess); } //final cleanup ... gluDeleteTess(tess); ClearVectors(); glPopMatrix(); }
void drawFilledPolygon(Icont *cont) { GLdouble v[3]; Ipoint *pts; int pt; int psize; int ptstr, ptend; sTessError = 0; ptend = cont->psize; ptstr = 0; pts = cont->pts; /* imodPrintStderr(".%d-%d", co, ptend); fflush(stdout); */ if (ptend) { psize = ptend + 1; do { sTessError = 0; psize--; if (psize - ptstr < 3) break; gluTessBeginPolygon(sTessel, NULL); gluTessBeginContour(sTessel); for (pt = ptstr; pt < psize; pt++) { v[0] = pts[pt].x; v[1] = pts[pt].y; v[2] = pts[pt].z; gluTessVertex(sTessel, v, &(pts[pt])); } gluTessEndContour(sTessel); gluTessEndPolygon(sTessel); if ((!sTessError) && ((psize - ptend) > 3)) { gluTessBeginPolygon(sTessel, NULL); gluTessBeginContour(sTessel); for (pt = psize; pt < ptend; pt++) { v[0] = pts[pt].x; v[1] = pts[pt].y; v[2] = pts[pt].z; gluTessVertex(sTessel, v, &(pts[pt])); } gluTessEndContour(sTessel); gluTessEndPolygon(sTessel); } } while(sTessError); } }
void drawFace(carve::poly::Face<3> *face, cRGBA fc, bool offset) { //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); GLUtesselator *tess = gluNewTess(); gluTessCallback(tess, GLU_TESS_BEGIN_DATA, (GLUTessCallback)_faceBegin); gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (GLUTessCallback)_faceVertex); gluTessCallback(tess, GLU_TESS_END_DATA, (GLUTessCallback)_faceEnd); gluTessBeginPolygon(tess, (void *)face); gluTessBeginContour(tess); carve::geom3d::Vector g_translation; double g_scale = 1.0; std::vector<std::pair<carve::geom3d::Vector, cRGBA> > v; v.resize(face->nVertices()); for (size_t i = 0, l = face->nVertices(); i != l; ++i) { v[i] = std::make_pair(g_scale * (face->vertex(i)->v + g_translation), fc); gluTessVertex(tess, (GLdouble *)v[i].first.v, (GLvoid *)&v[i]); } gluTessEndContour(tess); gluTessEndPolygon(tess); gluDeleteTess(tess); }
void DebugHooks::drawFaceLoop(const std::vector<const carve::geom3d::Vector *> &face_loop, const carve::geom3d::Vector &normal, float r, float g, float b, float a, bool lit) { if (lit) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); GLUtesselator *tess = gluNewTess(); gluTessCallback(tess, GLU_TESS_BEGIN, (GLUTessCallback)glBegin); gluTessCallback(tess, GLU_TESS_VERTEX, (GLUTessCallback)glVertex3dv); gluTessCallback(tess, GLU_TESS_END, (GLUTessCallback)glEnd); glNormal3dv(normal.v); glColor4f(r, g, b, a); gluTessBeginPolygon(tess, (void *)NULL); gluTessBeginContour(tess); std::vector<carve::geom3d::Vector> v; v.resize(face_loop.size()); for (size_t i = 0, l = face_loop.size(); i != l; ++i) { v[i] = g_scale * (*face_loop[i] + g_translation); gluTessVertex(tess, (GLdouble *)v[i].v, (GLvoid *)v[i].v); } gluTessEndContour(tess); gluTessEndPolygon(tess); gluDeleteTess(tess); glEnable(GL_LIGHTING); }
void GUIPolygon::performTesselation(SUMOReal lineWidth) const { if (getFill()) { // draw the tesselated shape double* points = new double[myShape.size() * 3]; GLUtesselator* tobj = gluNewTess(); gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(APIENTRY*)()) &glVertex3dv); gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(APIENTRY*)()) &beginCallback); gluTessCallback(tobj, GLU_TESS_END, (GLvoid(APIENTRY*)()) &endCallback); //gluTessCallback(tobj, GLU_TESS_ERROR, (GLvoid (APIENTRY*) ()) &errorCallback); gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(APIENTRY*)()) &combineCallback); gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); gluTessBeginPolygon(tobj, NULL); gluTessBeginContour(tobj); for (size_t i = 0; i != myShape.size(); ++i) { points[3 * i] = myShape[(int) i].x(); points[3 * i + 1] = myShape[(int) i].y(); points[3 * i + 2] = 0; gluTessVertex(tobj, points + 3 * i, points + 3 * i); } gluTessEndContour(tobj); gluTessEndPolygon(tobj); gluDeleteTess(tobj); delete[] points; } else { myLineWidth = lineWidth; GLHelper::drawLine(myShape); GLHelper::drawBoxLines(myShape, myLineWidth); } //std::cout << "OpenGL says: '" << gluErrorString(glGetError()) << "'\n"; }
//---------------------------------------------------------- void ofEndShape(bool bClose){ // (close -> add the first point to the end) // ----------------------------------------------- if ((bClose == true)){ //--------------------------- if (polyVertices.size() > currentStartVertex){ double* point = new double[3]; point[0] = polyVertices[currentStartVertex][0]; point[1] = polyVertices[currentStartVertex][1]; point[2] = 0; polyVertices.push_back(point); } } //------------------------------------------------ if ((polyMode == OF_POLY_WINDING_ODD) && (drawMode == OF_OUTLINE)){ // let's just draw via another method, like glLineLoop // much, much faster, and *no* tess / computation necessary glBegin(GL_LINE_STRIP); for (int i=currentStartVertex; i< polyVertices.size(); i++) { float x = polyVertices[i][0]; float y = polyVertices[i][1]; glVertex2f(x,y); } glEnd(); } else { if ( tobj != NULL){ gluTessBeginContour( tobj); for (int i=currentStartVertex; i<polyVertices.size(); i++) { gluTessVertex( tobj, polyVertices[i],polyVertices[i]); } gluTessEndContour( tobj); } } if ( tobj != NULL){ // no matter what we did / do, we need to delete the tesselator object gluTessEndPolygon( tobj); gluDeleteTess( tobj); tobj = NULL; } // now clear the vertices on the dynamically allocated data clearTessVertices(); if (bSmoothHinted && drawMode == OF_OUTLINE) endSmoothing(); }
eBool eTriangulator::triangulate() { m_triIndices.clear(); m_triIndices.reserve(m_totalVtxCount*3); GLUtesselator *tess = gluNewTess(); gluTessCallback(tess, GLU_TESS_EDGE_FLAG_DATA, (void (eCALLBACK *)())_edgeFlagCallback); gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (void (eCALLBACK *)())_vertexCallback); gluTessCallback(tess, GLU_TESS_ERROR_DATA, (void (eCALLBACK *)())_errorCallback); gluTessCallback(tess, GLU_TESS_COMBINE_DATA, (void (eCALLBACK *)())_combineCallback); gluTessBeginPolygon(tess, this); for (eU32 i=0, vtxNum=0; i<m_contours.size(); i++) { const eArray<eVector3> &contour = *m_contours[i]; if(contour.isEmpty()) continue; gluTessBeginContour(tess); { for (eU32 j=0; j<contour.size(); j++) { eF64 coords[] = {contour[j].x, contour[j].y, contour[j].z}; gluTessVertex(tess, coords, (ePtr)vtxNum); vtxNum++; } } gluTessEndContour(tess); } gluTessEndPolygon(tess); eASSERT(m_triIndices.size()%3 == 0); return eTRUE; }
void GLUTriangulator::processOutputFace(std::vector<carve::poly::Face<3> *> &faces, const carve::poly::Face<3> *orig, bool flipped) { size_t f = 0; while (f < faces.size()) { carve::poly::Face<3> *face = faces[f]; if (face->nVertices() == 3) { ++f; continue; } orig_face = face; new_faces.clear(); gluTessBeginPolygon(tess, (void *)this); gluTessBeginContour(tess); for (size_t i = 0; i < face->nVertices(); ++i) { gluTessVertex(tess, (GLdouble *)face->vertex(i)->v.v, (GLvoid *)face->vertex(i)); } gluTessEndContour(tess); gluTessEndPolygon(tess); faces.erase(faces.begin() + f); faces.reserve(faces.size() + new_faces.size()); faces.insert(faces.begin() + f, new_faces.begin(), new_faces.end()); f += new_faces.size(); delete face; } }
void ODDC::DrawPolygonsTessellated( int n, int npoints[], wxPoint points[], wxCoord xoffset, wxCoord yoffset ) { if( dc ) { int prev = 0; for( int i = 0; i < n; i++ ) { dc->DrawPolygon( npoints[i], &points[i + prev], xoffset, yoffset ); prev += npoints[i]; } } #ifdef ocpnUSE_GL else { GLUtesselator *tobj = gluNewTess(); gluTessCallback( tobj, GLU_TESS_VERTEX, (_GLUfuncptr) &ODDCvertexCallback ); gluTessCallback( tobj, GLU_TESS_BEGIN, (_GLUfuncptr) &ODDCbeginCallback ); gluTessCallback( tobj, GLU_TESS_END, (_GLUfuncptr) &ODDCendCallback ); gluTessCallback( tobj, GLU_TESS_COMBINE, (_GLUfuncptr) &ODDCcombineCallback ); gluTessCallback( tobj, GLU_TESS_ERROR, (_GLUfuncptr) &ODDCerrorCallback ); gluTessNormal( tobj, 0, 0, 1); gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); gluTessProperty(tobj, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); if(glIsEnabled(GL_TEXTURE_2D)) g_bTexture2D = true; else g_bTexture2D = false; ConfigurePen(); if( ConfigureBrush() ) { gluTessBeginPolygon(tobj, NULL); int prev = 0; for( int j = 0; j < n; j++ ) { gluTessBeginContour(tobj); for( int i = 0; i < npoints[j]; i++ ) { GLvertex* vertex = new GLvertex(); gTesselatorVertices.Add( vertex ); vertex->info.x = (GLdouble) points[i + prev].x; vertex->info.y = (GLdouble) points[i + prev].y; vertex->info.z = (GLdouble) 0.0; vertex->info.r = (GLdouble) 0.0; vertex->info.g = (GLdouble) 0.0; vertex->info.b = (GLdouble) 0.0; vertex->info.a = (GLdouble) 0.0; gluTessVertex( tobj, (GLdouble*)vertex, (GLdouble*)vertex ); } gluTessEndContour( tobj ); prev += npoints[j]; } gluTessEndPolygon(tobj); } gluDeleteTess(tobj); for (unsigned int i = 0; i<gTesselatorVertices.Count(); i++) delete (GLvertex*)gTesselatorVertices.Item(i); gTesselatorVertices.Clear(); } #endif }
Triangulate::Result Triangulate::Process(const WindingRule& windingRule) { if (!mTesselator) { util::LogMessage(1, "tesselation error: unable to create tesselator"); // log the error } mVertices.clear(); // ensure no vertices exist from previous triangulation mIndices.clear(); // ensure no indices exist from previous triangulation FreeNewVertices(); // ensure no new vertices exist from previous triangulation gluTessProperty(mTesselator, GLU_TESS_BOUNDARY_ONLY, GL_FALSE); gluTessProperty(mTesselator, GLU_TESS_WINDING_RULE, static_cast<unsigned int>(windingRule)); try { unsigned int iter = 0u; gluTessBeginPolygon(mTesselator, (void*)this); for (auto contour = mContours.begin(); contour != mContours.end(); ++contour) { gluTessBeginContour(mTesselator); for (auto point = contour->begin(); point != contour->end(); ++point) { gluTessVertex(mTesselator, &((*point)[0]), &(*point)); ++iter; } gluTessEndContour(mTesselator); } gluTessEndPolygon(mTesselator); } catch (std::exception& e) { } FreeNewVertices(); // clean up new vertices return std::make_pair(mVertices, mIndices); }
void tesselate_contour (GLUtesselator *tobj, PLINE *contour, GLdouble *vertices, double scale) { VNODE *vn = &contour->head; int offset = 0; /* If the contour is round, and hidgl_fill_circle would use * less slices than we have vertices to draw it, then call * hidgl_fill_circle to draw this contour. */ if (contour->is_round) { double slices = calc_slices (contour->radius / scale, 2 * M_PI); if (slices < contour->Count) { hidgl_fill_circle (contour->cx, contour->cy, contour->radius, scale); return; } } gluTessBeginPolygon (tobj, NULL); gluTessBeginContour (tobj); do { vertices [0 + offset] = vn->point[0]; vertices [1 + offset] = vn->point[1]; vertices [2 + offset] = 0.; gluTessVertex (tobj, &vertices [offset], &vertices [offset]); offset += 3; } while ((vn = vn->next) != &contour->head); gluTessEndContour (tobj); gluTessEndPolygon (tobj); }
void hidgl_fill_polygon (int n_coords, Coord *x, Coord *y) { int i; GLUtesselator *tobj; GLdouble *vertices; assert (n_coords > 0); vertices = malloc (sizeof(GLdouble) * n_coords * 3); tobj = gluNewTess (); gluTessCallback(tobj, GLU_TESS_BEGIN, (_GLUfuncptr)myBegin); gluTessCallback(tobj, GLU_TESS_VERTEX, (_GLUfuncptr)myVertex); gluTessCallback(tobj, GLU_TESS_COMBINE, (_GLUfuncptr)myCombine); gluTessCallback(tobj, GLU_TESS_ERROR, (_GLUfuncptr)myError); gluTessBeginPolygon (tobj, NULL); gluTessBeginContour (tobj); for (i = 0; i < n_coords; i++) { vertices [0 + i * 3] = x[i]; vertices [1 + i * 3] = y[i]; vertices [2 + i * 3] = 0.; gluTessVertex (tobj, &vertices [i * 3], &vertices [i * 3]); } gluTessEndContour (tobj); gluTessEndPolygon (tobj); gluDeleteTess (tobj); myFreeCombined (); free (vertices); }
/*ARGSUSED*/ void GLAPIENTRY gluNextContour( GLUtesselator *tess, GLenum type ) { UNUSED_VAR(type); gluTessEndContour( tess ); gluTessBeginContour( tess ); }
void drawFace(Face* face){ //glClear(GL_STENCIL_BUFFER_BIT); GLUtesselator* tess = tesser(); if (!tess) return; gluTessBeginPolygon(tess,NULL); Loop* firLp = face->fLoops; Loop* tmpLp = firLp; do{ HalfEdge* firHe = tmpLp->lHalfEdges; HalfEdge* tmpHe = firHe; gluTessBeginContour(tess); do{ gluTessVertex(tess, tmpHe->heStartVertex->point.pos, tmpHe->heStartVertex->point.pos); glNormal3dv(face->normal.pos); //以下注释的函数不知道为什么是错的,总之传进去的法向量有问题。再显示的时候不对。使用上面的函数传就可以了。 /*gluTessNormal(tess, tmpHe->heStartVertex->normal.pos[0], tmpHe->heStartVertex->normal.pos[1], tmpHe->heStartVertex->normal.pos[2]);*/ tmpHe = tmpHe->nxtHalfEdge; }while(tmpHe != firHe); gluTessEndContour(tess); tmpLp = tmpLp->nxtLoop; }while(tmpLp != firLp); gluTessEndPolygon(tess); }
static void runTesselator(value contours) { CAMLparam1(contours); gluTessBeginPolygon(tobj, NULL); while (contours != Val_int(0)) { value contour=Field(contours, 0); gluTessBeginContour(tobj); while (contour != Val_int(0)) { value v=Field(contour, 0); GLdouble *r = new_vertex(Double_val(Field(v, 0)), Double_val(Field(v, 1)), Double_val(Field(v, 2))); gluTessVertex(tobj, r, (void *)r); contour = Field(contour, 1); } contours = Field(contours, 1); gluTessEndContour(tobj); } gluTessEndPolygon(tobj); gluDeleteTess(tobj); tobj = NULL; free_chunks(); CAMLreturn0; }
void drawTexturedPolyhedron(carve::mesh::MeshSet<3> *poly, carve::interpolate::FaceVertexAttr<tex_t> &fv_tex, carve::interpolate::FaceAttr<GLuint> &f_tex_num) { glEnable(GL_TEXTURE_2D); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); GLUtesselator *tess = gluNewTess(); gluTessCallback(tess, GLU_TESS_BEGIN, (GLUTessCallback)glBegin); gluTessCallback(tess, GLU_TESS_VERTEX_DATA, (GLUTessCallback)tess_vertex); gluTessCallback(tess, GLU_TESS_END, (GLUTessCallback)glEnd); for (carve::mesh::MeshSet<3>::face_iter i = poly->faceBegin(); i != poly->faceEnd(); ++i) { carve::mesh::MeshSet<3>::face_t *f = *i; std::vector<vt_t> vc(f->nVertices()); bool textured = true; for (carve::mesh::MeshSet<3>::face_t::edge_iter_t e = f->begin(); e != f->end(); ++e) { vc[e.idx()].x = g_scale * (e->vert->v.x + g_translation.x); vc[e.idx()].y = g_scale * (e->vert->v.y + g_translation.y); vc[e.idx()].z = g_scale * (e->vert->v.z + g_translation.z); if (fv_tex.hasAttribute(f, e.idx())) { tex_t t = fv_tex.getAttribute(f, e.idx()); vc[e.idx()].u = t.u; vc[e.idx()].v = t.v; } else { textured = false; } } if (textured) { GLuint tex_num = f_tex_num.getAttribute(f, 0); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, tex_num); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } else { glColor4f(0.5f, 0.6f, 0.7f, 1.0f); } glNormal3dv(f->plane.N.v); gluTessBeginPolygon(tess, (void *)&textured); gluTessBeginContour(tess); for (size_t j = 0; j != vc.size(); ++j) { gluTessVertex(tess, (GLdouble *)&vc[j], (GLvoid *)&vc[j]); } gluTessEndContour(tess); gluTessEndPolygon(tess); } gluDeleteTess(tess); glDisable(GL_TEXTURE_2D); }
void GLHelper::drawFilledPolyTesselated(const PositionVector& v, bool close) { if (v.size() == 0) { return; } GLUtesselator* tobj = gluNewTess(); gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(APIENTRY*)()) &glVertex3dv); gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(APIENTRY*)()) &glBegin); gluTessCallback(tobj, GLU_TESS_END, (GLvoid(APIENTRY*)()) &glEnd); gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(APIENTRY*)()) &combCallback); gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD); gluTessBeginPolygon(tobj, nullptr); gluTessBeginContour(tobj); double* points = new double[(v.size() + int(close)) * 3]; for (int i = 0; i != (int)v.size(); ++i) { points[3 * i] = v[i].x(); points[3 * i + 1] = v[i].y(); points[3 * i + 2] = 0; gluTessVertex(tobj, points + 3 * i, points + 3 * i); } if (close) { const int i = (int)v.size(); points[3 * i] = v[0].x(); points[3 * i + 1] = v[0].y(); points[3 * i + 2] = 0; gluTessVertex(tobj, points + 3 * i, points + 3 * i); } gluTessEndContour(tobj); gluTessEndPolygon(tobj); gluDeleteTess(tobj); delete[] points; }
void g::render_level::compile_displaylist(const level& lev) { // clear for(vbos_t::iterator it = vbos.begin(); it != vbos.end(); it++) glDeleteBuffers(1, &it->first.first); vbos.clear(); sizes.clear(); // set vertex data typedef std::vector<std::vector<GLdouble*> > vertices_t; vertices_t vertices; for(level::polygon_container::const_iterator it = lev.polygons.begin(); it != lev.polygons.end(); it++) { vertices.push_back(std::vector<GLdouble*>()); for(level::vertex_container::const_iterator jt = it->begin(); jt != it->end(); jt++) { GLdouble* vertex = new GLdouble[3]; vertex[0] = jt->x(); vertex[1] = jt->y(); vertex[2] = 0.0; vertices.back().push_back(vertex); } } // set glu tesselator typedef void (CALLBACK* func)(); GLUtesselator* tess = gluNewTess(); BOOST_ASSERT(tess != NULL); gluTessCallback(tess, GLU_TESS_BEGIN, (func)tessbegin); gluTessCallback(tess, GLU_TESS_END, (func)tessend); gluTessCallback(tess, GLU_TESS_ERROR, (func)tesserror); gluTessCallback(tess, GLU_TESS_VERTEX, (func)tessvertex); // add to vbo for(vertices_t::iterator it = vertices.begin(); it != vertices.end(); it++) { gluTessBeginPolygon(tess, NULL); gluTessBeginContour(tess); for(vertices_t::value_type::iterator jt = it->begin(); jt != it->end(); jt++) gluTessVertex(tess, *jt, *jt); gluTessEndContour(tess); gluTessEndPolygon(tess); } for(vbos_t::iterator it = vbos.begin(); it != vbos.end(); it++) { glBindBuffer(GL_ARRAY_BUFFER, it->first.first); glBufferData(GL_ARRAY_BUFFER, it->second.size() * sizeof(GLdouble), it->second.data(), GL_STATIC_DRAW); } // cleanup gluDeleteTess(tess); for(vertices_t::iterator it = vertices.begin(); it != vertices.end(); it++) for(vertices_t::value_type::iterator jt = it->begin(); jt != it->end(); jt++) delete [] *jt; for(vbos_t::iterator it = vbos.begin(); it != vbos.end(); it++) { sizes.push_back(it->second.size()); it->second.clear(); } }
gboolean on_expose(GtkWidget *drawing, GdkEventExpose *event, gpointer _) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-1,1, -1,1, 10,-10); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glTranslatef(0, 0, -5); glEnable(GL_COLOR_MATERIAL); glDisable(GL_TEXTURE_2D); glColor3f(1.0, 1.0, 1.0); /* Create vertexes */ double verts[20][3]; for (int i = 0; i < G_N_ELEMENTS(verts); i++) { float ang = 2*G_PI * i / G_N_ELEMENTS(verts); verts[i][0] = sin(ang) * (i%2+0.5) * 0.6; verts[i][1] = cos(ang) * (i%2+0.5) * 0.6; verts[i][2] = 0; } /* Draw raw polygon */ glColor4f(0.5, 0.0, 0.0, 1.0); GLUtesselator *tess = gluNewTess(); gluTessCallback(tess, GLU_TESS_BEGIN, glBegin); gluTessCallback(tess, GLU_TESS_VERTEX, glVertex3dv); gluTessCallback(tess, GLU_TESS_END, glEnd); gluTessBeginPolygon(tess, NULL); gluTessBeginContour(tess); for (int i = 0; i < G_N_ELEMENTS(verts); i++) gluTessVertex(tess, verts[i], verts[i]); gluTessEndContour(tess); gluTessEndPolygon(tess); gluDeleteTess(tess); /* Draw tesselated polygon */ //glColor4f(0.0, 0.0, 0.5, 1.0); //glBegin(GL_POLYGON); //for (int i = 0; i < G_N_ELEMENTS(verts); i++) // glVertex3dv(verts[i]); //glEnd(); /* Draw outline */ glColor4f(0.8, 0.8, 0.8, 1.0); glBegin(GL_LINE_LOOP); for (int i = 0; i < G_N_ELEMENTS(verts); i++) glVertex3dv(verts[i]); glEnd(); /* Flush */ GdkGLDrawable *gldrawable = gdk_gl_drawable_get_current(); if (gdk_gl_drawable_is_double_buffered(gldrawable)) gdk_gl_drawable_swap_buffers(gldrawable); else glFlush(); return FALSE; }
int erl_tess_impl(char* buff, ErlDrvPort port, ErlDrvTermData caller) { ErlDrvBinary* bin; int i; int num_vertices; GLdouble *n; int AP; int a_max = 2; int i_max = 6; num_vertices = * (int *) buff; buff += 8; /* Align */ n = (double *) buff; buff += 8*3; egl_tess.alloc_max = a_max*num_vertices*3; bin = driver_alloc_binary(egl_tess.alloc_max*sizeof(GLdouble)); egl_tess.error = 0; egl_tess.tess_coords = (double *) bin->orig_bytes; memcpy(egl_tess.tess_coords,buff,num_vertices*3*sizeof(GLdouble)); egl_tess.index_max = i_max*3*num_vertices; egl_tess.tess_index_list = (int *) driver_alloc(sizeof(int) * egl_tess.index_max); egl_tess.tess_coords = (double *) bin->orig_bytes; egl_tess.index_n = 0; egl_tess.alloc_n = num_vertices*3; gluTessNormal(tess, n[0], n[1], n[2]); gluTessBeginPolygon(tess, 0); gluTessBeginContour(tess); for (i = 0; i < num_vertices; i++) { gluTessVertex(tess, egl_tess.tess_coords+3*i, egl_tess.tess_coords+3*i); } gluTessEndContour(tess); gluTessEndPolygon(tess); AP = 0; ErlDrvTermData *rt; rt = (ErlDrvTermData *) driver_alloc(sizeof(ErlDrvTermData) * (13+egl_tess.index_n*2)); rt[AP++]=ERL_DRV_ATOM; rt[AP++]=driver_mk_atom((char *) "_egl_result_"); for(i=0; i < egl_tess.index_n; i++) { rt[AP++] = ERL_DRV_INT; rt[AP++] = (int) egl_tess.tess_index_list[i]; }; rt[AP++] = ERL_DRV_NIL; rt[AP++] = ERL_DRV_LIST; rt[AP++] = egl_tess.index_n+1; rt[AP++] = ERL_DRV_BINARY; rt[AP++] = (ErlDrvTermData) bin; rt[AP++] = egl_tess.alloc_n*sizeof(GLdouble); rt[AP++] = 0; rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Return tuple {list, Bin} rt[AP++] = ERL_DRV_TUPLE; rt[AP++] = 2; // Result tuple driver_send_term(port,caller,rt,AP); /* fprintf(stderr, "List %d: %d %d %d \r\n", */ /* res, */ /* n_pos, */ /* (tess_alloc_vertex-new_vertices)*sizeof(GLdouble), */ /* num_vertices*6*sizeof(GLdouble)); */ driver_free_binary(bin); driver_free(egl_tess.tess_index_list); driver_free(rt); return 0; }
/*ARGSUSED*/ void GLAPIENTRY gluNextContour( GLUtesselator *tess, GLenum type ) { (void)type; gluTessEndContour( tess ); gluTessBeginContour( tess ); }
void glu_tessbegincontour( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { MOGLDEFMYTESS; if (NULL == gluTessBeginContour) mogl_glunsupported("gluTessBeginContour"); gluTessBeginContour((GLUtesselator*) mytess->glutesselator); }
static void hugsprim_gluTessBeginContour_4(HugsStackPtr hugs_root) { HsPtr arg1; arg1 = hugs->getPtr(); gluTessBeginContour(arg1); hugs->returnIO(hugs_root,0); }
static void draw_polygon(struct graphics_priv *gr, struct graphics_gc_priv *gc, struct point *p, int count) { int i; if ((gr->parent && !gr->parent->overlay_enabled) || (gr->parent && gr->parent->overlay_enabled && !gr->overlay_enabled)) { return; } #if USE_OPENGLES set_color(gr, gc); draw_array(gr, p, count, GL_LINE_STRIP); #else graphics_priv_root->dirty = 1; GLUtesselator *tess = gluNewTess(); // create a tessellator if (!tess) return; // failed to create tessellation object, return 0 GLdouble quad1[count][3]; for (i = 0; i < count; i++) { quad1[i][0] = (GLdouble) (p[i].x); quad1[i][1] = (GLdouble) (p[i].y); quad1[i][2] = 0; } // register callback functions gluTessCallback(tess, GLU_TESS_BEGIN, (void (APIENTRY *)(void)) tessBeginCB); gluTessCallback(tess, GLU_TESS_END, (void (APIENTRY *)(void)) tessEndCB); // gluTessCallback(tess, GLU_TESS_ERROR, (void (*)(void))tessErrorCB); gluTessCallback(tess, GLU_TESS_VERTEX, (void (APIENTRY *)(void)) tessVertexCB); gluTessCallback(tess, GLU_TESS_COMBINE, (void (APIENTRY *)(void)) tessCombineCB); // tessellate and compile a concave quad into display list // gluTessVertex() takes 3 params: tess object, pointer to vertex coords, // and pointer to vertex data to be passed to vertex callback. // The second param is used only to perform tessellation, and the third // param is the actual vertex data to draw. It is usually same as the second // param, but It can be more than vertex coord, for example, color, normal // and UV coords which are needed for actual drawing. // Here, we are looking at only vertex coods, so the 2nd and 3rd params are // pointing same address. glColor4f(gc->fr, gc->fg, gc->fb, gc->fa); gluTessBeginPolygon(tess, 0); // with NULL data gluTessBeginContour(tess); for (i = 0; i < count; i++) { gluTessVertex(tess, quad1[i], quad1[i]); } gluTessEndContour(tess); gluTessEndPolygon(tess); gluDeleteTess(tess); // delete after tessellation #endif }
void ocpnDC::DrawPolygonTessellated( int n, wxPoint points[], wxCoord xoffset, wxCoord yoffset ) { if( dc ) dc->DrawPolygon( n, points, xoffset, yoffset ); #ifdef ocpnUSE_GL else { # ifndef ocpnUSE_GLES // tessalator in glues is broken if( n < 5 ) # endif { DrawPolygon( n, points, xoffset, yoffset ); return; } glPushAttrib( GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_LINE_BIT | GL_HINT_BIT | GL_POLYGON_BIT ); //Save state SetGLAttrs( false ); static GLUtesselator *tobj = NULL; if( ! tobj ) tobj = gluNewTess(); gluTessCallback( tobj, GLU_TESS_VERTEX, (_GLUfuncptr) &ocpnDCvertexCallback ); gluTessCallback( tobj, GLU_TESS_BEGIN, (_GLUfuncptr) &ocpnDCbeginCallback ); gluTessCallback( tobj, GLU_TESS_END, (_GLUfuncptr) &ocpnDCendCallback ); gluTessCallback( tobj, GLU_TESS_COMBINE, (_GLUfuncptr) &ocpnDCcombineCallback ); gluTessCallback( tobj, GLU_TESS_ERROR, (_GLUfuncptr) &ocpnDCerrorCallback ); gluTessNormal( tobj, 0, 0, 1); gluTessProperty( tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_NONZERO ); if( ConfigureBrush() ) { gluTessBeginPolygon( tobj, NULL ); gluTessBeginContour( tobj ); for( int i = 0; i < n; i++ ) { GLvertex* vertex = new GLvertex(); gTesselatorVertices.Add( vertex ); vertex->info.x = (GLdouble) points[i].x; vertex->info.y = (GLdouble) points[i].y; vertex->info.z = (GLdouble) 0.0; vertex->info.r = (GLdouble) 0.0; vertex->info.g = (GLdouble) 0.0; vertex->info.b = (GLdouble) 0.0; gluTessVertex( tobj, (GLdouble*)vertex, (GLdouble*)vertex ); } gluTessEndContour( tobj ); gluTessEndPolygon( tobj ); } glPopAttrib(); for( unsigned int i=0; i<gTesselatorVertices.Count(); i++ ) delete (GLvertex*)gTesselatorVertices.Item(i); gTesselatorVertices.Clear(); } #endif }
void Tesselator::addContour(const std::vector<TVec3d>& pts, std::vector<std::vector<TVec2f> > textureCoordinatesLists ) { unsigned int len = pts.size(); if ( len < 3 ) return; for (size_t i = 0; i < textureCoordinatesLists.size(); i++) { std::vector<TVec2f>& texCoords = textureCoordinatesLists.at(i); if (texCoords.size() != pts.size()) { if (!texCoords.empty()) { CITYGML_LOG_ERROR(_logger, "Invalid call to 'addContour'. The number of texture coordinates in list " << i << " (" << texCoords.size() << ") " "does not match the number of vertices (" << pts.size() << "). The texture coordinates list will be resized which may cause invalid texture coordinates."); } texCoords.resize(pts.size(), TVec2f(0.f, 0.f)); } } for (size_t i = 0; i < std::max(_texCoordsLists.size(), textureCoordinatesLists.size()); i++) { if (i >= _texCoordsLists.size()) { std::vector<TVec2f> texCoords(_vertices.size(), TVec2f(0.f, 0.f)); texCoords.insert(texCoords.end(), textureCoordinatesLists.at(i).begin(), textureCoordinatesLists.at(i).end()); _texCoordsLists.push_back(texCoords); } else if (i >= textureCoordinatesLists.size()) { _texCoordsLists.at(i).resize(_texCoordsLists.at(i).size() + pts.size(), TVec2f(0.f, 0.f)); } else { _texCoordsLists.at(i).insert(_texCoordsLists.at(i).end(), textureCoordinatesLists.at(i).begin(), textureCoordinatesLists.at(i).end()); } } unsigned int pos = _vertices.size(); gluTessBeginContour( _tobj ); for ( unsigned int i = 0; i < len; i++ ) { _vertices.push_back( pts[i] ); _indices.push_back(pos + i); gluTessVertex( _tobj, &(_vertices.back()[0]), &_indices.back() ); } gluTessEndContour( _tobj ); #ifndef NDEBUG for (size_t i = 0; i < _texCoordsLists.size(); i++) { assert(_texCoordsLists.at(i).size() == _vertices.size()); } #endif }
// Inserts all contours into the given tesselator; this results in the // renumbering of all vertices from 'start'. Returns the end number. // Take care when using this call since tesselators cannot work on // the internal data concurrently int VRML_LAYER::Import( int start, GLUtesselator* tess ) { if( start < 0 ) { error = "Import(): invalid index ( start < 0 )"; return -1; } if( !tess ) { error = "Import(): NULL tesselator pointer"; return -1; } unsigned int i, j; // renumber from 'start' for( i = 0, j = vertices.size(); i < j; ++i ) { vertices[i]->i = start++; vertices[i]->o = -1; } // push each contour to the tesselator VERTEX_3D* vp; GLdouble pt[3]; std::list<int>::const_iterator cbeg; std::list<int>::const_iterator cend; for( i = 0; i < contours.size(); ++i ) { if( contours[i]->size() < 3 ) continue; cbeg = contours[i]->begin(); cend = contours[i]->end(); gluTessBeginContour( tess ); while( cbeg != cend ) { vp = vertices[ *cbeg++ ]; pt[0] = vp->x; pt[1] = vp->y; pt[2] = 0.0; gluTessVertex( tess, pt, vp ); } gluTessEndContour( tess ); } return start; }
void GFXSystem::startBgPoly() { // glDisable(GL_DEPTH_TEST); glDepthMask(GL_FALSE); glBindTexture(GL_TEXTURE_2D, backTexture); //glBegin(GL_POLYGON); gluTessBeginPolygon(tobj, NULL); gluTessBeginContour(tobj); tesselatePosition = 0; }