2013-01-09 10 views
5

Ich habe die Beispiele here verwendet, um meine Tessellation-Callbacks in eine andere Klasse zu verschieben.OpenGL Tessellation Callback nicht ausgeführt

Der Code wird kompiliert, aber der Rückrufcode wird nie ausgeführt.

Callback-Klasse:

template <class Class, typename ReturnType, typename Parameter> 
class SingularCallBack 
{ 
public: 

    typedef ReturnType (Class::*Method)(Parameter); 

    SingularCallBack(Class* class_instance, Method method) 
     : class_instance_(class_instance), 
     method_(method) 
    {} 

    ReturnType operator()(Parameter parameter) 
    { 
     return (class_instance_->*method_)(parameter); 
    } 

    ReturnType execute(Parameter parameter) 
    { 
     return operator()(parameter); 
    } 

private: 

    Class* class_instance_; 
    Method method_; 
}; 

Rückrufe:

void MyClass::tessBegin(GLenum which) 
{ 
    glBegin(which); 
    cout << "BEGIN CALLBACK IS WORKING"; 
} 

void MyClass::tessVertex(const GLvoid *data) 
{ 
    // cast back to double type 
    const GLdouble *ptr = (const GLdouble*)data; 

    glVertex3dv(ptr); 
    cout << "VERTEX CALLBACK IS WORKING"; 
} 

Tessellation-Funktion, wo ich sie bin Registrierung:

int MyClass::TessellatePolys() 
{ 
    GLUtesselator *tess = gluNewTess(); // create a tessellator 
    if(!tess) return 0; // failed to create tessellation object, return 0 

    // register callback functions 
    SingularCallBack<GLOrtho, void, GLenum>*BeginCallback; 
    BeginCallback = new SingularCallBack<GLOrtho, void, GLenum>(this,&GLOrtho::tessBegin); 
    gluTessCallback(tess, GLU_TESS_BEGIN, (void (CALLBACK *)())BeginCallback); 

    SingularCallBack<GLOrtho, void, const GLvoid*>*VertexCallback; 
    VertexCallback = new SingularCallBack<GLOrtho, void, const GLvoid*>(this,&GLOrtho::tessVertex); 
    gluTessCallback(tess, GLU_TESS_VERTEX, (void (CALLBACK *)())VertexCallback); 

    ... (do tessellation) ... 

    return id; 
} 

Was mit der Art und Weise falsch ist die Rückrufe registriert werden ?

+0

Ich sehe nicht, wie das Gießen eines Objektzeigers zu einem Funktionszeiger funktionieren soll. Die Art, wie ich es lese, ist, dass der Tesselator versucht, die Daten in 'BeginCallback :: class_instance_' auszuführen, nicht' BeginCallback' zu dereferenzieren und 'operator()' auszuführen. – genpfault

+9

Ich sehe was du sagst. Dieser Teil war mein Versuch, diese Lösung (http://www.partow.net/programming/templatecallback/) in den Tessellationscode einzupassen. Komme ich das ganze Ding falsch an? – BrickFrog

+1

Art von. Der GLU-Tessellator ist ziemlich alter Code und behandelt C++ - Objekte nicht so, wie Sie es versuchen. Callbacks einfach machen C-sytle-Funktionen vereinfachen viele Dinge. Die ['gluTessCallback'-Manpage] (http://www.opengl.org/sdk/docs/man2/xhtml/gluTessCallback.xml) hat eine vernünftige Diskussion der Callbacks und was Sie in sie aufnehmen wollen (angenommen Sie kennen sich mit OpenGL im Sofortmodus-Stil aus. – radical7

Antwort

0

Sie werfen einen Zeiger auf einen Objekttyp auf einen Zeiger auf einen Funktionstyp (wie "BeginCallback" auf "void (CALLBACK *)()"). Diese Typen sind inkompatibel und nicht miteinander verwandt. Der Code wird kompiliert, da es sich um einen C-Style-Cast handelt, ohne dass eine Typprüfung erforderlich ist. Mehr noch, aus der C++ - Compiler Sicht sind die BeginCallback und VertexCallback unterschiedliche und inkompatible Typen und die Funktion gluTessCallback hat keine Möglichkeit, ihre überladene operator() aufrufen - das sind verschiedene Member-Funktionen.