将类函数的指针传递给GLUT

Pass pointer to class function to GLUT

本文关键字:GLUT 指针 类函数      更新时间:2023-10-16

我有一个class

class App {
private:
    float angle;
public:
    App();
    int OnExecute();
    void OnLoop();
    void OnRender();
    bool OnInit();
    void OnCleanup();
};
//In my cpp file:
int App::OnExecute() {
    if (OnInit() == false) {
        return -1;
    }
    OnLoop();
    OnRender();
    OnCleanup();
    return 0;
}
bool App::OnInit() {
    glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA );
    glutInitWindowPosition(-1,-1);
    glutInitWindowSize(1024,768);
    glutCreateWindow("D&D VT");
    glutDisplayFunc(Render); //Why can't I put this->OnRender
    //glutReshapeFunc(changeSize);
    //glutIdleFunc(Render);
    return true;
}

我注释了我正在努力做我想做的事情的行。我想传递一个指针到我的类函数。我已经尝试了大约4种不同的方法来做到这一点,我得到编译错误,除非我创建一个非类函数传递。

我试过通过this->*OnRender。我试着将函数声明为virtual voidvoid (App::*OnRender)()。我试着把它定义为void &App::OnRender() {};

每次都有不同的错误,抱怨我的语法组合。

glutDisplayFunc(Render); //Why can't I put this->OnRender

因为C和c++不是这样工作的。你想到的是所谓的闭包。this->Render是语法糖,结合了两个不同的元素:

  • 指向类的某个实例的指针

    指向类成员的指针

两者必须以特定的方式组合才能解引用。在c++中,你可以写一个带两个参数的回调函数(指向类实例this的指针和指向类成员&App::Render的指针),但是GLUT是你使用的框架,它是用C写的,它的API是C。C不知道类,也不知道类成员,所以你想做的是几乎不可能实现的,除非做一些疯狂的事情,比如使用ffcall来创建闭包。

我的建议:不要使用GLUT。GLUT只是一些框架,您可以随时替换它。使用Qt怎么样?它得到了适当的OpenGL支持,如果你想做所有的c++ OOP,它会更好用。

解决这一困境的关键在于这三个GLUT函数。

int glutCreateWindow(char *name);
void glutSetWindow(int win);
int glutGetWindow(void);

没有窗口,你不能显示任何东西,你可以查询窗口。因此,您需要将此窗口int与指向您想要的任何东西的指针关联起来:指向实例的指针,或某个结构体的指针,无论您喜欢什么。例子:

static ::std::unordered_map<int, Window*> windows;
extern "C" void display_callback()
{
  auto const window_id(glutGetWindow());
  windows[window_id]->do_something();
}

如果你使用的是freeglut,那么看看这些函数:

glutGetWindowData()
glutSetWindowData().