gluTessCallback指向回调函数。编译错误

时间:2014-05-12 16:34:42

标签: c++ visual-c++ opengl function-pointers

我有一个名为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中,我试图注册gluTessCallbackBeginCallbackEndCallback回调...

gluTessCallback(tess, GLU_TESS_BEGIN, (void(*)())&this->BeginCallback);

但是这给了我一个编译错误,

  

错误C2276:'&' :绑定成员函数的非法操作   表达

我需要成为这种方法(来自当前实例),因为我需要在其中创建并释放一些实例值。

任何人都可以帮助我?

2 个答案:

答案 0 :(得分:3)

  

使用GLU_TESS_*_DATA,用户指定的数据可用于" per-polygon"数据

使用私有静态成员函数作为回调,并通过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;
};

答案 1 :(得分:2)

如果不捕获当前对象的this值,则无法在C ++中获取对成员函数指针的引用。

换句话说,当你在C ++中调用一个成员函数时,你隐式地将this作为参数传递给函数 - 没有指定this你不能调用一个成员函数(和一个常规函数)函数指针没有空间存储this引用。

你可以通过以下两种方式处理这个问题;使你的回调函数静态(不需要对象引用),或者你可以将它完全移出类。

如果你正在使用C ++ 11,你可以使用lambda表达式,但我不确定将一个传递给这个调用的含义;我相信它应该没问题。