Anybody can figure out why this does not work. It crashes with stack overflow. And when setting a break point inside the begin callback, it does not show the correct primitive type, but a funny number. Inside vertex callback it gives wrong vertex data than the one passed to the gluTessVertex. I’m using C++/CLI.
// GluTessellator.h
#pragma once
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <list>
using namespace std;
using namespace System;
using namespace System::Collections::Generic;
using namespace Seljax::MathLib::Geometry;
using namespace Seljax::PluginFramework::Plugins::Interfaces::RenderingEngineInterfaces;
namespace Seljax {
namespace GluTessellator {
typedef struct
{
double data[14];
} Vertex_t;
typedef list<Vertex_t> Polygon_t;
typedef struct
{
Polygon_t outline;
GLenum type;
} TessPrim_t;
typedef list<TessPrim_t *> TessSurf_t;
typedef struct
{
Polygon_t outline;
list<Polygon_t *> holes;
} Surface_t;
public ref class GluTessellator
{
// TODO: Add your methods for this class here.
private:
GLUtesselator *tess;
static TessSurf_t *tessSurf;
Surface_t *surface;
Polygon_t *curOutline;
public: GluTessellator()
{
tess = gluNewTess();
tessSurf = new TessSurf_t();
surface = new Surface_t();
curOutline = NULL;
if (tess)
{
gluTessCallback(tess, GLU_TESS_BEGIN, (void (__stdcall *)())begin);
gluTessCallback(tess, GLU_TESS_END, (void (__stdcall *)())end);
gluTessCallback(tess, GLU_TESS_VERTEX, (void (__stdcall *)())vertex);
gluTessCallback(tess, GLU_TESS_COMBINE, (void (__stdcall *)())combine);
gluTessCallback(tess, GLU_TESS_ERROR, (void (__stdcall *)())error);
}
}
public: ~GluTessellator()
{
gluDeleteTess(tess);
//delete tessList;
//tessList = NULL;
}
public: void BeginSurfaceOutline()
{
curOutline = &surface->outline;
}
public: void EndSurfaceOutline()
{
curOutline = NULL;
}
public: void BeginSurfaceHole()
{
Polygon_t *poly = new Polygon_t;
curOutline = poly;
surface->holes.push_back(poly);
}
public: void EndSurfaceHole()
{
curOutline = NULL;
}
public: void PushVertexData(array<double>^ vdata)
{
Vertex_t v;
v.data[0] = vdata[0];
v.data[1] = vdata[1];
v.data[2] = vdata[2];
//v.data[3] = vdata[3];
//v.data[4] = vdata[4];
curOutline->push_back(v);
}
public: void TessellateSurface()
{
gluTessBeginPolygon(tess, NULL);
gluTessBeginContour(tess);
for (Polygon_t::iterator v = surface->outline.begin(); v != surface->outline.end(); v++)
{
Console::WriteLine("({0}, {1}, {2})", v->data[0], v->data[1], v->data[2]);
gluTessVertex(tess, v->data, v->data);
}
gluTessEndContour(tess);
for (list<Polygon_t *>::iterator hole = surface->holes.begin(); hole != surface->holes.end(); hole++)
{
gluTessBeginContour(tess);
for (Polygon_t::iterator v = (*hole)->begin(); v != (*hole)->end(); v++)
gluTessVertex(tess, v->data, v->data);
gluTessEndContour(tess);
}
gluTessEndPolygon(tess);
}
static void __stdcall begin(GLenum type)
{
TessPrim_t *prim = new TessPrim_t();
prim->type = type;
tessSurf->push_back(prim);
}
static void __stdcall end()
{
}
static void __stdcall vertex(GLvoid *vertex_data)
{
TessPrim_t *prim = tessSurf->back();
Vertex_t v;
v.data[0] = ((double *)vertex_data)[0];
v.data[1] = ((double *)vertex_data)[1];
v.data[2] = ((double *)vertex_data)[2];
//v.data[3] = ((double *)vertex_data)[3];
//v.data[4] = ((double *)vertex_data)[4];
prim->outline.push_back(v);
}
static void __stdcall combine(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **outData)
{
double *v = (double *)malloc(14 * sizeof(double));
v[0] = coords[0];
v[1] = coords[1];
v[2] = coords[2];
/*for( int i = 3; i < 5; i++ )
{
v[i] = 0;
for( int j = 0; j < 4; j++ )
if( vertex_data[j] != 0 )
v[i] += weight[j] * vertex_data[j][i];
}*/
*outData = v;
}
static void __stdcall error(GLenum errCode)
{
const GLubyte *errStr;
errStr = gluErrorString(errCode);
}
};
}
}