From 9da475e4e8b697b68c3dd07990e5136c53a9bcbe Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 2 Mar 2018 19:23:01 +0100 Subject: [PATCH] Examples: GLFW, Vulkan: GLFW binding viewport tweaks to supports Vulkan better (do not call SwapBuffer, share context etc.). Added DUMMY (empty) platform/viewport interface in the viewport code. --- examples/imgui_impl_glfw.cpp | 37 +++++++++---- examples/imgui_impl_glfw.h | 1 + examples/imgui_impl_vulkan.cpp | 89 ++++++++++++++++++++++++++++++++ examples/vulkan_example/main.cpp | 6 ++- 4 files changed, 123 insertions(+), 10 deletions(-) diff --git a/examples/imgui_impl_glfw.cpp b/examples/imgui_impl_glfw.cpp index f5fce96c..2e28a52a 100644 --- a/examples/imgui_impl_glfw.cpp +++ b/examples/imgui_impl_glfw.cpp @@ -36,10 +36,17 @@ #endif // Data -static GLFWwindow* g_Window = NULL; -static double g_Time = 0.0f; -static bool g_MouseJustPressed[5] = { false, false, false, false, false }; -static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; +enum GlfwClientApi +{ + GlfwClientApi_Unknown, + GlfwClientApi_OpenGL, + GlfwClientApi_Vulkan +}; +static GLFWwindow* g_Window = NULL; +static GlfwClientApi g_ClientApi = GlfwClientApi_Unknown; +static double g_Time = 0.0f; +static bool g_MouseJustPressed[5] = { false, false, false, false, false }; +static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; // Forward Declarations static void ImGui_ImplGlfw_InitPlatformInterface(); @@ -98,7 +105,7 @@ void ImGui_ImplGlfw_InstallCallbacks(GLFWwindow* window) glfwSetCharCallback(window, ImGui_ImplGlfw_CharCallback); } -bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) +bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) { g_Window = window; @@ -149,6 +156,15 @@ bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks) if (io.ConfigFlags & ImGuiConfigFlags_MultiViewports) ImGui_ImplGlfw_InitPlatformInterface(); + g_ClientApi = GlfwClientApi_OpenGL; + return true; +} + +bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks) +{ + if (!ImGui_ImplGlfw_Init(window, install_callbacks)) + return false; + g_ClientApi = GlfwClientApi_Vulkan; return true; } @@ -161,6 +177,7 @@ void ImGui_ImplGlfw_Shutdown() glfwDestroyCursor(g_MouseCursors[cursor_n]); g_MouseCursors[cursor_n] = NULL; } + g_ClientApi = GlfwClientApi_Unknown; } static void ImGui_ImplGlfw_UpdateMouse() @@ -176,7 +193,6 @@ static void ImGui_ImplGlfw_UpdateMouse() io.MouseHoveredViewport = 0; // Update buttons - ImGuiIO& io = ImGui::GetIO(); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) { // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. @@ -296,7 +312,8 @@ static void ImGui_ImplGlfw_CreateViewport(ImGuiViewport* viewport) glfwWindowHint(GLFW_VISIBLE, false); glfwWindowHint(GLFW_FOCUSED, false); glfwWindowHint(GLFW_DECORATED, (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? false : true); - data->Window = glfwCreateWindow((int)viewport->Size.x, (int)viewport->Size.y, "No Title Yet", NULL, g_Window); + GLFWwindow* share_window = (g_ClientApi == GlfwClientApi_OpenGL) ? g_Window : NULL; + data->Window = glfwCreateWindow((int)viewport->Size.x, (int)viewport->Size.y, "No Title Yet", NULL, share_window); data->WindowOwned = true; viewport->PlatformHandle = (void*)data->Window; viewport->Name = NULL; @@ -405,7 +422,8 @@ static void ImGui_ImplGlfw_SetWindowTitle(ImGuiViewport* viewport, const char* t static void ImGui_ImplGlfw_RenderViewport(ImGuiViewport* viewport) { ImGuiPlatformDataGlfw* data = (ImGuiPlatformDataGlfw*)viewport->PlatformUserData; - glfwMakeContextCurrent(data->Window); + if (g_ClientApi == GlfwClientApi_OpenGL) + glfwMakeContextCurrent(data->Window); if (glfwWindowShouldClose(data->Window)) viewport->PlatformRequestClose = true; @@ -414,7 +432,8 @@ static void ImGui_ImplGlfw_RenderViewport(ImGuiViewport* viewport) static void ImGui_ImplGlfw_SwapBuffers(ImGuiViewport* viewport) { ImGuiPlatformDataGlfw* data = (ImGuiPlatformDataGlfw*)viewport->PlatformUserData; - glfwSwapBuffers(data->Window); + if (g_ClientApi == GlfwClientApi_OpenGL) + glfwSwapBuffers(data->Window); } static void ImGui_ImplGlfw_InitPlatformInterface() diff --git a/examples/imgui_impl_glfw.h b/examples/imgui_impl_glfw.h index 3e8fd6c7..c19089d0 100644 --- a/examples/imgui_impl_glfw.h +++ b/examples/imgui_impl_glfw.h @@ -13,6 +13,7 @@ struct GLFWwindow; IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); +IMGUI_API bool ImGui_ImplGlfw_InitForVulkan(GLFWwindow* window, bool install_callbacks); IMGUI_API void ImGui_ImplGlfw_Shutdown(); IMGUI_API void ImGui_ImplGlfw_NewFrame(); diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index 2e4ca7af..2a728ea6 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -57,6 +57,10 @@ static VkBuffer g_IndexBuffer[IMGUI_VK_QUEUED_FRAMES] = {}; static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE; static VkBuffer g_UploadBuffer = VK_NULL_HANDLE; +// Forward Declarations +static void ImGui_ImplVulkan_InitPlatformInterface(); +static void ImGui_ImplVulkan_ShutdownPlatformInterface(); + static uint32_t __glsl_shader_vert_spv[] = { 0x07230203,0x00010000,0x00080001,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b, @@ -699,12 +703,17 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo *init_data) g_DescriptorPool = init_data->DescriptorPool; g_CheckVkResult = init_data->CheckVkResultFn; + ImGuiIO& io = ImGui::GetIO(); ImGui_ImplVulkan_CreateDeviceObjects(); + if (io.ConfigFlags & ImGuiConfigFlags_MultiViewports) + ImGui_ImplVulkan_InitPlatformInterface(); + return true; } void ImGui_ImplVulkan_Shutdown() { + ImGui_ImplVulkan_ShutdownPlatformInterface(); ImGui_ImplVulkan_InvalidateDeviceObjects(); } @@ -790,3 +799,83 @@ VkPresentModeKHR ImGui_ImplVulkan_SelectPresentMode(VkPhysicalDevice physical_de return VK_PRESENT_MODE_FIFO_KHR; // Always available } + +// -------------------------------------------------------------------------------------------------------- +// Platform Windows (OPTIONAL/EXPERIMENTAL) +// -------------------------------------------------------------------------------------------------------- + +#include "imgui_internal.h" // ImGuiViewport + +struct ImGuiPlatformDataVulkan +{ + // store swap chain, render target/frame buffer, etc. + + ImGuiPlatformDataVulkan() { } + ~ImGuiPlatformDataVulkan() { } +}; + +static void ImGui_ImplVulkan_CreateViewport(ImGuiViewport* viewport) +{ + ImGuiPlatformDataVulkan* data = IM_NEW(ImGuiPlatformDataVulkan)(); + viewport->RendererUserData = data; + + // FIXME-PLATFORM + //HWND hwnd = (HWND)viewport->PlatformHandle; + //IM_ASSERT(hwnd != 0); + + //... +} + +static void ImGui_ImplVulkan_DestroyViewport(ImGuiViewport* viewport) +{ + if (ImGuiPlatformDataVulkan* data = (ImGuiPlatformDataVulkan*)viewport->RendererUserData) + { + //... + IM_DELETE(data); + } + viewport->RendererUserData = NULL; +} + +static void ImGui_ImplVulkan_ResizeViewport(ImGuiViewport* viewport, int w, int h) +{ + ImGuiPlatformDataVulkan* data = (ImGuiPlatformDataVulkan*)viewport->RendererUserData; + //... + (void)data; + (void)w; + (void)h; +} + +static void ImGui_ImplVulkan_RenderViewport(ImGuiViewport* viewport) +{ + ImGuiPlatformDataVulkan* data = (ImGuiPlatformDataVulkan*)viewport->RendererUserData; + ImVec4 clear_color = ImGui::GetStyle().Colors[ImGuiCol_WindowBg]; // FIXME-PLATFORM + clear_color.w = 1.0f; + + (void)data; + // clear + // call ImGui_ImplVulkan_RenderDrawData(&viewport->DrawData) +} + +static void ImGui_ImplVulkan_SwapBuffers(ImGuiViewport* viewport) +{ + ImGuiPlatformDataVulkan* data = (ImGuiPlatformDataVulkan*)viewport->RendererUserData; + (void)data; + //... +} + +void ImGui_ImplVulkan_InitPlatformInterface() +{ + ImGuiIO& io = ImGui::GetIO(); + io.RendererInterface.CreateViewport = ImGui_ImplVulkan_CreateViewport; + io.RendererInterface.DestroyViewport = ImGui_ImplVulkan_DestroyViewport; + io.RendererInterface.ResizeViewport = ImGui_ImplVulkan_ResizeViewport; + io.RendererInterface.RenderViewport = ImGui_ImplVulkan_RenderViewport; + io.RendererInterface.SwapBuffers = ImGui_ImplVulkan_SwapBuffers; +} + +void ImGui_ImplVulkan_ShutdownPlatformInterface() +{ + ImGuiIO& io = ImGui::GetIO(); + memset(&io.RendererInterface, 0, sizeof(io.RendererInterface)); +} + diff --git a/examples/vulkan_example/main.cpp b/examples/vulkan_example/main.cpp index ebd458a9..2e6c8bbd 100644 --- a/examples/vulkan_example/main.cpp +++ b/examples/vulkan_example/main.cpp @@ -568,10 +568,11 @@ int main(int, char**) init_info.CheckVkResultFn = check_vk_result; ImGuiIO& io = ImGui::GetIO(); (void)io; + //io.ConfigFlags |= ImGuiConfigFlags_MultiViewports; //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplVulkan_Init(&init_info); - ImGui_ImplGlfw_Init(window, true); + ImGui_ImplGlfw_InitForVulkan(window, true); // Setup style ImGui::StyleColorsDark(); @@ -689,6 +690,9 @@ int main(int, char**) ImGui_ImplVulkan_Render(g_CommandBuffer[g_FrameIndex]); frame_end(); frame_present(); + + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindows(); } // Cleanup