4

It's pretty hard to render the data I generate, if I want to use one vertex array format only.

I tried to provide GLU_TESS_EDGE_FLAG_DATA callback, but it made my program crash. (also tried without "_DATA" in end, same effect).

How can I get it to generate GL_TRIANGLES only?

Rookie
  • 4,064
  • 6
  • 54
  • 86

1 Answers1

6

gluTessCallback(), GLU_TESS_EDGE_FLAG:

... if a non-NULL edge flag callback is provided ... fans and strips are converted to independent triangles.

This is what I've been using:

struct TessContext
{
    ~TessContext()
    {
        for( size_t i = 0; i < combined.size(); ++i )
        {
            delete[] combined[i];
        }
    }

    typedef std::pair< double, double > Point;
    std::vector< Point > pts;
    std::vector< GLdouble* > combined;
};

#ifndef CALLBACK
#define CALLBACK __stdcall
#endif

void CALLBACK tess_begin( GLenum ) {}
void CALLBACK tess_edgeFlag( GLboolean ) {}
void CALLBACK tess_end() {}

void CALLBACK tess_vertex
    ( 
    void*           data, 
    TessContext*    ctx 
    )
{
    GLdouble* coord = (GLdouble*)data;
    ctx->pts.push_back( TessContext::Point( coord[0], coord[1] ) );
}

void CALLBACK tess_combine
    ( 
    GLdouble        coords[3], 
    void*           vertex_data[4], 
    GLfloat         weight[4], 
    void**          outData, 
    TessContext*    ctx 
    )
{
    GLdouble* newVert = new GLdouble[3];
    ctx->combined.push_back( newVert );

    newVert[0] = coords[0];
    newVert[1] = coords[1];
    newVert[2] = coords[2];
    *outData = newVert;
}

template< typename Vec >
std::vector< Vec > Triangulate
    ( 
    const vector< Vec >& aSimplePolygon
    )
{
    std::vector< GLdouble > coords;
    for( size_t i = 0; i < aSimplePolygon.size(); ++i )
    {
        coords.push_back( aSimplePolygon[i].x() );
        coords.push_back( aSimplePolygon[i].y() );
        coords.push_back( 0 );
    }

    GLUtesselator* tess = gluNewTess();
    gluTessCallback( tess, GLU_TESS_BEGIN,          (void (CALLBACK *)())   tess_begin      );
    gluTessCallback( tess, GLU_TESS_EDGE_FLAG,      (void (CALLBACK *)())   tess_edgeFlag   );
    gluTessCallback( tess, GLU_TESS_VERTEX_DATA,    (void (CALLBACK *)())   tess_vertex     );
    gluTessCallback( tess, GLU_TESS_END,            (void (CALLBACK *)())   tess_end        );
    gluTessCallback( tess, GLU_TESS_COMBINE_DATA,   (void (CALLBACK *)())   tess_combine    );
    gluTessNormal( tess, 0.0, 0.0, 1.0 );

    TessContext ctx;

    gluTessBeginPolygon( tess, &ctx );
    gluTessBeginContour( tess );

    for( size_t i = 0; i < aSimplePolygon.size(); ++i )
    {
        gluTessVertex( tess, &coords[i*3], &coords[i*3] );
    }

    gluTessEndContour( tess );
    gluTessEndPolygon( tess );

    gluDeleteTess(tess);

    std::vector< Vec > ret( ctx.pts.size() );
    for( size_t i = 0; i < ret.size(); ++i )
    {
        ret[i].x() = static_cast< Vec::Scalar >( ctx.pts[i].first );
        ret[i].y() = static_cast< Vec::Scalar >( ctx.pts[i].second );
    }

    return ret;
}

I tend to use Eigen::Vector2f for Vec.

genpfault
  • 51,148
  • 11
  • 85
  • 139
  • Looks like i had wrong parameter type: `void`. Is that vector method for storing the coords safe to use? The clipper lib which im using, is creating the pointers with new[] for each point, and then freeing it later with delete[]. I dont know why he does it so complicated. I really like your version because it doesnt allocate them one by one. Is that also faster? – Rookie Sep 26 '12 at 17:20
  • also, why you dont have & for the `(void (CALLBACK *)())&tess_begin` etc ? – Rookie Sep 26 '12 at 17:24
  • I don't see why it wouldn't be safe to use. The vectors aren't deallocated until after `gluDeleteTess()`. [Address-of operator information, re: function pointers](http://stackoverflow.com/questions/6893285/why-do-all-these-crazy-function-pointer-definitions-all-work-what-is-really-goi). – genpfault Sep 26 '12 at 19:01
  • Isn't it smarter to add the & mark, instead of using the implicit conversion? At least many guides say that you should not let implicit conversions happen; "always make it clear there is a conversion". – Rookie Sep 27 '12 at 10:27
  • Eh, probably. Feel free to add them :) – genpfault Sep 27 '12 at 15:39