0

I have an ImGui widget with code similar to this:

ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::Begin("Window 1");
ImGui::Button("Hello 1");
ImGui::End();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

This runs fine.

If I add another frame, something like this:

ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::Begin("Window 1");
ImGui::Button("Hello 1");
ImGui::End();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplGlfw_NewFrame();
ImGui::NewFrame();
ImGui::Begin("Window 2");
ImGui::Button("Hello 2");
ImGui::End();
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

It renders fine but any mouse click cause an infinite recursion when glfwPollEvents() is called (the recursion is in ImGui_ImplGlfw_MouseButtonCallback(...)).

Note: I know I can perform several Begin(...) ... End(...) sequences without creating a new frame between them but I want the widgets to be independent of each other.

This is the call stack btw:

.
.
.
ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow *, int, int, int) imgui_impl_glfw.cpp:94
ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow *, int, int, int) imgui_impl_glfw.cpp:94
ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow *, int, int, int) imgui_impl_glfw.cpp:94
ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow *, int, int, int) imgui_impl_glfw.cpp:94
ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow *, int, int, int) imgui_impl_glfw.cpp:94
ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow *, int, int, int) imgui_impl_glfw.cpp:94
_glfwInputMouseClick(_GLFWwindow *, int, int, int) input.c:350
windowProc(HWND__ *, unsigned int, unsigned long long, long long) win32_window.c:804
<unknown> 0x00007ffce6e4e858
<unknown> 0x00007ffce6e4e4ee
<unknown> 0x00007ffcb74702a0
<unknown> 0x00007ffce6e4e858
<unknown> 0x00007ffce6e4e299
_glfwPlatformPollEvents() win32_window.c:1977
glfwPollEvents() window.c:1092
Widget::NewFrame() Widget.cpp:20
Widget::Draw(const Eigen::Matrix<…> &, const Eigen::Matrix<…> &, const Eigen::Matrix<…> &, int, unsigned int) Widget.cpp:28
Movable::Draw(const Eigen::Matrix<…> &, const Eigen::Matrix<…> &, const Eigen::Matrix<…> &, int, unsigned int) Movable.cpp:160
Scene::Draw(int, const std::shared_ptr<…> &, unsigned int) Scene.cpp:30
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
traveh
  • 2,700
  • 3
  • 27
  • 44
  • *"want the widgets to be independent of each other"* What does that mean? ImGui might get fussy with this, because not drawing a widget for a frame might reset some of its state. – HolyBlackCat Oct 02 '22 at 13:52
  • Creating several ImGui contexts might work better for this, though I still don't see the point. – HolyBlackCat Oct 02 '22 at 13:53

1 Answers1

0

What you want to do is create two different ImGui contexts (call ImGui::CreateContext() two times), and also initialize the backend two times for those contexts.

You will need to handle the WndProc and ImGui_ImplOpenGL3_RenderDrawData for two separate contexts.

But ImGui doesn't recommend to do this, you might want to look at how the docking branch handles multiple viewports/windows here

Or if your problem is simply window name collision (two ImGui window that have the same name), just add ## after the name, for example: "Window 1#win_1" will be rendered as Window 1

thedemons
  • 1,139
  • 2
  • 9
  • 25