Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

d3d11 Multi-Viewport bug #6208

Open
hebohang opened this issue Mar 1, 2023 · 4 comments
Open

d3d11 Multi-Viewport bug #6208

hebohang opened this issue Mar 1, 2023 · 4 comments

Comments

@hebohang
Copy link

hebohang commented Mar 1, 2023

Version/Branch of Dear ImGui:

Version: 1.88
Branch: docking

Backend:

C++20, Windows10

I tried both two ways:
imgui_impl_dx11 + imgui_impl_glfw
imgui_impl_dx11 + imgui_impl_win32

All appear the same bug.

When I disable the Multi-Viewport, it seems only the color not right:

2023-03-02.01-06-49.mp4

However, when I enable Multi-Viewport with code:

ImGuiIO& io = ImGui::GetIO(); (void)io;
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; 

It will raise a bug:

2023-03-02.01-07-23.mp4

When I put the imgui window next to the main window, the program will freeze.

I used the DXGI_SWAP_EFFECT_FLIP_DISCARD effect to create my swapchain, I find it probably related to the swapchain. And it seems I must clear my RenderTarget when imgui draw.

Some code I write:

    void DX11ImGuiLayer::OnAttach()
    {
        ImguiInit();

        Application& app = Application::GetInstance();
        GLFWwindow* window = static_cast<GLFWwindow*>(app.GetWindow().GetNativeWindow());
        HWND hWnd = glfwGetWin32Window(window);

        // Setup Platform/Renderer backends
        ImGui_ImplGlfw_InitForOther(window, true);
        //ImGui_ImplWin32_Init(hWnd);
        ImGui_ImplDX11_Init(DX11Context::Get()->GetDevice().Get(), DX11Context::Get()->GetD3D11Context().Get());

        DX11Context::Get()->OnResize();
    }

    void DX11ImGuiLayer::OnDetach()
    {
        // Cleanup
        ImGui_ImplDX11_Shutdown();
        //ImGui_ImplWin32_Shutdown();
        ImGui_ImplGlfw_Shutdown();
        ImGui::DestroyContext();
    }

    void DX11ImGuiLayer::OnImGuiRender()
    {
        //static bool pOpen = true;
        //ImGui::ShowDemoWindow(&pOpen);
    }

    void DX11ImGuiLayer::Begin()
    {
        // Start the Dear ImGui frame
        ImGui_ImplDX11_NewFrame();
        //ImGui_ImplWin32_NewFrame();
        ImGui_ImplGlfw_NewFrame();
        ImGui::NewFrame();

        ImGuizmo::BeginFrame();
    }

    void DX11ImGuiLayer::End()
    {
        ImGuiIO& io = ImGui::GetIO();
        Application& app = Application::GetInstance();
        io.DisplaySize = ImVec2((float)app.GetWindow().GetWidth(), (float)app.GetWindow().GetHeight());

        // Rendering
        ImGui::Render();
        ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
        //DX11Context::Get()->GetD3D11Context()->OMSetRenderTargets(1, DX11Context::Get()->GetBackBufferRTV().GetAddressOf(), NULL);
        ImDrawData* main_draw_data = ImGui::GetDrawData();
        ImGui_ImplDX11_RenderDrawData(main_draw_data);

        if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
        {
            GLFWwindow* backup_current_context = glfwGetCurrentContext();
            ImGui::UpdatePlatformWindows();
            ImGui::RenderPlatformWindowsDefault();
            glfwMakeContextCurrent(backup_current_context);
        }
    }

ImguiInit Function I writed:

    void ImGuiLayer::ImguiInit()
    {
        // Setup Dear ImGui context
        IMGUI_CHECKVERSION();
        ImGui::CreateContext();
        ImGuiIO& io = ImGui::GetIO(); (void)io;
        io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;       // Enable Keyboard Controls
        //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;      // Enable Gamepad Controls
        io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;           // Enable Docking
        io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;         // Enable Multi-Viewport / Platform Windows
        //io.ConfigViewportsNoAutoMerge = true;
        //io.ConfigViewportsNoTaskBarIcon = true;

        ImguiInitFont();

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

        // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones.
        ImGuiStyle& style = ImGui::GetStyle();
        if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
        {
            style.WindowRounding = 0.0f;
            style.Colors[ImGuiCol_WindowBg].w = 1.0f;
        }

        SetDarkThemeColors();
    }

Hope to get your help.

@hebohang
Copy link
Author

hebohang commented Mar 2, 2023

I find the color error seems to be with the color space. I use the DXGI_FORMAT_R8G8B8A8_UNORM_SRGB as the D3D11_RENDER_TARGET_VIEW_DESC format. I fine the same issue:
#578

I still don't know how to fix the multi-view issue (When I put the imgui window next to the main window, the program will freeze) .

@ocornut
Copy link
Owner

ocornut commented Mar 6, 2023

Hello,

  • If something freeze please provide a callstack and more details.
  • Does it happens on vanilla/unmodified examples?

@VonBismarck1986
Copy link

Error comes from imgui_impl_dx12.cpp line 906

IDXGISwapChain1* swap_chain = nullptr; res = dxgi_factory->CreateSwapChainForHwnd(vd->CommandQueue, hwnd, &sd1, nullptr, nullptr, &swap_chain); IM_ASSERT(res == S_OK);

@VonBismarck1986
Copy link

I guess it goes back to using DXGI_FORMAT_R8G8B8A8_UNORM_SRGB instead of DXGI_FORMAT_R8G8B8A8_UNORM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants