OpenGL GLFW 使用ImGUI:多窗口ImGui输入冲突

看了下之前记录的东西,非常的乱,所以决定接下来按阶段和内容记录学习,这样至少会更有条理。

上周的问题:多窗口ImGui输入冲突

这部分是由于,在while中循环调用渲染glfwPollEvents()时,处理的输入操作只会应用在当前生效的ImGui的上下文环境中(这个当前生效的),这个环境既是ImGui::SetCurrentContext(context)设置的上下文环境(如果只创建了一个上下文就默认是该唯一的上下文环境)。因为我这是每个窗口都设置了独立的ImGui(ImGui_ImplGlfw_InitForOpenGL(window, true):由于创建ImGui需要绑定到已有窗口),所以在运行过程中实际上只有在glfwPollEvents()运行时生效的ImGui上下文才能对输入操作。

void glfwPollEvents();

该函数仅处理事件队列中的事件,然后立即返回。

解决方法: glfwSetWindowFocusCallback (GLFWwindow *window, GLFWwindowfocusfun callback)通过获取窗口是否被聚焦(也就是被输入设备选中),从而将当前被选中窗口的ImGui上下文设置为当前上下文。

这块是我实现了一个基类,两个派生类分别用于创建纹理UI和主菜单UI的glfw窗口和imGui。glfwSetWindowFocusCallback()设置回调是在类的构造函数中实现的,我需要的是在回调函数中实现将类的静态成员变量currentContext设置为当前触发回调的window的ImGui上下文,然后在每次循环调用的派生类的ImGuiRender函数(按自己需求写的用于绘制GUI的函数)的最后将上下文设置为currentContext。

这块遇到了glfwSetWindowFocusCallback()的参数不能是成员函数,而得是普通函数的问题,所以不能直接将使用了成员变量的成员函数直接给glfwSetWindowFocusCallback()。

好在可以通过glfwSetWindowUserPointer(window, this)将一个实例绑定到当前窗口上,再在普通函数中根据glfwGetWindowUserPointer(window)来获取该实例。

glfwSetWindowFocusCallback设置的回调失效

glfwSetWindowFocusCallback在构造函数中声明就会有问题,只有最后一个生效(例如我在基类的构造函数中实现了创建window,然后设置WindowFocusCallback,在两个派生类被实例化的过程中,只有最后一个实例化的才能被成功回调)。而我在主程序中显式的设置两个FocusCallback写一个成员函数专门用来设置回调就不会有问题。

当然这样还是会有一些逻辑bug,比如当前聚焦的是Main Menu,但是鼠标在Texture上,会触发Main Menu中对应位置的鼠标悬浮动画,但是完全不影响功能。能实现ok就已经很欣慰了^ ^。

posted @ 2024-08-29 17:21  PAddingoi  阅读(21)  评论(0编辑  收藏  举报  来源