0

我正在尝试将一个函数传递给 GLUT 回调 glutSpecialFunc。

当我尝试将静态函数(specialKeyProcessor)传递给它时,它工作得很好。

当我将此函数移至专门处理键盘相关函数的类(KeyBoardMovement)时,它似乎不起作用:

.... 键盘移动键盘;.... glutSpecialFunc(keyboard.specialKeyProcessor);

错误弹出:必须调用非静态成员函数的引用。

我不理解这个错误,因为我看不出放置在不同位置的相同功能之间有任何区别。

4

2 回答 2

2

glutSpecialFunc函数设置每个窗口的回调。如果您使用的是 OpenGLUT,它还允许您使用glutSetWindowData.

因此,您可以像这样创建一个全局 shim 函数:

void specialKeyProcessor(int key, int x, int y) {
    KeyboardMovement *keyboard = static_cast<KeyboardMovement *>(glutGetWindowData());
    keyboard->specialKeyProcessor(key, x, y);
}

并使用以下方法关联您的键盘处理程序glutGetWindowData

glutSetWindowData(static_cast<void *>(&keyboard));

如果您需要存储多条窗口数据,您可以存储一个指向特定于窗口的指针,struct其中包含每个特定于窗口的数据的字段。


如果您不使用 OpenGLUT,则可以考虑std::map将窗口 ID 映射到全局数据。然后,您可以采用与上述类似的方法来获取特定于窗口的数据。

于 2013-02-13T23:49:13.980 回答
0

C++ 不支持闭包,这意味着它不能将类实例连同方法一起转换为函数指针,调用该函数指针时将执行类实例的方法。

不幸的是,GLUT 不支持数据感知回调,就像大多数其他 C 回调 API 一样。所以它要么编写一个包装函数,它将调用你的类的全局实例,要么使用一个名为“ffcall”的库使用一些非常肮脏的技巧,它实际上可以在运行时创建新函数,可以参数化并充当一个可以传递给 GLUT 的闭包。但这确实是黑暗的东西,正确的做法是抛弃 GLUT。

于 2013-02-13T23:40:29.217 回答