2013-01-09 4 views
5

Ho utilizzato gli esempi here per spostare i miei callback di tessellation in una classe diversa.OpenGL Tessellation Callback Not Executing

Il codice viene compilato, ma il codice di richiamata non viene mai eseguito.

richiamata Classe:

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_; 
}; 

le richiamate: la funzione

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 dove li sto registrando:

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; 
} 

Cosa c'è di sbagliato con il modo in cui i callback sono stati registrati ?

+0

Non vedo come si possa eseguire il cast di un puntatore a un puntatore a funzione. Il modo in cui sto leggendo è che il tesselator proverà ad eseguire i dati in 'BeginCallback :: class_instance_', non dereference' BeginCallback' ed esegui 'operator()'. – genpfault

+9

Vedo cosa stai dicendo. Quella parte è stata il mio tentativo di integrare questa soluzione (http://www.partow.net/programming/templatecallback/) nel codice della tessellazione. Sto arrivando all'intera cosa in modo errato? – BrickFrog

+1

Tipo di. Il tessellator GLU è un codice piuttosto vecchio e non gestisce gli oggetti C++ nel modo in cui stai provando. Rendere le tue callback semplicemente semplici funzioni C-sytle semplificherà molte cose. La [man page ['gluTessCallback'] (http://www.opengl.org/sdk/docs/man2/xhtml/gluTessCallback.xml) ha una discussione ragionevole sui callback e su cosa vorresti includere in essi (supponendo che hai familiarità con OpenGL in stile immediato. – radical7

risposta

0

Si sta lanciando un puntatore a un tipo di oggetto a un puntatore a un tipo di funzione (ad esempio "BeginCallback" su "void (CALLBACK *)()"). Questi tipi sono incompatibili e non correlati. Il codice viene compilato in quanto è un cast in stile c, senza alcun tipo di controllo. Ancora di più, dal punto di vista del compilatore C++, BeginCallback e VertexCallback sono tipi diversi e incompatibili e la funzione gluTessCallback non ha la capacità di chiamare il proprio operatore sovraccarico() - queste sono funzioni membro diverse.