glfw输入回调以使用成员函数

时间:2017-12-21 12:43:08

标签: c++ opengl glfw

如您所知,glfw使用回调进行输入,回调函数具有用户需要匹配的特定签名。以下是文档中的示例:

void key_callback(GLFWwindow* window, int key, int scancode, int action, int 
mods)
{
    if (key == GLFW_KEY_E && action == GLFW_PRESS)
        activate_airship();
}

现在,激活飞艇似乎是一个全球性的功能。我真正想做的是,在每个输入阶段修改一些对象。所以我想要这样的东西:

void key_callback(Airship a, GLFWwindow* window, int key, int scancode, int 
                  action, int mods)
{
    if (key == GLFW_KEY_W && action == GLFW_PRESS)
        a.render_Wireframe();
}

如您所见,我想传递我想要修改的对象Airship。但这一次,回调签名被破坏了。我不能再使用它了。实现这一目标的最佳方法是什么?我想提出想法,但在将来,我可能想要改变这个不只是飞艇,而是我添加的新对象。这里的设计应该是什么?

事情是,能够为整个程序设置一个回调,我不知道如何实现以下功能。假设我有两个对象AirshipBattlesip。我希望他们两个都有自己的输入处理机制。如果W是场景中的拾取对象,则按Airship应该执行某些操作,如果Battleship是拾取的对象,则按其他内容。

所以我希望最终有类似的东西;

class Airship : public SceneObject
{
    ...
    void input_handle(){
        if(is_picked && pressed == GLFW_KEY_W)
            launch_missile();
    }
}

class Battleship : public SceneObject
{
    ...
    void input_handle(){
        if(is_picked && pressed == GLFW_KEY_W)
            do_something_else();
    }
}

在我的主循环中,我有一个SceneObject的向量,我在每个帧上为每个对象调用input_handle。我不知道如何使用glfw的单个回调方案来处理这样的事情。即使我匹配签名,我也无法将这些内容作为回调函数传递给窗口,因为它们是类成员。如果我可以传递类成员,那么没有什么会改变,因为我只能设置一个回调。

1 个答案:

答案 0 :(得分:0)

以下是我最终以简化方式解决此问题的方法。我不确定这是否是正确的设计,但它可能对未来的观众有所帮助。我有一个类似于对象的场景图,比如SceneGraph,它包含问题中提到的所有SceneObjects。我最终使这个SceneGraph对象成为单身人士。我每次运行都有一个场景图,所以对我来说这似乎是合乎逻辑的。

class SceneGraph
{  
    // ...
    // many more code
    friend void key_callback(GLFWwindow* window, int key, int scancode,
                             int action, int mods)
    {
        // get the singleton instance, singleton is static and this is
        // a friend function, so I can register this as a callback 
        SceneGraph* d = SceneGraph::handle();
        d->input_handle();
    } 

    void input_handle()
    {
         for(auto& s : objs)
             s.input_handle()
    }
private:
    std::vector<SceneObject> objs;
}

当然,您可以将按钮状态等传递给输入例程。我只想展示我最简单的设计。我在原始问题中谈到的对象选择示例现在也可以处理。