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."
This commit is contained in:
Robert Osfield
2012-02-07 11:29:47 +00:00
parent 0775483b7c
commit 52270c9656
2 changed files with 30 additions and 24 deletions

View File

@@ -86,8 +86,6 @@ class OSGUTIL_EXPORT Tessellator : public osg::Referenced
osg::Geometry::PrimitiveSetList getContours() { return _Contours;}
typedef std::vector<osg::Vec3*> 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<Prim> > 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);

View File

@@ -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();