From 3cdf3f9411b20cc877bab399279c9bc450185efb Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 6 Jan 2025 18:10:01 +0100 Subject: [PATCH] Examples: Add Win32+Vulkan example: add multi-viewport support. (#8180) --- examples/example_win32_vulkan/main.cpp | 50 +++++++++++++++++++++----- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/examples/example_win32_vulkan/main.cpp b/examples/example_win32_vulkan/main.cpp index 3fabf7a2d..689629a7a 100644 --- a/examples/example_win32_vulkan/main.cpp +++ b/examples/example_win32_vulkan/main.cpp @@ -340,6 +340,16 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd) LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +// FIXME: This code would ideally be inside imgui_impl_win32.cpp, it would create a dependency on Vulkan headers in imgui_impl_win32.cpp +static int ImGui_ImplWin32_CreateVkSurface(ImGuiViewport* viewport, ImU64 vk_instance, const void* vk_allocator, ImU64* out_vk_surface) +{ + VkWin32SurfaceCreateInfoKHR createInfo = {}; + createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + createInfo.hwnd = (HWND)viewport->PlatformHandleRaw; + createInfo.hinstance = ::GetModuleHandle(nullptr); + return (int)vkCreateWin32SurfaceKHR((VkInstance)vk_instance, &createInfo, (VkAllocationCallbacks*)vk_allocator, (VkSurfaceKHR*)out_vk_surface); +} + // Main code int main(int, char**) { @@ -380,13 +390,27 @@ int main(int, char**) 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.ConfigFlags |= ImGuiConfigFlags_ViewportsNoTaskBarIcons; + //io.ConfigFlags |= ImGuiConfigFlags_ViewportsNoMerge; // Setup Dear ImGui style ImGui::StyleColorsDark(); //ImGui::StyleColorsLight(); + // 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; + } + // Setup Platform/Renderer backends ImGui_ImplWin32_Init(hwnd); + ImGui::GetPlatformIO().Platform_CreateVkSurface = ImGui_ImplWin32_CreateVkSurface; + ImGui_ImplVulkan_InitInfo init_info = {}; init_info.Instance = g_Instance; init_info.PhysicalDevice = g_PhysicalDevice; @@ -486,17 +510,25 @@ int main(int, char**) // Rendering ImGui::Render(); - ImDrawData* draw_data = ImGui::GetDrawData(); - const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f); - if (!is_minimized) + ImDrawData* main_draw_data = ImGui::GetDrawData(); + const bool main_is_minimized = (main_draw_data->DisplaySize.x <= 0.0f || main_draw_data->DisplaySize.y <= 0.0f); + wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w; + wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w; + wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w; + wd->ClearValue.color.float32[3] = clear_color.w; + if (!main_is_minimized) + FrameRender(wd, main_draw_data); + + // Update and Render additional Platform Windows + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { - wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w; - wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w; - wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w; - wd->ClearValue.color.float32[3] = clear_color.w; - FrameRender(wd, draw_data); - FramePresent(wd); + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); } + + // Present Main Platform Window + if (!main_is_minimized) + FramePresent(wd); } // Cleanup