void Opengl2dPainter::drawPolygon(const POINT2F* pPoints, INT count, bool bFill) { /// opengl tesselation if (bFill) gluTessProperty(_pPimpl->pTesslation, GLU_TESS_BOUNDARY_ONLY, false); else gluTessProperty(_pPimpl->pTesslation, GLU_TESS_BOUNDARY_ONLY, true); VERTEX_EDGE v; std::vector<VERTEX_EDGE> vertices; vertices.reserve(count+1); gluTessBeginPolygon(_pPimpl->pTesslation, NULL); gluTessBeginContour(_pPimpl->pTesslation); gluNextContour(_pPimpl->pTesslation, GLU_EXTERIOR); for (int i=0; i< count; ++i) { v.x = pPoints[i].x; v.y = pPoints[i].y; v.z = 0; vertices.push_back(v); gluTessVertex(_pPimpl->pTesslation, (double*)&vertices[i], (void*) &vertices[i]); } v.x = pPoints[0].x; v.y = pPoints[0].y; v.z = 0; vertices.push_back(v); gluTessVertex(_pPimpl->pTesslation, (double*)&vertices[count],(void*) &vertices[count]); gluTessEndContour(_pPimpl->pTesslation); gluTessEndPolygon(_pPimpl->pTesslation); }
/* 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(); }
void XMGPolygon::SetCoordArray ( const XMGVector2X* src_arr_coord, XMGTexUnit unit, GLuint src_idx_shape, GLuint src_idx_facet ) { XMGPolygonImpl* impl = (XMGPolygonImpl *) m_impl; XMGRenderImpl* impl_parent = (XMGRenderImpl *) XMGRender::m_impl; XMGTess* data; XMGShape* shape; XMGFacet* facet; GLuint idx_tess; GLuint idx_shape; GLuint idx_facet; GLuint idx_vertex; GLuint num_shape; GLuint num_facet; GLuint num_vertex; GLuint off_src; XMGVector2F* farr_coord; XMGVector2X* xarr_coord; XMGRender::SetCoordArray ( src_arr_coord, unit, src_idx_shape, src_idx_facet ); if ( impl_parent->m_has_face[ 0 ] == XMG_FALSE && impl_parent->m_has_face[ 1 ] ) { return; } if ( src_idx_facet != XMG_FACET_ALL ) { shape = impl_parent->m_vec_shape[ src_idx_facet ]; facet = shape->m_vec_facet[ src_idx_facet ]; if ( facet->m_vec_contour.size ( ) == 0 ) { return; } } off_src = 0; for ( impl_parent->RangeArray ( src_idx_shape, impl_parent->m_vec_shape.size ( ), idx_shape, num_shape ); idx_shape < num_shape; idx_shape++ ) { shape = impl_parent->m_vec_shape[ idx_shape ]; for ( impl_parent->RangeArray ( src_idx_facet, shape->m_vec_facet.size ( ), idx_facet, num_facet ); idx_facet < num_facet; idx_facet++ ) { facet = shape->m_vec_facet[ idx_facet ]; if ( idx_facet < 2 ) { switch ( impl_parent->m_geo_type ) { case XMG_GEO_CONE : case XMG_GEO_CWALL : idx_tess = 1; break; default : idx_tess = idx_facet; break; } if ( impl->m_tess[ idx_tess ] ) { data = impl->m_data[ idx_tess ][ idx_shape ]; data->Init ( XMG_TESS_COORD ); gluTessBeginPolygon ( impl->m_tess[ idx_tess ], (GLvoid *) data ); gluTessBeginContour ( impl->m_tess[ idx_tess ] ); for ( idx_vertex = 0, num_vertex = shape->m_num_basic; idx_vertex < num_vertex; idx_vertex++ ) { data->m_arr_vertex[ idx_vertex * 8 + 6 ] = XMG_X2F ( src_arr_coord[ off_src + idx_vertex ].m_x ); data->m_arr_vertex[ idx_vertex * 8 + 7 ] = XMG_X2F ( src_arr_coord[ off_src + idx_vertex ].m_y ); if ( shape->m_idx_hole != 0 && shape->m_idx_hole == idx_vertex ) { gluNextContour ( impl->m_tess[ idx_tess ], GLU_INTERIOR ); } gluTessVertex ( impl->m_tess[ idx_tess ], &data->m_arr_vertex[ idx_vertex * 8 ], &data->m_arr_vertex[ idx_vertex * 8 ] ); } gluTessEndContour ( impl->m_tess[ idx_tess ] ); gluTessEndPolygon ( impl->m_tess[ idx_tess ] ); if ( impl_parent->m_type_coords[ unit ] == XMG_TYPE_FLOAT ) { XMGAssert ( farr_coord = (XMGVector2F *) kdMalloc ( sizeof ( XMGVector2F ) * facet->m_num_ext ) ); for ( idx_vertex = 0, num_vertex = facet->m_num_ext; idx_vertex < num_vertex; idx_vertex++ ) { farr_coord[ idx_vertex ] = data->m_vec_coord[ idx_vertex ]; } impl_parent->SetBuffer ( impl_parent->m_id_coords[ unit ], farr_coord, sizeof ( XMGVector2F ) * facet->m_off_ext, sizeof ( XMGVector2F ) * facet->m_num_ext ); kdFree ( farr_coord ); } else { XMGAssert ( xarr_coord = (XMGVector2X *) kdMalloc ( sizeof ( XMGVector2X ) * facet->m_num_ext ) ); for ( idx_vertex = 0, num_vertex = facet->m_num_ext; idx_vertex < num_vertex; idx_vertex++ ) { xarr_coord[ idx_vertex ] = data->m_vec_coord[ idx_vertex ]; } impl_parent->SetBuffer ( impl_parent->m_id_coords[ unit ], xarr_coord, sizeof ( XMGVector2X ) * facet->m_off_ext, sizeof ( XMGVector2X ) * facet->m_num_ext ); kdFree ( xarr_coord ); } } } off_src += facet->m_num_vertex; } } }
void XMGPolygon::SetVertexArray ( const XMGVector3X* src_arr_vertex, const GLuint* arr_idx_hole ) { XMGPolygonImpl* impl = (XMGPolygonImpl *) m_impl; XMGRenderImpl* impl_parent = (XMGRenderImpl *) XMGRender::m_impl; XMGTess* data[2]; XMGShape* shape; XMGFacet* facet; XMGContour* contour; GLuint idx_tess; GLuint idx_shape; GLuint idx_facet; GLuint idx_vertex; GLuint idx_vec; GLuint num_shape; GLuint num_vertex; GLuint num_vec; GLuint off_vertex; GLuint off_ext; XMGVector3X src_vertex; XMGVector3X* arr_vertex; off_vertex = 0; off_ext = impl_parent->m_num_vertex; impl_parent->m_ext_vertex = 0; for ( idx_shape = 0, num_shape = impl_parent->m_vec_shape.size ( ); idx_shape < num_shape; idx_shape++ ) { shape = impl_parent->m_vec_shape[ idx_shape ]; shape->m_idx_hole = arr_idx_hole ? arr_idx_hole[ idx_shape ] : XMG_HOLE_NULL; // Set tess vertices if ( impl->m_tess[ 0 ] || impl->m_tess[ 1 ] ) { for ( idx_tess = 0; idx_tess < 2; idx_tess++ ) { if ( impl->m_tess[ idx_tess ] ) { data[ idx_tess ] = impl->m_data[ idx_tess ][ idx_shape ]; data[ idx_tess ]->Init ( XMG_TESS_VERTEX ); gluTessBeginPolygon ( impl->m_tess[ idx_tess ], (GLvoid *) data[ idx_tess ] ); gluTessBeginContour ( impl->m_tess[ idx_tess ] ); } } for ( idx_vertex = 0, num_vertex = shape->m_num_basic; idx_vertex < num_vertex; idx_vertex++ ) { for ( idx_tess = 0; idx_tess < 2; idx_tess++ ) { if ( idx_tess == 0 ) { if ( impl->m_tess[ idx_tess ] ) { src_vertex = src_arr_vertex[ off_vertex + idx_vertex ]; } else { continue; } } else if ( idx_tess == 1 ) { if ( impl->m_tess[ idx_tess ] ) { switch ( impl_parent->m_geo_type ) { case XMG_GEO_SOLID : src_vertex = src_arr_vertex[ off_vertex + num_vertex + idx_vertex ]; break; case XMG_GEO_BSOLID : if ( shape->m_idx_hole ) { src_vertex = src_arr_vertex[ idx_vertex < shape->m_idx_hole ? shape->m_idx_hole - idx_vertex - 1 : num_vertex + shape->m_idx_hole - idx_vertex - 1 ]; } else { src_vertex = src_arr_vertex[ num_vertex - idx_vertex - 1 ]; } src_vertex.m_z = 0; break; } } else { continue; } } data[ idx_tess ]->m_arr_vertex[ idx_vertex * 8 + 0 ] = XMG_X2F ( src_vertex.m_x ); data[ idx_tess ]->m_arr_vertex[ idx_vertex * 8 + 1 ] = XMG_X2F ( src_vertex.m_y ); data[ idx_tess ]->m_arr_vertex[ idx_vertex * 8 + 2 ] = XMG_X2F ( src_vertex.m_z ); if ( shape->m_idx_hole != 0 && shape->m_idx_hole == idx_vertex ) { gluNextContour ( impl->m_tess[ idx_tess ], GLU_INTERIOR ); } gluTessVertex ( impl->m_tess[ idx_tess ], &data[ idx_tess ]->m_arr_vertex[ idx_vertex * 8 ], &data[ idx_tess ]->m_arr_vertex[ idx_vertex * 8 ] ); } } idx_facet = 0; for ( idx_tess = 0; idx_tess < 2; idx_tess++ ) { if ( impl->m_tess[ idx_tess ] ) { gluTessEndContour ( impl->m_tess[ idx_tess ] ); gluTessEndPolygon ( impl->m_tess[ idx_tess ] ); // Set contours with original facet = shape->m_vec_facet[ idx_facet ]; facet->ClearContour ( ); if ( shape->m_idx_hole == XMG_HOLE_NULL ) { XMGAssert ( contour = new XMGContour ( ) ); contour->m_draw_limit = XMG_LIMIT_LINE; contour->m_off_vertex = facet->m_off_vertex; contour->m_num_vertex = facet->m_num_vertex; facet->m_vec_contour.push_back ( contour ); } else { XMGAssert ( contour = new XMGContour ( ) ); contour->m_draw_limit = XMG_LIMIT_LINE; contour->m_off_vertex = facet->m_off_vertex; contour->m_num_vertex = shape->m_idx_hole; facet->m_vec_contour.push_back ( contour ); XMGAssert ( contour = new XMGContour ( ) ); contour->m_draw_limit = XMG_LIMIT_LINE; contour->m_off_vertex = facet->m_off_vertex + shape->m_idx_hole; contour->m_num_vertex = facet->m_num_vertex - shape->m_idx_hole; facet->m_vec_contour.push_back ( contour ); } // Set contours with tessed facet->m_off_ext = off_ext; for ( idx_vec = 0, num_vec = data[ idx_tess ]->m_vec_num_vertex.size ( ); idx_vec < num_vec; idx_vec++ ) { XMGAssert ( contour = new XMGContour ( ) ); contour->m_draw_limit = XMG_LIMIT_TRI; contour->m_disp_mode = data[ idx_tess ]->m_vec_mode[ idx_vec ]; contour->m_off_vertex = off_ext; contour->m_num_vertex = data[ idx_tess ]->m_vec_num_vertex[ idx_vec ]; facet->m_vec_contour.push_back ( contour ); off_ext += contour->m_num_vertex; } idx_facet++; facet->m_num_ext = data[ idx_tess ]->m_vec_vertex.size ( ); impl_parent->m_ext_vertex += facet->m_num_ext; } } } off_vertex += shape->m_num_input; } XMGRender::SetVertexArray ( src_arr_vertex, XMG_SHAPE_ALL ); if ( impl->m_tess[ 0 ] || impl->m_tess[ 1 ] ) { off_vertex = 0; num_vertex = impl_parent->m_ext_vertex; XMGAssert ( arr_vertex = (XMGVector3X *) kdMalloc ( sizeof ( XMGVector3X ) * num_vertex ) ); for ( idx_shape = 0, num_shape = impl_parent->m_vec_shape.size ( ); idx_shape < num_shape; idx_shape++ ) { for ( idx_tess = 0; idx_tess < 2; idx_tess++ ) { if ( impl->m_tess[ idx_tess ] ) { data[ idx_tess ] = impl->m_data[ idx_tess ][ idx_shape ]; for ( idx_vertex = 0, num_vertex = data[ idx_tess ]->m_vec_vertex.size ( ); idx_vertex < num_vertex; idx_vertex++ ) { arr_vertex[ off_vertex ] = data[ idx_tess ]->m_vec_vertex[ idx_vertex ]; off_vertex++; } data[ idx_tess ]->ClearVector ( ); } } } impl_parent->SetBuffer ( impl_parent->m_id_vertex, arr_vertex, sizeof ( XMGVector3X ) * impl_parent->m_num_vertex, sizeof ( XMGVector3X ) * impl_parent->m_ext_vertex ); kdFree ( arr_vertex ); } }
void gluauxNextContour (GLUtriangulatorObj* tessobj, GLenum type) { current(tessobj); gluNextContour(tessobj,type); }
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); }