Как передать нестатическую функцию-член в glutDisplayFunc - PullRequest
6 голосов
/ 20 апреля 2010

У меня есть класс, который имеет функциональность для инициализации opengl и запуска его в отдельном потоке.

Моя проблема: обратные вызовы openGL, такие как glutDisplayFunc, glutMotionFunc и т. Д., Принимают void (* f) void, и я не могу передать функцию-член класса.

пути вокруг. 1) Я могу объявить функцию-член как статическую, но в этом случае мне нужно объявить все используемые переменные-члены как статические, и в итоге весь класс объявляется статическим.

2) Я могу использовать отдельную функцию и объявить мой объект как глобальный, но это очень плохо.

Интересно, есть ли какие-то способы, так что мне не нужно делать мой класс opengl статичным ?? (используя c ++)

Ответы [ 4 ]

4 голосов
/ 20 апреля 2010

Вам понадобится создать "thunk" или "trampoline": Обратные вызовы функций API C в код функции-члена C ++

2 голосов
/ 20 апреля 2010

Поскольку обратные вызовы не принимают никаких параметров, мало что можно сделать.Одной из возможностей является создание пространства имен с функциями и статическим членом данных, который является вашим текущим классом.Функции просто перенаправляют вызовы функций в существующий класс.Это просто немного более чистая версия вашего # 2.

namespace GLForwader
{
    static MyGLClass* = new myGlClass();

    void glutDisplayFunc() {myGlClass->glutDisplayFunc();}
    void glutMotionFunc() {myGlClass->glutMotionFunc();}
}
0 голосов
/ 12 июня 2014

Я только что искал это, так как у меня была та же проблема при очистке и ООП'е нашего кода. Оказывается, что такие полезные вещи, как std :: bind, здесь не работают, но если вы все равно компилируете на C ++ 11, вы можете определить анонимную функцию для переноса функции-члена.

class Renderer {
  void Start();
  void Render();
}

// ...

void Renderer::Start() {
  // ...
  glutDisplayFunc([](){ Render(); });
}
0 голосов
/ 20 апреля 2010

Простой обходной путь:

Объявите глобальный указатель на ваш класс и инициализируйте его в main (), позвольте обратному вызову вызвать обычный метод для этого экземпляра

MyOGLClass *g_pOGL;

void oglDraw()
{
    if(g_pOGL)
        g_pOGL->oglDraw();
}

void main()
{
    // Init your class
    MyOGLClass o;

    g_pOGL = &o;

    //...

    glutMainLoop();

}

Ограничение: у вас может быть только один экземпляр вашего класса, но для приложения OpenGL это не так уж и плохо, поскольку вам все равно нужен только один экземпляр ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...