c++ opengl callback freeglut

c++ - Función de devolución de llamada en freeglut del objeto



opengl callback (4)

Estoy usando MSVC ++ y freeglut para usar OpenGL. Ahora, tengo una clase llamada Camera , que es bastante simple, pero también contiene la función para la remodelación de mi ventana.

Mi pregunta es: ¿cómo puedo configurar glutReshapeFunc(void (*callback)(int,int)) a mi función en mi cámara?

Tengo el siguiente código, que no funcionará, debido a un error del compilador:

int main(int argc, char **argv) { Camera *camera = new Camera(); glutReshapeFunc(camera->ReshapeCamera); }

y mi clase de cámara se ve así en Camera.h :

class Camera { public: Camera(void); ~Camera(void); void ReshapeCamera(int width, int height); };

Tal vez esta es solo una pregunta de devolución de llamada más general, pero lo único que encontré en Internet fue crear una clase de envoltura alrededor de la devolución de llamada. Pero no parece que esto debería ser tan difícil. Gracias por adelantado.


No hay una manera limpia de hacer esto. C no sabe acerca de los objetos, por lo que los punteros a los miembros no funcionan. C no hace plantillas, por lo que los funtores no funcionan. La API ni siquiera le permite pasar un void *userData arbitrario void *userData a su devolución de llamada, por lo que tampoco puede pasar el objeto de esa manera.

Por lo tanto, tendrá que crear una función contenedora que no sea una función miembro, y tendrá que darle acceso a la instancia del objeto Camera alguna manera, a través de una variable estática y / o global.

Si puede haber varios objetos escuchando este evento, puede crear una clase singleton que le permita registrar escuchas arbitrarios.


No puedes conectarlo directamente. ReshapeCamera es una función miembro, necesita una instancia de cámara para ejecutarse. La devolución de llamada glut es una función C, que no tiene una instancia de cámara para llamar a su método. Necesita crear una función que llame al método de remodelación de la cámara.


No tiene nada que ver con una cosa de "C vs C ++". Solo necesita comprender lo que implica una llamada a función de miembro y, básicamente, con qué se compila.

myObject.memberFunction(); // This is what the programmer sees. memberFunction(&myObject); // This is what the compiler sees.

Una función miembro es una descripción elegante de una función que simplemente toma el objeto como primer parámetro. Es simplemente invisible en la lista de parámetros reales.

void MyClass::memberFunction() // This is the declaration the programmer sees. void memberFunction(MyClass* this) // This is what the compiler sees.

A partir de ahí, C ++ agrega semántica especial para facilitar el trabajo orientado a objetos. Por lo tanto, aunque su objeto tenga una función miembro del formato void (int, int), en realidad tiene el formato void (Camera *, int, int) y no coincide con el formato deseado. Esta es la razón por la cual los miembros de la función estática se pueden usar para dichos indicadores de función. ¿Alguna vez se dio cuenta de que las funciones de miembros estáticos no pueden acceder a los miembros de "esto"? Esto se debe a que las funciones miembro estáticas no pasan una instancia del objeto que representa "esto".

En efecto, podría emular gran parte de la programación orientada a objetos en el plano C. Si realiza un conjunto de funciones que toman un puntero estructural como el primer parámetro, ¡obtendrá muchas de las mismas ventajas!


A continuación se muestra cómo registrar la función de devolución de llamada de c ++ Es generalmente útil, no específico del exceso.

Aquí está su programa c ++ de cliente

int main(int argc, char *argv[]) { std::cout << "launching Camera ..." << std::endl; Camera * camera = new Camera(); // ------ glut new window boilerplate ------- // int WindowHandle = 0; glutInit(&argc, argv); WindowHandle = glutCreateWindow("hello there"); if(WindowHandle < 1) { std::cerr << "ERROR: Could not create a new rendering window" << std::endl; exit(EXIT_FAILURE); } // ------------------------------------------ // camera->setup_callback(); glutMainLoop(); return 0;

}

Aquí está la cámara.cpp

Camera * ptr_global_instance = NULL; extern "C" void ReshapeCamera_callback(int width, int height) { // c function call which calls your c++ class method ptr_global_instance->ReshapeCamera_cb(width, height); } void Camera::ReshapeCamera_cb(int width, int height) { std::cout << "width " << width << " height " << height << std::endl; } void Camera::setup_callback() { // c++ method which registers c function callback ::ptr_global_instance = this; ::glutReshapeFunc(::ReshapeCamera_callback); }

y su cabecera Camera.h

class Camera { public: void ReshapeCamera_cb(int width, int height); void setup_callback(); };

Observe el uso de un puntero de clase global c ++ ptr_global_instance