ocornut / imgui

Dear ImGui: Bloat-free Graphical User interface for C++ with minimal dependencies
MIT License
60.67k stars 10.25k forks source link

Application crash after selecting "io.ConfigFlags: ViewportsEnable" checkbox from inside Dear ImGui Demo > Configuration > Configuration #5371

Closed benwithington closed 1 week ago

benwithington commented 2 years ago

From Config/build Information

Dear ImGui 1.88 WIP (18724) Branch https://github.com/ocornut/imgui/tree/7b5a8e4f2bbc06eac3b913a7f7df67edff99c538 (Sorry I don't know how to link branches properly)

--------------------------------
sizeof(size_t): 8, sizeof(ImDrawIdx): 2, sizeof(ImDrawVert): 20
define: __cplusplus=199711
define: _WIN32
define: _WIN64
define: _MSC_VER=1932
define: _MSVC_LANG=201402
define: IMGUI_HAS_VIEWPORT
define: IMGUI_HAS_DOCK
--------------------------------
io.BackendPlatformName: imgui_impl_glfw
io.BackendRendererName: imgui_impl_opengl3
io.ConfigFlags: 0x00000000
io.ConfigViewportsNoDecoration
io.ConfigInputTextCursorBlink
io.ConfigWindowsResizeFromEdges
io.ConfigMemoryCompactTimer = 60.0
io.BackendFlags: 0x00001C0E
 HasMouseCursors
 HasSetMousePos
 PlatformHasViewports
 HasMouseHoveredViewport
 RendererHasVtxOffset
 RendererHasViewports
--------------------------------
io.Fonts: 1 fonts, Flags: 0x00000000, TexSize: 512,64
io.DisplaySize: 1280.00,720.00
io.DisplayFramebufferScale: 1.00,1.00
--------------------------------
style.WindowPadding: 8.00,8.00
style.WindowBorderSize: 1.00
style.FramePadding: 4.00,3.00
style.FrameRounding: 0.00
style.FrameBorderSize: 0.00
style.ItemSpacing: 8.00,4.00
style.ItemInnerSpacing: 4.00,4.00

My Issue/Question:

After checking out the latest docking branch, I was exploring the demo window, after checking the "io.ConfigFlags: ViewportsEnable" checkbox inside Configuration>Configuration of the demo window., the program crashes. All other checkboxs in the configuration menu work as intended.

This is the error that gets printed:

Assertion failed: (g.FrameCount == 0 || g.FrameCount == g.FrameCountPlatformEnded) && "Forgot to call UpdatePlatformWindows() in main loop after EndFrame()? Check examples/ applications for reference.", file ~\imgui.cpp, line 8617

Screenshots/Video

bugreport _

Standalone, minimal, complete and verifiable example: I haven't actually writtten any code, this bug happened while using ImGui::ShowDemoWindow(), below is all of the imgui code I used in my project

    /* Dear ImGui Setup */
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;

    //Setup Dear ImGui style
    ImGui::StyleColorsDark();

    //Setup platform/renderer backends
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init("#version 330");

    while(!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(0.23, 0.2f, 0.45f, 1.0);

        //ImGui Frame start point
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        ImGui::ShowDemoWindow();

        //Render ImGui Stuff
        ImGui::Render();
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();

This is my first time submitting a bug report on github so I hope I've done everything right

PathogenDavid commented 2 years ago

This is my first time submitting a bug report on github so I hope I've done everything right

Looks good to me, thanks a lot for filling out the template!

Short version: The easiest way for you to work around this for now is to enable viewports before calling ImGui_ImplGlfw_InitForOpenGL/ImGui_ImplOpenGL3_Init, IE: io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;

(If you want your app to start with them disabled you should be able to turn them back off right after initialization.)


I can repro this in example_glfw_opengl3 (albeit with a different assert -- it was the same assert, I can't read) by commenting where viewports and docking are enabled during initialization:

https://github.com/ocornut/imgui/blob/7b5a8e4f2bbc06eac3b913a7f7df67edff99c538/examples/example_glfw_opengl3/main.cpp#L70-L71

Basically what's happening is the backends are initializing without configuring their viewport support internals and don't initialize it when you enable it later.

Not sure if we want to support this scenario, but it seems to me like the backends should just call ImGui_Impl*_InitPlatformInterface unconditionally instead of checking for ImGuiConfigFlags_ViewportsEnable like they currently do.

ocornut commented 2 years ago

Thanks both for your report and analysis.

Not sure if we want to support this scenario, but it seems to me like the backends should just call ImGui_Impl*_InitPlatformInterface unconditionally instead of checking for ImGuiConfigFlags_ViewportsEnable like they currently do.

I wanted to strongly convey that this backend code was optional for people trying to study and reimplement backends. Two things:

PathogenDavid commented 2 years ago

I think we could make the backend lazily initialize, so it can still convey that.

I do worry slightly that this might be misleading in the other direction though: It might imply that your backend should support lazy initialization.

There's already quite a few comments in the backends that state when things are optional. Is that not enough in this case too?

Either way the assertion is misleading should be improved.

It's slightly better in context:

https://github.com/ocornut/imgui/blob/7b5a8e4f2bbc06eac3b913a7f7df67edff99c538/imgui.cpp#L8617-L8627

Might just be a matter of moving that first assert to the bottom?

benwithington commented 2 years ago

Short version: The easiest way for you to work around this for now is to enable viewports before calling ImGui_ImplGlfw_InitForOpenGL/ImGui_ImplOpenGL3_Init, IE: io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;

Sorry if I've misunderstood, but after trying your work around, the same issue persists, except that the application crashes when the program executes io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;

For completeness my code looks like this now:

/* Dear ImGui Setup */
    IMGUI_CHECKVERSION();
    ImGui::CreateContext();
    ImGuiIO& io = ImGui::GetIO(); (void)io;

    io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;

    //Setup Dear ImGui style
    ImGui::StyleColorsDark();

    //Setup platform/renderer backends
    ImGui_ImplGlfw_InitForOpenGL(window, true);
    ImGui_ImplOpenGL3_Init("#version 330");

    while(!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(0.23, 0.2f, 0.45f, 1.0);

        //ImGui Frame start point
        ImGui_ImplOpenGL3_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        ImGui::ShowDemoWindow();

        //Render ImGui Stuff
        ImGui::Render();
        ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    ImGui_ImplOpenGL3_Shutdown();
    ImGui_ImplGlfw_Shutdown();
    ImGui::DestroyContext();
ocornut commented 2 years ago

In this case simply read what the assert says and compare your code to the examples. You are not calling a function.

ocornut commented 1 week ago

Pushed 22503bf which makes it possible to enable ImGuiConfigFlags_ViewportsEnable after backend initialization. This should be solved.