With
GLU_TESS_*_DATA
, the user-specified data may be used for "per-polygon" data.
Use private static member functions as callbacks and pass in your instance pointer through user_data
.
Inside each callback you can static_cast<>
the user_data
pointer to your Polygon
type and manipulate the resulting instance as desired.
Something like this:
class Poly
{
public:
Poly( vector< dvec3 >& poly )
{
GLUtesselator* tess = gluNewTess();
gluTessCallback( tess, GLU_TESS_BEGIN, (GLvoid (CALLBACK *)()) Poly::begin );
gluTessCallback( tess, GLU_TESS_EDGE_FLAG, (GLvoid (CALLBACK *)()) Poly::edgeFlag );
gluTessCallback( tess, GLU_TESS_END, (GLvoid (CALLBACK *)()) Poly::end );
gluTessCallback( tess, GLU_TESS_VERTEX_DATA, (GLvoid (CALLBACK *)()) Poly::vertexData );
gluTessCallback( tess, GLU_TESS_COMBINE_DATA, (GLvoid (CALLBACK *)()) Poly::combineData );
gluTessNormal( tess, 0.0, 0.0, 1.0 );
gluTessBeginPolygon( tess, (void*)this );
gluTessBeginContour( tess );
for( size_t i = 0; i < poly.size(); ++i )
{
gluTessVertex( tess, &poly[i][0], &poly[i] );
}
gluTessEndContour( tess );
gluTessEndPolygon( tess );
gluDeleteTess(tess);
for( size_t i = 0; i < mCombined.size(); ++i )
{
delete mCombined[i];
}
mCombined.clear();
}
void Render()
{
glBegin( GL_TRIANGLES );
for( size_t i = 0; i < mTriangles.size(); ++i )
{
glVertex3dv( &mTriangles[i][0] );
}
glEnd();
}
private:
static void begin( GLenum type ) {}
static void edgeFlag( GLboolean flag ) {}
static void end() {}
static void vertexData( void *vertex_data, void *polygon_data )
{
Poly& p = *static_cast< Poly* >( polygon_data );
dvec3& pt = *static_cast< dvec3* >( vertex_data );
p.mTriangles.push_back( pt );
}
static void combineData( GLdouble coords[3], void *vertex_data[4], GLfloat weight[4], void **outData, void *polygon_data )
{
Poly& p = *static_cast< Poly* >( polygon_data );
dvec3* newVert = new dvec3();
(*newVert)[0] = coords[0];
(*newVert)[1] = coords[1];
(*newVert)[2] = coords[2];
p.mCombined.push_back( newVert );
*outData = newVert;
}
vector< dvec3 > mTriangles;
vector< dvec3* > mCombined;
};