Заставить GLUtesselator генерировать только GL_TRIANGLES?

Довольно сложно отрисовать данные, которые я генерирую, если я хочу использовать только один формат массива вершин.

Я пытался обеспечить обратный вызов GLU_TESS_EDGE_FLAG_DATA, но это привело к сбою моей программы. (также пытался без «_DATA» в конце, тот же эффект).

Как я могу получить его только для генерации GL_TRIANGLES?

4

Решение

gluTessCallback(), GLU_TESS_EDGE_FLAG:

… если предоставляется обратный вызов не-NULL флага … вееры и полосы преобразуются в независимые треугольники.

Это то, что я использовал:

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;
}

Я склонен использовать Eigen::Vector2f за Vec,

5

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]