From 52270c965662cd82d0be220c3cd352edf1b363cb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 7 Feb 2012 11:29:47 +0000 Subject: [PATCH] From David Fries, "Of the two ways to use the Tessellator object, only retessellatePolygons was applying the winding and boundary option. Moved the gluTessProperty calls into beginTessellation(). There's a comment typo fix, removing an unused VertexPointList typedef, and allocates one _tobj instead of one per tesellation. Protections were added to check that _tobj was allocated in the few remaining places it wasn't being checked. --- On a side note, I would like to avoid the 'new Vec3d' in Tessellator::addVertex for each call to gluTessVertex(tess, location, data). The RedBook leaves it ambiguous if the location pointer must remain valid after gluTessVertex or not. http://www.opengl.org/sdk/docs/man/xhtml/gluTessVertex.xml says that changing location is not safe, so being conservative, I'll leave it as is, even though the Mesa GLU library copies the data not the pointer, so it is currently safe." --- include/osgUtil/Tessellator | 13 ++++++++---- src/osgUtil/Tessellator.cpp | 41 +++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/include/osgUtil/Tessellator b/include/osgUtil/Tessellator index 4225340ec..d5d8ea861 100644 --- a/include/osgUtil/Tessellator +++ b/include/osgUtil/Tessellator @@ -86,8 +86,6 @@ class OSGUTIL_EXPORT Tessellator : public osg::Referenced osg::Geometry::PrimitiveSetList getContours() { return _Contours;} - typedef std::vector VertexPointList; - struct Prim : public osg::Referenced { Prim(GLenum mode):_mode(mode) {} @@ -101,9 +99,16 @@ class OSGUTIL_EXPORT Tessellator : public osg::Referenced void beginTessellation(); void beginContour(); + + /** Add a vertex to the current contour, see gluTessVertex for details. + * Note the vertex pointer is returned at the end of tessellation and + * must not be left dangling or be overwritten until all results are + * collected. + */ void addVertex(osg::Vec3* vertex); + void endContour(); - + void endTessellation(); typedef std::vector< osg::ref_ptr > PrimList; @@ -114,7 +119,7 @@ class OSGUTIL_EXPORT Tessellator : public osg::Referenced protected: - /** remove unused parts of the array, eg for wehn retessellating + /** remove unused parts of the array, eg for when retessellating * tessellation can introduce extra vertices for concave or crossing boundaries, * these will leak memory if not removed when retessellating. */ void reduceArray(osg::Array * cold, const unsigned int nnu); diff --git a/src/osgUtil/Tessellator.cpp b/src/osgUtil/Tessellator.cpp index e09060d9d..e6bf0081e 100644 --- a/src/osgUtil/Tessellator.cpp +++ b/src/osgUtil/Tessellator.cpp @@ -26,7 +26,15 @@ Tessellator::Tessellator() : _ttype(TESS_TYPE_POLYGONS), _boundaryOnly(false), _numberVerts(0) { - _tobj = 0; + _tobj = gluNewTess(); + if (_tobj) + { + gluTessCallback(_tobj, GLU_TESS_VERTEX_DATA, (GLU_TESS_CALLBACK) vertexCallback); + gluTessCallback(_tobj, GLU_TESS_BEGIN_DATA, (GLU_TESS_CALLBACK) beginCallback); + gluTessCallback(_tobj, GLU_TESS_END_DATA, (GLU_TESS_CALLBACK) endCallback); + gluTessCallback(_tobj, GLU_TESS_COMBINE_DATA,(GLU_TESS_CALLBACK) combineCallback); + gluTessCallback(_tobj, GLU_TESS_ERROR_DATA, (GLU_TESS_CALLBACK) errorCallback); + } _errorCode = 0; _index=0; } @@ -34,22 +42,25 @@ Tessellator::Tessellator() : Tessellator::~Tessellator() { reset(); + if (_tobj) + { + gluDeleteTess(_tobj); + } } void Tessellator::beginTessellation() { reset(); - if (!_tobj) _tobj = gluNewTess(); - - gluTessCallback(_tobj, GLU_TESS_VERTEX_DATA, (GLU_TESS_CALLBACK) vertexCallback); - gluTessCallback(_tobj, GLU_TESS_BEGIN_DATA, (GLU_TESS_CALLBACK) beginCallback); - gluTessCallback(_tobj, GLU_TESS_END_DATA, (GLU_TESS_CALLBACK) endCallback); - gluTessCallback(_tobj, GLU_TESS_COMBINE_DATA,(GLU_TESS_CALLBACK) combineCallback); - gluTessCallback(_tobj, GLU_TESS_ERROR_DATA, (GLU_TESS_CALLBACK) errorCallback); - if (tessNormal.length()>0.0) gluTessNormal(_tobj, tessNormal.x(), tessNormal.y(), tessNormal.z()); + if (_tobj) + { + gluTessProperty(_tobj, GLU_TESS_WINDING_RULE, _wtype); + gluTessProperty(_tobj, GLU_TESS_BOUNDARY_ONLY, _boundaryOnly); + + if (tessNormal.length()>0.0) gluTessNormal(_tobj, tessNormal.x(), tessNormal.y(), tessNormal.z()); - gluTessBeginPolygon(_tobj,this); + gluTessBeginPolygon(_tobj,this); + } } void Tessellator::beginContour() @@ -93,8 +104,6 @@ void Tessellator::endTessellation() if (_tobj) { gluTessEndPolygon(_tobj); - gluDeleteTess(_tobj); - _tobj = 0; if (_errorCode!=0) { @@ -106,12 +115,6 @@ void Tessellator::endTessellation() void Tessellator::reset() { - if (_tobj) - { - gluDeleteTess(_tobj); - _tobj = 0; - } - for (Vec3dList::iterator i = _coordData.begin(); i != _coordData.end(); ++i) { delete (*i); @@ -222,8 +225,6 @@ void Tessellator::retessellatePolygons(osg::Geometry &geom) // occurs around the whole set of contours. if (_ttype==TESS_TYPE_GEOMETRY) { beginTessellation(); - gluTessProperty(_tobj, GLU_TESS_WINDING_RULE, _wtype); - gluTessProperty(_tobj, GLU_TESS_BOUNDARY_ONLY , _boundaryOnly); } // process all the contours into the Tessellator int noContours = _Contours.size();