指向回调函数的指针.编译错误



我有一个名为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表达式,但我不确定传递一个给这个调用的含义;我想应该没问题。

最新更新