From a06eb833590478276a3c186a7b66a9cf5082ebf4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 25 May 2020 15:31:33 +0200 Subject: [PATCH] Examples: GLFW+Vulkan, SDL+Vulkan: Fix for handling of minimized windows. (#3259) --- docs/CHANGELOG.txt | 1 + examples/example_glfw_vulkan/main.cpp | 20 ++++++++++++-------- examples/example_sdl_vulkan/main.cpp | 23 +++++++++++++++-------- examples/imgui_impl_vulkan.cpp | 1 + 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index da94c890..dff65283 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -70,6 +70,7 @@ Other Changes: - Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData structure didn't have any vertices. (#2697) [@kudaba] - Backends: OSX: Added workaround to avoid fast mouse clicks. (#3261, #1992, #2525) [@nburrus] +- Examples: GLFW+Vulkan, SDL+Vulkan: Fix for handling of minimized windows. (#3259) - Examples: Apple: Fixed example_apple_metal and example_apple_opengl2 using imgui_impl_osx.mm not forwarding right and center mouse clicks. (#3260) [@nburrus] diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 15ec2068..3ce1984a 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -248,7 +248,7 @@ static void CleanupVulkanWindow() ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator); } -static void FrameRender(ImGui_ImplVulkanH_Window* wd) +static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data) { VkResult err; @@ -286,8 +286,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); } - // Record Imgui Draw Data and draw funcs into command buffer - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); + // Record dear imgui primitives into command buffer + ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer); // Submit command buffer vkCmdEndRenderPass(fd->CommandBuffer); @@ -456,7 +456,8 @@ int main(int, char**) // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); - if (g_SwapChainRebuild) + // Resize swap chain? + if (g_SwapChainRebuild && g_SwapChainResizeWidth > 0 && g_SwapChainResizeHeight > 0) { g_SwapChainRebuild = false; ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); @@ -508,10 +509,13 @@ int main(int, char**) // Rendering ImGui::Render(); - memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); - FrameRender(wd); - - FramePresent(wd); + ImDrawData* draw_data = ImGui::GetDrawData(); + const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f); + if (!is_minimized) + { + FrameRender(wd, draw_data); + FramePresent(wd); + } } // Cleanup diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp index 53975516..9eaea945 100644 --- a/examples/example_sdl_vulkan/main.cpp +++ b/examples/example_sdl_vulkan/main.cpp @@ -240,7 +240,7 @@ static void CleanupVulkanWindow() ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator); } -static void FrameRender(ImGui_ImplVulkanH_Window* wd) +static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data) { VkResult err; @@ -278,8 +278,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); } - // Record Imgui Draw Data and draw funcs into command buffer - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); + // Record dear imgui primitives into command buffer + ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer); // Submit command buffer vkCmdEndRenderPass(fd->CommandBuffer); @@ -447,13 +447,17 @@ int main(int, char**) done = true; if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window)) { + // Note: your own application may rely on SDL_WINDOWEVENT_MINIMIZED/SDL_WINDOWEVENT_RESTORED to skip updating all-together. + // Here ImGui_ImplSDL2_NewFrame() will set io.DisplaySize to zero which will disable rendering but let application run. + // Please note that you can't Present into a minimized window. g_SwapChainResizeWidth = (int)event.window.data1; g_SwapChainResizeHeight = (int)event.window.data2; g_SwapChainRebuild = true; } } - if (g_SwapChainRebuild) + // Resize swap chain? + if (g_SwapChainRebuild && g_SwapChainResizeWidth > 0 && g_SwapChainResizeHeight > 0) { g_SwapChainRebuild = false; ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); @@ -505,10 +509,13 @@ int main(int, char**) // Rendering ImGui::Render(); - memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); - FrameRender(wd); - - FramePresent(wd); + ImDrawData* draw_data = ImGui::GetDrawData(); + const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f); + if (!is_minimized) + { + FrameRender(wd, draw_data); + FramePresent(wd); + } } // Cleanup diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index 93c3b404..c65b2db0 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -999,6 +999,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V { VkResult err; VkSwapchainKHR old_swapchain = wd->Swapchain; + wd->Swapchain = NULL; err = vkDeviceWaitIdle(device); check_vk_result(err);