从glfw回调调用overriden方法时崩溃

时间:2013-12-27 06:25:37

标签: vala glfw

我目前正在使用OpenGL和GLFW开发跨平台2D渲染引擎。我有一个名为GameWindow的基类窗口类,以及一个继承GameWindow的名为Game的类。游戏会覆盖基类中的一些虚方法,以便GameWindow可以处理帧限制等。在GameWindow的构造函数中,我使用glfwSetWindowSizeCallback指定在调整窗口大小时要运行的方法。然后,此方法调用GameWindow的虚拟on_resize方法,该方法触发Game中的overriden方法。从GameWindow中调用任何虚拟方法都具有在Game中调用适当方法的预期效果。但是,如果从GameWindow中的窗口调整大小回调调用虚方法,则应用程序崩溃。我通过存储GameWindow的静态实例并从回调中调用它的on_resize方法来解决这个问题。但是,我宁愿不必这样做。对这个问题有更好的解决方法吗?提前谢谢。

~Michael K。

class GameWindow : Object {
    GLFWwindow* win;
    ...
    public GameWindow(...) {
        ...
        glfwSetWindowSizeCallback(win, (GLFWwindowsizefun)window_size_callback);
    }

    public void run(...) {
        ...
        on_render(renderElapsed);  // This works fine.
        ...
    }

    public virtual void on_resize(int width, int height) {}

    public void window_size_callback(GLFWwindow* window, int width, int height) {
        ...
        on_resize(width, height);  // This causes a crash.
    }
}

class Game : GameWindow {
    ...
    public override void on_render(double time) { ... }

    public override void on_resize(int width, int height) { ... }
}

2 个答案:

答案 0 :(得分:1)

GLFWwindowsizefun不接受目标/上下文,因此Vala无法将当前GameWindow实例传递给回调。这实际上意味着回调中this为空,因此调用on_resize失败。你的演员正在隐藏Vala编译器的错误。

你应该:

  1. 使window_size_callback成为静态方法。
  2. 创建某种查找表,以便在全局变量中从GameWindow中查找GLFWwindow。 (您可能希望GameWindow在查找表中无主,并让GameWindow析构函数从查找表中删除。
  3. 在回调中,向右查找GameWindow并在其上调用on_resize方法。

答案 1 :(得分:0)

就像(非常延迟的)更新一样,我再次开始搞乱GLFW并发现它实际上有办法处理这类事情:glfwSetUserPointer和glfwGetUserPointer。我最后编辑了我的代码来存储指向调用GameWindow实例的指针。在回调方法中,我只是使用glfwGetUserPointer获取所述指针,并将其强制转换为GameWindow类型。然后,我可以像往常一样使用该实例。

编辑:虽然apmasell的答案是正确的,但它主要是一个不允许用户指针之类的库的解决方案。