Browse Source

Backends: SDL+GLFW, Examples: SDL+Metal, GLFW+Metal: Fix viewport support with Metal backend.

Fixes #5392 + alignment fixes and removed static_cast<> + Amended with fix.
rokups 3 years ago
parent
commit
101aec95d9

+ 11 - 1
backends/imgui_impl_glfw.cpp

@@ -71,11 +71,17 @@
 
 
 // GLFW
 // GLFW
 #include <GLFW/glfw3.h>
 #include <GLFW/glfw3.h>
+
 #ifdef _WIN32
 #ifdef _WIN32
 #undef APIENTRY
 #undef APIENTRY
 #define GLFW_EXPOSE_NATIVE_WIN32
 #define GLFW_EXPOSE_NATIVE_WIN32
-#include <GLFW/glfw3native.h>   // for glfwGetWin32Window
+#include <GLFW/glfw3native.h>   // for glfwGetWin32Window()
+#endif
+#ifdef __APPLE__
+#define GLFW_EXPOSE_NATIVE_COCOA
+#include <GLFW/glfw3native.h>   // for glfwGetCocoaWindow()
 #endif
 #endif
+
 #define GLFW_HAS_WINDOW_TOPMOST       (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ GLFW_FLOATING
 #define GLFW_HAS_WINDOW_TOPMOST       (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3200) // 3.2+ GLFW_FLOATING
 #define GLFW_HAS_WINDOW_HOVERED       (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_HOVERED
 #define GLFW_HAS_WINDOW_HOVERED       (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ GLFW_HOVERED
 #define GLFW_HAS_WINDOW_ALPHA         (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwSetWindowOpacity
 #define GLFW_HAS_WINDOW_ALPHA         (GLFW_VERSION_MAJOR * 1000 + GLFW_VERSION_MINOR * 100 >= 3300) // 3.3+ glfwSetWindowOpacity
@@ -538,6 +544,8 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
     main_viewport->PlatformHandle = (void*)bd->Window;
     main_viewport->PlatformHandle = (void*)bd->Window;
 #ifdef _WIN32
 #ifdef _WIN32
     main_viewport->PlatformHandleRaw = glfwGetWin32Window(bd->Window);
     main_viewport->PlatformHandleRaw = glfwGetWin32Window(bd->Window);
+#elif defined(__APPLE__)
+    main_viewport->PlatformHandleRaw = (void*)glfwGetCocoaWindow(bd->Window);
 #endif
 #endif
     if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
     if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
         ImGui_ImplGlfw_InitPlatformInterface();
         ImGui_ImplGlfw_InitPlatformInterface();
@@ -877,6 +885,8 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
     viewport->PlatformHandle = (void*)vd->Window;
     viewport->PlatformHandle = (void*)vd->Window;
 #ifdef _WIN32
 #ifdef _WIN32
     viewport->PlatformHandleRaw = glfwGetWin32Window(vd->Window);
     viewport->PlatformHandleRaw = glfwGetWin32Window(vd->Window);
+#elif defined(__APPLE__)
+    viewport->PlatformHandleRaw = (void*)glfwGetCocoaWindow(vd->Window);
 #endif
 #endif
     glfwSetWindowPos(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y);
     glfwSetWindowPos(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y);
 
 

+ 7 - 7
backends/imgui_impl_metal.mm

@@ -75,16 +75,16 @@ static void ImGui_ImplMetal_InvalidateDeviceObjectsForPlatformWindows();
 
 
 struct ImGui_ImplMetal_Data
 struct ImGui_ImplMetal_Data
 {
 {
-    MetalContext*            SharedMetalContext;
+    MetalContext*               SharedMetalContext;
 
 
-    ImGui_ImplMetal_Data()  { memset(this, 0, sizeof(*this)); }
+    ImGui_ImplMetal_Data()      { memset(this, 0, sizeof(*this)); }
 };
 };
 
 
-static ImGui_ImplMetal_Data*     ImGui_ImplMetal_CreateBackendData()  { return IM_NEW(ImGui_ImplMetal_Data)(); }
-static ImGui_ImplMetal_Data*     ImGui_ImplMetal_GetBackendData()     { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : NULL; }
-static void                      ImGui_ImplMetal_DestroyBackendData() { IM_DELETE(ImGui_ImplMetal_GetBackendData()); }
+static ImGui_ImplMetal_Data*    ImGui_ImplMetal_CreateBackendData() { return IM_NEW(ImGui_ImplMetal_Data)(); }
+static ImGui_ImplMetal_Data*    ImGui_ImplMetal_GetBackendData()    { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : NULL; }
+static void                     ImGui_ImplMetal_DestroyBackendData(){ IM_DELETE(ImGui_ImplMetal_GetBackendData()); }
 
 
-static inline CFTimeInterval     GetMachAbsoluteTimeInSeconds()       { return static_cast<CFTimeInterval>(static_cast<double>(clock_gettime_nsec_np(CLOCK_UPTIME_RAW)) / 1e9); }
+static inline CFTimeInterval    GetMachAbsoluteTimeInSeconds()      { return (CFTimeInterval)(double)(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1e9); }
 
 
 #ifdef IMGUI_IMPL_METAL_CPP
 #ifdef IMGUI_IMPL_METAL_CPP
 
 
@@ -462,7 +462,7 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
     }
     }
     data->FirstFrame = false;
     data->FirstFrame = false;
 
 
-    viewport->DpiScale = static_cast<float>(window.backingScaleFactor);
+    viewport->DpiScale = (float)window.backingScaleFactor;
     if (data->MetalLayer.contentsScale != viewport->DpiScale)
     if (data->MetalLayer.contentsScale != viewport->DpiScale)
     {
     {
         data->MetalLayer.contentsScale = viewport->DpiScale;
         data->MetalLayer.contentsScale = viewport->DpiScale;

+ 14 - 14
backends/imgui_impl_osx.mm

@@ -63,23 +63,23 @@
 // Data
 // Data
 struct ImGui_ImplOSX_Data
 struct ImGui_ImplOSX_Data
 {
 {
-    CFTimeInterval          Time;
-    NSCursor*               MouseCursors[ImGuiMouseCursor_COUNT];
-    bool                    MouseCursorHidden;
-    ImGuiObserver*          Observer;
-    KeyEventResponder*      KeyEventResponder;
-    NSTextInputContext*     InputContext;
-    id                      Monitor;
-    NSWindow*               Window;
-
-    ImGui_ImplOSX_Data()    { memset(this, 0, sizeof(*this)); }
+    CFTimeInterval              Time;
+    NSCursor*                   MouseCursors[ImGuiMouseCursor_COUNT];
+    bool                        MouseCursorHidden;
+    ImGuiObserver*              Observer;
+    KeyEventResponder*          KeyEventResponder;
+    NSTextInputContext*         InputContext;
+    id                          Monitor;
+    NSWindow*                   Window;
+
+    ImGui_ImplOSX_Data()        { memset(this, 0, sizeof(*this)); }
 };
 };
 
 
-static ImGui_ImplOSX_Data*  ImGui_ImplOSX_CreateBackendData()  { return IM_NEW(ImGui_ImplOSX_Data)(); }
-static ImGui_ImplOSX_Data*  ImGui_ImplOSX_GetBackendData()     { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; }
-static void                 ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(ImGui_ImplOSX_GetBackendData()); }
+static ImGui_ImplOSX_Data*      ImGui_ImplOSX_CreateBackendData()   { return IM_NEW(ImGui_ImplOSX_Data)(); }
+static ImGui_ImplOSX_Data*      ImGui_ImplOSX_GetBackendData()      { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; }
+static void                     ImGui_ImplOSX_DestroyBackendData()  { IM_DELETE(ImGui_ImplOSX_GetBackendData()); }
 
 
-static inline CFTimeInterval GetMachAbsoluteTimeInSeconds()    { return static_cast<CFTimeInterval>(static_cast<double>(clock_gettime_nsec_np(CLOCK_UPTIME_RAW)) / 1e9); }
+static inline CFTimeInterval    GetMachAbsoluteTimeInSeconds()      { return (CFTimeInterval)(double)(clock_gettime_nsec_np(CLOCK_UPTIME_RAW) / 1e9); }
 
 
 // Forward Declarations
 // Forward Declarations
 static void ImGui_ImplOSX_InitPlatformInterface();
 static void ImGui_ImplOSX_InitPlatformInterface();

+ 12 - 2
backends/imgui_impl_sdl.cpp

@@ -408,12 +408,16 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void
     // Our mouse update function expect PlatformHandle to be filled for the main viewport
     // Our mouse update function expect PlatformHandle to be filled for the main viewport
     ImGuiViewport* main_viewport = ImGui::GetMainViewport();
     ImGuiViewport* main_viewport = ImGui::GetMainViewport();
     main_viewport->PlatformHandle = (void*)window;
     main_viewport->PlatformHandle = (void*)window;
-#ifdef _WIN32
     SDL_SysWMinfo info;
     SDL_SysWMinfo info;
     SDL_VERSION(&info.version);
     SDL_VERSION(&info.version);
     if (SDL_GetWindowWMInfo(window, &info))
     if (SDL_GetWindowWMInfo(window, &info))
+    {
+#ifdef _WIN32
         main_viewport->PlatformHandleRaw = (void*)info.info.win.window;
         main_viewport->PlatformHandleRaw = (void*)info.info.win.window;
+#elif defined(__APPLE__)
+        main_viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
 #endif
 #endif
+    }
 
 
     // Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event.
     // Set SDL hint to receive mouse click events on window focus, otherwise SDL doesn't emit the event.
     // Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered.
     // Without this, when clicking to gain focus, our widgets wouldn't activate even though they showed as hovered.
@@ -639,6 +643,8 @@ static void ImGui_ImplSDL2_UpdateMonitors()
         monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
         monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
 #endif
 #endif
 #if SDL_HAS_PER_MONITOR_DPI
 #if SDL_HAS_PER_MONITOR_DPI
+        // FIXME-VIEWPORT: On MacOS SDL reports actual monitor DPI scale, ignoring OS configuration. We may want to set
+        //  DpiScale to cocoa_window.backingScaleFactor here.
         float dpi = 0.0f;
         float dpi = 0.0f;
         if (!SDL_GetDisplayDPI(n, &dpi, NULL, NULL))
         if (!SDL_GetDisplayDPI(n, &dpi, NULL, NULL))
             monitor.DpiScale = dpi / 96.0f;
             monitor.DpiScale = dpi / 96.0f;
@@ -748,12 +754,16 @@ static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport)
         SDL_GL_MakeCurrent(vd->Window, backup_context);
         SDL_GL_MakeCurrent(vd->Window, backup_context);
 
 
     viewport->PlatformHandle = (void*)vd->Window;
     viewport->PlatformHandle = (void*)vd->Window;
-#if defined(_WIN32)
     SDL_SysWMinfo info;
     SDL_SysWMinfo info;
     SDL_VERSION(&info.version);
     SDL_VERSION(&info.version);
     if (SDL_GetWindowWMInfo(vd->Window, &info))
     if (SDL_GetWindowWMInfo(vd->Window, &info))
+    {
+#if defined(_WIN32)
         viewport->PlatformHandleRaw = info.info.win.window;
         viewport->PlatformHandleRaw = info.info.win.window;
+#elif defined(__APPLE__)
+        viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
 #endif
 #endif
+    }
 }
 }
 
 
 static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)
 static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)

+ 3 - 2
docs/CHANGELOG.txt

@@ -233,8 +233,9 @@ Docking+Viewports Branch:
 - Viewports: Fixed main viewport size not matching ImDrawData::DisplaySize for one frame during resize
 - Viewports: Fixed main viewport size not matching ImDrawData::DisplaySize for one frame during resize
   when multi-viewports are disabled. (#4900)
   when multi-viewports are disabled. (#4900)
 - Backends: SDL: Fixed dragging out main viewport broken on some SDL setups. (#5012) [@rokups]
 - Backends: SDL: Fixed dragging out main viewport broken on some SDL setups. (#5012) [@rokups]
-- Backends: OSX: Added suppot for multi-viewports. [@stuartcarnie, @metarutaiga] (#4821, #2778)
-- Backends: Metal: Added suppot for multi-viewports. [@stuartcarnie, @metarutaiga] (#4821, #2778)
+- Backends: OSX: Added support for multi-viewports. [@stuartcarnie, @metarutaiga] (#4821, #2778)
+- Backends: Metal: Added support for multi-viewports. [@stuartcarnie, @metarutaiga] (#4821, #2778)
+- Examples: OSX+Metal, SDL+Metal, GLFW+Metal: Added support for multi-viewports. [@rokups]
 
 
 
 
 -----------------------------------------------------------------------
 -----------------------------------------------------------------------

+ 18 - 1
examples/example_glfw_metal/main.mm

@@ -29,11 +29,21 @@ int main(int, char**)
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;   // Enable Gamepad Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;   // Enable Gamepad Controls
+    io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;        // Enable Docking
+    io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;      // Enable Multi-Viewport / Platform Windows
 
 
     // Setup style
     // Setup style
     ImGui::StyleColorsDark();
     ImGui::StyleColorsDark();
     //ImGui::StyleColorsClassic();
     //ImGui::StyleColorsClassic();
 
 
+    // 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;
+    }
+
     // Load Fonts
     // Load Fonts
     // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
     // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
     // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
     // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
@@ -64,7 +74,7 @@ int main(int, char**)
     id <MTLCommandQueue> commandQueue = [device newCommandQueue];
     id <MTLCommandQueue> commandQueue = [device newCommandQueue];
 
 
     // Setup Platform/Renderer backends
     // Setup Platform/Renderer backends
-    ImGui_ImplGlfw_InitForOpenGL(window, true);
+    ImGui_ImplGlfw_InitForOther(window, true);
     ImGui_ImplMetal_Init(device);
     ImGui_ImplMetal_Init(device);
 
 
     NSWindow *nswin = glfwGetCocoaWindow(window);
     NSWindow *nswin = glfwGetCocoaWindow(window);
@@ -152,6 +162,13 @@ int main(int, char**)
             ImGui::Render();
             ImGui::Render();
             ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
             ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
 
 
+            // Update and Render additional Platform Windows
+            if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
+            {
+                ImGui::UpdatePlatformWindows();
+                ImGui::RenderPlatformWindowsDefault();
+            }
+
             [renderEncoder popDebugGroup];
             [renderEncoder popDebugGroup];
             [renderEncoder endEncoding];
             [renderEncoder endEncoding];
 
 

+ 17 - 0
examples/example_sdl_metal/main.mm

@@ -20,11 +20,21 @@ int main(int, char**)
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     ImGuiIO& io = ImGui::GetIO(); (void)io;
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;  // Enable Keyboard Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;   // Enable Gamepad Controls
     //io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;   // Enable Gamepad Controls
+    io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;        // Enable Docking
+    io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;      // Enable Multi-Viewport / Platform Windows
 
 
     // Setup style
     // Setup style
     ImGui::StyleColorsDark();
     ImGui::StyleColorsDark();
     //ImGui::StyleColorsClassic();
     //ImGui::StyleColorsClassic();
 
 
+    // 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;
+    }
+
     // Load Fonts
     // Load Fonts
     // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
     // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
     // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
     // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple.
@@ -160,6 +170,13 @@ int main(int, char**)
             ImGui::Render();
             ImGui::Render();
             ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
             ImGui_ImplMetal_RenderDrawData(ImGui::GetDrawData(), commandBuffer, renderEncoder);
 
 
+            // Update and Render additional Platform Windows
+            if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
+            {
+                ImGui::UpdatePlatformWindows();
+                ImGui::RenderPlatformWindowsDefault();
+            }
+
             [renderEncoder popDebugGroup];
             [renderEncoder popDebugGroup];
             [renderEncoder endEncoding];
             [renderEncoder endEncoding];