我有一个名为Polygon
的类,我试图在其中渲染一个镶嵌多边形。
我在这个类中有一个方法,叫做render
,还有几个方法来绘制我的多边形。
包括:
public class Polygon : public Entity
{
protected:
...
public:
bool render();
GLdouble* NewVector(GLdouble x, GLdouble y);
void CALLBACK BeginCallback(GLenum type);
void CALLBACK EndCallback();
void CALLBACK VertexCallback(GLvoid *vertex);
void CALLBACK CombineCallback(GLdouble coords[3], GLdouble *data[4], GLfloat weight[4], GLdouble **dataOut);
void CALLBACK ErrorCallback(GLenum errorCode);
};
在我的方法render
中,我试图为BeginCallback
, EndCallback
等注册gluTessCallback
回调…
gluTessCallback(tess, GLU_TESS_BEGIN, (void(*)())&this->BeginCallback);
但是这会给我一个编译错误,
错误C2276: '&':绑定成员函数的非法操作表达
我需要这个方法(从当前实例),因为我需要创建和释放其中的一些实例值。
有人能帮我吗?
对于
GLU_TESS_*_DATA
,用户指定的数据可以用于"每多边形"数据。
使用私有静态成员函数作为回调函数,并通过user_data
传递实例指针。
在每个回调中,你可以static_cast<>
user_data
指针指向你的Polygon
类型,并按需要操作结果实例。
像这样:
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;
};
如果不捕获当前对象的this
值,就无法在c++中获得对成员函数指针的引用。
换句话说,当你在c++中调用成员函数时,你隐式地将this
作为参数传递给函数——如果不指定this
是什么,你就不能调用成员函数(并且常规函数指针没有空间存储this
引用)。
你可以用几种方法来处理这个问题;将回调函数设置为静态(不需要对象引用),或者可以将其完全移到类之外。
如果你正在使用c++ 11,你可以使用lambda表达式,但我不确定传递一个给这个调用的含义;我想应该没问题。