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.

This commit is contained in:
omar 2018-03-02 19:23:01 +01:00
parent 5b282bdd48
commit 9da475e4e8
4 changed files with 123 additions and 10 deletions

View File

@ -36,7 +36,14 @@
#endif #endif
// Data // Data
enum GlfwClientApi
{
GlfwClientApi_Unknown,
GlfwClientApi_OpenGL,
GlfwClientApi_Vulkan
};
static GLFWwindow* g_Window = NULL; static GLFWwindow* g_Window = NULL;
static GlfwClientApi g_ClientApi = GlfwClientApi_Unknown;
static double g_Time = 0.0f; static double g_Time = 0.0f;
static bool g_MouseJustPressed[5] = { false, false, false, false, false }; static bool g_MouseJustPressed[5] = { false, false, false, false, false };
static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 }; static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_Count_] = { 0 };
@ -149,6 +156,15 @@ bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks)
if (io.ConfigFlags & ImGuiConfigFlags_MultiViewports) if (io.ConfigFlags & ImGuiConfigFlags_MultiViewports)
ImGui_ImplGlfw_InitPlatformInterface(); 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; return true;
} }
@ -161,6 +177,7 @@ void ImGui_ImplGlfw_Shutdown()
glfwDestroyCursor(g_MouseCursors[cursor_n]); glfwDestroyCursor(g_MouseCursors[cursor_n]);
g_MouseCursors[cursor_n] = NULL; g_MouseCursors[cursor_n] = NULL;
} }
g_ClientApi = GlfwClientApi_Unknown;
} }
static void ImGui_ImplGlfw_UpdateMouse() static void ImGui_ImplGlfw_UpdateMouse()
@ -176,7 +193,6 @@ static void ImGui_ImplGlfw_UpdateMouse()
io.MouseHoveredViewport = 0; io.MouseHoveredViewport = 0;
// Update buttons // Update buttons
ImGuiIO& io = ImGui::GetIO();
for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) 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. // 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_VISIBLE, false);
glfwWindowHint(GLFW_FOCUSED, false); glfwWindowHint(GLFW_FOCUSED, false);
glfwWindowHint(GLFW_DECORATED, (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? false : true); 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; data->WindowOwned = true;
viewport->PlatformHandle = (void*)data->Window; viewport->PlatformHandle = (void*)data->Window;
viewport->Name = NULL; viewport->Name = NULL;
@ -405,6 +422,7 @@ static void ImGui_ImplGlfw_SetWindowTitle(ImGuiViewport* viewport, const char* t
static void ImGui_ImplGlfw_RenderViewport(ImGuiViewport* viewport) static void ImGui_ImplGlfw_RenderViewport(ImGuiViewport* viewport)
{ {
ImGuiPlatformDataGlfw* data = (ImGuiPlatformDataGlfw*)viewport->PlatformUserData; ImGuiPlatformDataGlfw* data = (ImGuiPlatformDataGlfw*)viewport->PlatformUserData;
if (g_ClientApi == GlfwClientApi_OpenGL)
glfwMakeContextCurrent(data->Window); glfwMakeContextCurrent(data->Window);
if (glfwWindowShouldClose(data->Window)) if (glfwWindowShouldClose(data->Window))
@ -414,6 +432,7 @@ static void ImGui_ImplGlfw_RenderViewport(ImGuiViewport* viewport)
static void ImGui_ImplGlfw_SwapBuffers(ImGuiViewport* viewport) static void ImGui_ImplGlfw_SwapBuffers(ImGuiViewport* viewport)
{ {
ImGuiPlatformDataGlfw* data = (ImGuiPlatformDataGlfw*)viewport->PlatformUserData; ImGuiPlatformDataGlfw* data = (ImGuiPlatformDataGlfw*)viewport->PlatformUserData;
if (g_ClientApi == GlfwClientApi_OpenGL)
glfwSwapBuffers(data->Window); glfwSwapBuffers(data->Window);
} }

View File

@ -13,6 +13,7 @@
struct GLFWwindow; struct GLFWwindow;
IMGUI_API bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks); 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_Shutdown();
IMGUI_API void ImGui_ImplGlfw_NewFrame(); IMGUI_API void ImGui_ImplGlfw_NewFrame();

View File

@ -57,6 +57,10 @@ static VkBuffer g_IndexBuffer[IMGUI_VK_QUEUED_FRAMES] = {};
static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE; static VkDeviceMemory g_UploadBufferMemory = VK_NULL_HANDLE;
static VkBuffer g_UploadBuffer = 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[] = static uint32_t __glsl_shader_vert_spv[] =
{ {
0x07230203,0x00010000,0x00080001,0x0000002e,0x00000000,0x00020011,0x00000001,0x0006000b, 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_DescriptorPool = init_data->DescriptorPool;
g_CheckVkResult = init_data->CheckVkResultFn; g_CheckVkResult = init_data->CheckVkResultFn;
ImGuiIO& io = ImGui::GetIO();
ImGui_ImplVulkan_CreateDeviceObjects(); ImGui_ImplVulkan_CreateDeviceObjects();
if (io.ConfigFlags & ImGuiConfigFlags_MultiViewports)
ImGui_ImplVulkan_InitPlatformInterface();
return true; return true;
} }
void ImGui_ImplVulkan_Shutdown() void ImGui_ImplVulkan_Shutdown()
{ {
ImGui_ImplVulkan_ShutdownPlatformInterface();
ImGui_ImplVulkan_InvalidateDeviceObjects(); ImGui_ImplVulkan_InvalidateDeviceObjects();
} }
@ -790,3 +799,83 @@ VkPresentModeKHR ImGui_ImplVulkan_SelectPresentMode(VkPhysicalDevice physical_de
return VK_PRESENT_MODE_FIFO_KHR; // Always available 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));
}

View File

@ -568,10 +568,11 @@ int main(int, char**)
init_info.CheckVkResultFn = check_vk_result; init_info.CheckVkResultFn = check_vk_result;
ImGuiIO& io = ImGui::GetIO(); (void)io; ImGuiIO& io = ImGui::GetIO(); (void)io;
//io.ConfigFlags |= ImGuiConfigFlags_MultiViewports;
//io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls
ImGui_ImplVulkan_Init(&init_info); ImGui_ImplVulkan_Init(&init_info);
ImGui_ImplGlfw_Init(window, true); ImGui_ImplGlfw_InitForVulkan(window, true);
// Setup style // Setup style
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@ -689,6 +690,9 @@ int main(int, char**)
ImGui_ImplVulkan_Render(g_CommandBuffer[g_FrameIndex]); ImGui_ImplVulkan_Render(g_CommandBuffer[g_FrameIndex]);
frame_end(); frame_end();
frame_present(); frame_present();
ImGui::UpdatePlatformWindows();
ImGui::RenderPlatformWindows();
} }
// Cleanup // Cleanup