Skip to content

Commit

Permalink
Backends: SDL+GLFW, Examples: SDL+Metal, GLFW+Metal: Fix viewport sup…
Browse files Browse the repository at this point in the history
…port with Metal backend.

Fixes #5392 + alignment fixes and removed static_cast<>
  • Loading branch information
rokups authored and ocornut committed Jun 16, 2022
1 parent e135cdb commit 9ff3017
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 26 deletions.
7 changes: 7 additions & 0 deletions backends/imgui_impl_glfw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,10 @@
#endif

// GLFW
#define GLFW_EXPOSE_NATIVE_COCOA
#include <GLFW/glfw3.h>
#include <GLFW/glfw3native.h>

#ifdef _WIN32
#undef APIENTRY
#define GLFW_EXPOSE_NATIVE_WIN32
Expand Down Expand Up @@ -538,6 +541,8 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
main_viewport->PlatformHandle = (void*)bd->Window;
#ifdef _WIN32
main_viewport->PlatformHandleRaw = glfwGetWin32Window(bd->Window);
#elif defined(__APPLE__)
main_viewport->PlatformHandleRaw = (void*)glfwGetCocoaWindow(bd->Window);
#endif
if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)
ImGui_ImplGlfw_InitPlatformInterface();
Expand Down Expand Up @@ -877,6 +882,8 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
viewport->PlatformHandle = (void*)vd->Window;
#ifdef _WIN32
viewport->PlatformHandleRaw = glfwGetWin32Window(vd->Window);
#elif defined(__APPLE__)
viewport->PlatformHandleRaw = (void*)glfwGetCocoaWindow(vd->Window);
#endif
glfwSetWindowPos(vd->Window, (int)viewport->Pos.x, (int)viewport->Pos.y);

Expand Down
14 changes: 7 additions & 7 deletions backends/imgui_impl_metal.mm
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,16 @@ - (MetalBuffer*)dequeueReusableBufferOfLength:(NSUInteger)length device:(id<MTLD

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

Expand Down Expand Up @@ -462,7 +462,7 @@ static void ImGui_ImplMetal_RenderWindow(ImGuiViewport* viewport, void*)
}
data->FirstFrame = false;

viewport->DpiScale = static_cast<float>(window.backingScaleFactor);
viewport->DpiScale = (float)window.backingScaleFactor;
if (data->MetalLayer.contentsScale != viewport->DpiScale)
{
data->MetalLayer.contentsScale = viewport->DpiScale;
Expand Down
28 changes: 14 additions & 14 deletions backends/imgui_impl_osx.mm
Original file line number Diff line number Diff line change
Expand Up @@ -63,23 +63,23 @@
// 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
static void ImGui_ImplOSX_InitPlatformInterface();
Expand Down
14 changes: 12 additions & 2 deletions backends/imgui_impl_sdl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
main_viewport->PlatformHandle = (void*)window;
#ifdef _WIN32
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (SDL_GetWindowWMInfo(window, &info))
{
#ifdef _WIN32
main_viewport->PlatformHandleRaw = (void*)info.info.win.window;
#elif defined(__APPLE__)
main_viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
#endif
}

// 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.
Expand Down Expand Up @@ -639,6 +643,8 @@ static void ImGui_ImplSDL2_UpdateMonitors()
monitor.WorkSize = ImVec2((float)r.w, (float)r.h);
#endif
#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;
if (!SDL_GetDisplayDPI(n, &dpi, NULL, NULL))
monitor.DpiScale = dpi / 96.0f;
Expand Down Expand Up @@ -748,12 +754,16 @@ static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport)
SDL_GL_MakeCurrent(vd->Window, backup_context);

viewport->PlatformHandle = (void*)vd->Window;
#if defined(_WIN32)
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (SDL_GetWindowWMInfo(vd->Window, &info))
{
#if defined(_WIN32)
viewport->PlatformHandleRaw = info.info.win.window;
#elif defined(__APPLE__)
viewport->PlatformHandleRaw = (void*)info.info.cocoa.window;
#endif
}
}

static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)
Expand Down
5 changes: 3 additions & 2 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,9 @@ Docking+Viewports Branch:
- Viewports: Fixed main viewport size not matching ImDrawData::DisplaySize for one frame during resize
when multi-viewports are disabled. (#4900)
- 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]


-----------------------------------------------------------------------
Expand Down
19 changes: 18 additions & 1 deletion examples/example_glfw_metal/main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,21 @@ 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

// Setup style
ImGui::StyleColorsDark();
//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
// - 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.
Expand Down Expand Up @@ -64,7 +74,7 @@ int main(int, char**)
id <MTLCommandQueue> commandQueue = [device newCommandQueue];

// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplGlfw_InitForOther(window, true);
ImGui_ImplMetal_Init(device);

NSWindow *nswin = glfwGetCocoaWindow(window);
Expand Down Expand Up @@ -152,6 +162,13 @@ int main(int, char**)
ImGui::Render();
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 endEncoding];

Expand Down
17 changes: 17 additions & 0 deletions examples/example_sdl_metal/main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,21 @@ 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

// Setup style
ImGui::StyleColorsDark();
//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
// - 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.
Expand Down Expand Up @@ -160,6 +170,13 @@ int main(int, char**)
ImGui::Render();
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 endEncoding];

Expand Down

0 comments on commit 9ff3017

Please sign in to comment.