OpenGL将glutSpecialFunc指向成员函数

时间:2016-11-11 03:49:58

标签: c++ function c++11 opengl

我的OpenGL函数glutSpecialFunc需要一个带有3个int参数的void函数指针。只需

即可轻松完成全局功能
glutSpecialFunc(processArrowKeys);

但是我想让它指向另一个文件中的结构中的成员函数,如下所示:

inputs.h

struct Keyboard {
bool leftMouseDown;
bool keyRight, keyLeft, keyUp, keyDown;

Keyboard() : leftMouseDown(false), keyRight(false), keyLeft(false), keyUp(false), keyDown(false) {

}

void Keyboard::processArrowKeys(int key, int x, int y) {

    // process key strokes
    if (key == GLUT_KEY_RIGHT) {
        keyRight = true;
        keyLeft = false;
        keyUp = false;
        keyDown = false;
    }
    else if (key == GLUT_KEY_LEFT) {
        keyRight = false;
        keyLeft = true;
        keyUp = false;
        keyDown = false;
    }
    else if (key == GLUT_KEY_UP) {
        keyRight = false;
        keyLeft = false;
        keyUp = true;
        keyDown = false;
    }
    else if (key == GLUT_KEY_DOWN) {
        keyRight = false;
        keyLeft = false;
        keyUp = false;
        keyDown = true;
    }

}

}; 

的main.cpp

#include "inputs.h"

Keyboard keyboard;

...

int main(int argc, char **argv) {

...

// callbacks
glutDisplayFunc(displayWindow);
glutReshapeFunc(reshapeWindow);
glutIdleFunc(updateScene);
glutSpecialFunc(&keyboard.processArrowKeys); // compiler error: '&': illegal operation on bound member function expression
glutMouseFunc(mouseButton);
glutMotionFunc(mouseMove);

glutMainLoop();

return 0;
}

知道如何解决这个编译错误吗?

1 个答案:

答案 0 :(得分:2)

你不能直接这样做,因为成员函数有一个隐含的 this 指针,必须以某种方式通过调用链传递。而是创建一个中间函数,将调用转发到正确的位置:

void processArrowKeys(int key, int x, int y) {
    keyboard.processArrowKeys(key, x, y);
}

int main() {
    // ...
    glutSpecialFunc(processArrowKeys);
    // ...
}
代码中的

keyboard似乎是全局的,因此它可以正常工作。如果你想要一个非全局状态,那么你将不得不使用一些GLUT实现支持的用户数据指针作为扩展(包括FreeGLUT和OpenGLUT):

void processArrowKeys(int key, int x, int y) {
    Keyboard *k = (Keyboard*)glutGetWindowData();
    k->processArrowKeys(key, x, y);
}

int main() {
    // ...
    glutSpecialFunc(processArrowKeys);
    glutSetWindowData(&keyboard);
    // ...
}