Window turns black when dragging outside main window

I wasn’t sure if I should post here or in “Getting Started” and chose here because other than this issue, I have dear imgui setup and working.

First, I am using Win32 API on Windows 10 with OpenGL using imgui_impl_win32 and imgui_impl_opengl3. I am using GLEW, so I have #define IMGUI_IMPL_OPENGL_LOADER_GLEW. I am using 1.72b, but until about ten minutes ago, I was using 1.6 and had the same issue.

My issue is that when I drag an imgui window outside the main application window, it turns black. If I boil my code down (which I need to do because it is running inside my engine that is composed of multiple layers), here is what it would look like in a simple application:

//Setup
IMGUI_CHECKVERSION();
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO(); (void)io;
Application& app = Application::GetApplication();
io.DisplaySize = ImVec2((float)app.GetWindowWidth(), (float)app.GetWindowHeight());
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;           // Enable Docking
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;         // Enable Multi-Viewport / Platform Windows
ImGui::StyleColorsDark();
ImGuiStyle& style = ImGui::GetStyle();
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
{
    style.WindowRounding = 0.0f;
    style.Colors[ImGuiCol_WindowBg].w = 1.0f;
}
void* window = Application::GetApplication().window->GetHandle();
ImGui_ImplWin32_Init(window);
ImGui_ImplOpenGL3_Init("#version 410");

//Begin a frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();

//Render stuff
ImGui::ShowDemoWindow(&show);

//End a frame
ImGuiIO& io = ImGui::GetIO();
Application& app = Application::GetApplication();
io.DisplaySize = ImVec2((float)app.GetWindowWidth(), (float)app.GetWindowHeight());
ImGui::Render();
HGLRC backup_current_context = wglGetCurrentContext();
ImGui::UpdatePlatformWindows();
//ImGui::RenderPlatformWindowsDefault();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
wglMakeCurrent(Mercury::Graphics::API::hDC ,backup_current_context);

//I also have the standard shutdown code, but it would not be relevant to this issue.

I have commented out the stuff about grabbing the context and making it current, but it still does not work. I have also uncommented the line with ImGui::RenderPlatformWindowsDefault(), but all that does is to cause the window being dragged outside to be drawn as a black rectangle outside and normally inside, but only the outside one can be interacted with.

Any ideas?

Thanks!

I did some investigating and discovered that the Win32 implementation does not set functions for Platform_RenderWindow and Platform_SwapBuffer, so I implemented the following:

static void ImGui_ImplWin32_RenderWindow(ImGuiViewport* viewport, void*)
{
    ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData;
    if (data->hDC == NULL)
    {
        data->hDC = GetDC(data->Hwnd);
        PIXELFORMATDESCRIPTOR pfd =
        {
            sizeof(PIXELFORMATDESCRIPTOR),
            1,
            PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,    // Flags
            PFD_TYPE_RGBA,        // The kind of framebuffer. RGBA or palette.
            32,                   // Colordepth of the framebuffer.
            0, 0, 0, 0, 0, 0,
            0,
            0,
            0,
            0, 0, 0, 0,
            24,                   // Number of bits for the depthbuffer
            8,                    // Number of bits for the stencilbuffer
            0,                    // Number of Aux buffers in the framebuffer.
            PFD_MAIN_PLANE,
            0,
            0, 0, 0
        };
        int iPixelFormat = ChoosePixelFormat(data->hDC, &pfd);
        SetPixelFormat(data->hDC, iPixelFormat, &pfd);
    }
    if (data->hGLRC == NULL)
        data->hGLRC = wglCreateContext(data->hDC);
    wglMakeCurrent(data->hDC, data->hGLRC);
}

static void ImGui_ImplWin32_SwapBuffers(ImGuiViewport* viewport, void*)
{
    ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData;
    wglMakeCurrent(data->hDC, data->hGLRC);
    SwapBuffers(data->hDC);
}

I also added the following two lines in InitPlatformInterface

    platform_io.Platform_RenderWindow = ImGui_ImplWin32_RenderWindow;
    platform_io.Platform_SwapBuffers = ImGui_ImplWin32_SwapBuffers;

I have set breakpoints to check things and the functions do get called and the hDC and hGLRC are properly created and set. (I added these to the structure and they are released in the destructor so that they would not have to be recreated every frame.)

I am getting to an extreme dead end with this. Unfortunately, there are no examples for Win32 using anything other than DirectX in the repository. If anyone knows of one, I would be happy to look at it myself as long as it implements multiple viewports.

There’s a pull request here:


Which was on hold exactly for this issue you are mentioning.
Also see:

Please post and followup in #2600 if possible.