Backends: SDL: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(). Use SDL_GetRendererOutputSize() instead of SDL_GL_GetDrawableSize() when bound to a SDL_Renderer. (#4927)
This is (kind of) an OpenGL-only function, which should be avoided when SDL2 isn't using OpenGL.
The only alternative that is recommended is SDL_GetRendererOutputSize, which limits this fix to the SDL_Renderer backend. Still, I think it's better than nothing.
I say that SDL_GL_GetDrawableSize is "kind of" OpenGL-only because it does technically work even when SDL2 isn't using OpenGL.
It's just that it becomes a shim to SDL_GetWindowSize, which is not suitable for high-DPI usage because it reflects the size of the window in screen coordinates, not actual pixels, so it really should be avoided when not using OpenGL.
diff --git a/backends/imgui_impl_sdl.cpp b/backends/imgui_impl_sdl.cpp
index 0b9f9c0..9764cb2 100644
--- a/backends/imgui_impl_sdl.cpp
+++ b/backends/imgui_impl_sdl.cpp
@@ -18,6 +18,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
+// 2022-02-04: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(), so we can use SDL_GetRendererOutputSize() instead of SDL_GL_GetDrawableSize() when bound to a SDL_Renderer.
// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion.
// 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
// 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
@@ -78,12 +79,13 @@
// SDL Data
struct ImGui_ImplSDL2_Data
{
- SDL_Window* Window;
- Uint64 Time;
- int MouseButtonsDown;
- SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
- char* ClipboardTextData;
- bool MouseCanUseGlobalState;
+ SDL_Window* Window;
+ SDL_Renderer* Renderer;
+ Uint64 Time;
+ int MouseButtonsDown;
+ SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
+ char* ClipboardTextData;
+ bool MouseCanUseGlobalState;
ImGui_ImplSDL2_Data() { memset(this, 0, sizeof(*this)); }
};
@@ -299,7 +301,7 @@
return false;
}
-static bool ImGui_ImplSDL2_Init(SDL_Window* window)
+static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer)
{
ImGuiIO& io = ImGui::GetIO();
IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!");
@@ -323,6 +325,7 @@
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
bd->Window = window;
+ bd->Renderer = renderer;
bd->MouseCanUseGlobalState = mouse_can_use_global_state;
io.SetClipboardTextFn = ImGui_ImplSDL2_SetClipboardText;
@@ -365,7 +368,7 @@
bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context)
{
IM_UNUSED(sdl_gl_context); // Viewport branch will need this.
- return ImGui_ImplSDL2_Init(window);
+ return ImGui_ImplSDL2_Init(window, NULL);
}
bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window)
@@ -373,7 +376,7 @@
#if !SDL_HAS_VULKAN
IM_ASSERT(0 && "Unsupported");
#endif
- return ImGui_ImplSDL2_Init(window);
+ return ImGui_ImplSDL2_Init(window, NULL);
}
bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window)
@@ -381,17 +384,17 @@
#if !defined(_WIN32)
IM_ASSERT(0 && "Unsupported");
#endif
- return ImGui_ImplSDL2_Init(window);
+ return ImGui_ImplSDL2_Init(window, NULL);
}
bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window)
{
- return ImGui_ImplSDL2_Init(window);
+ return ImGui_ImplSDL2_Init(window, NULL);
}
-bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window)
+bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer)
{
- return ImGui_ImplSDL2_Init(window);
+ return ImGui_ImplSDL2_Init(window, renderer);
}
void ImGui_ImplSDL2_Shutdown()
@@ -520,7 +523,10 @@
SDL_GetWindowSize(bd->Window, &w, &h);
if (SDL_GetWindowFlags(bd->Window) & SDL_WINDOW_MINIMIZED)
w = h = 0;
- SDL_GL_GetDrawableSize(bd->Window, &display_w, &display_h);
+ if (bd->Renderer != NULL)
+ SDL_GetRendererOutputSize(bd->Renderer, &display_w, &display_h);
+ else
+ SDL_GL_GetDrawableSize(bd->Window, &display_w, &display_h);
io.DisplaySize = ImVec2((float)w, (float)h);
if (w > 0 && h > 0)
io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h);
diff --git a/backends/imgui_impl_sdl.h b/backends/imgui_impl_sdl.h
index 3db454c..dc18c2c 100644
--- a/backends/imgui_impl_sdl.h
+++ b/backends/imgui_impl_sdl.h
@@ -19,13 +19,14 @@
#include "imgui.h" // IMGUI_IMPL_API
struct SDL_Window;
+struct SDL_Renderer;
typedef union SDL_Event SDL_Event;
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context);
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window);
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window);
IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window);
-IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window);
+IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer);
IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown();
IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame();
IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event);
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt
index bcc4b0a..edfd466 100644
--- a/docs/CHANGELOG.txt
+++ b/docs/CHANGELOG.txt
@@ -86,6 +86,8 @@
- If calling ImGui_ImplGlfw_InitXXX with install_callbacks=true: nothing to do. is already done for you.
- If calling ImGui_ImplGlfw_InitXXX with install_callbacks=false: you WILL NEED to register the GLFW callback
using glfwSetCursorPosCallback() and forward it to the backend function ImGui_ImplGlfw_CursorPosCallback().
+- Backends: SDL: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(), so backend can call
+ SDL_GetRendererOutputSize() to obtain framebuffer size valid for hi-dpi. (#4927) [@Clownacy]
- Commented out redirecting functions/enums names that were marked obsolete in 1.69, 1.70, 1.71, 1.72 (March-July 2019)
- ImGui::SetNextTreeNodeOpen() -> use ImGui::SetNextItemOpen()
- ImGui::GetContentRegionAvailWidth() -> use ImGui::GetContentRegionAvail().x
diff --git a/examples/example_sdl_sdlrenderer/main.cpp b/examples/example_sdl_sdlrenderer/main.cpp
index aee4a78..582b5a1 100644
--- a/examples/example_sdl_sdlrenderer/main.cpp
+++ b/examples/example_sdl_sdlrenderer/main.cpp
@@ -30,7 +30,7 @@
}
// Setup window
- SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
+ SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+SDL_Renderer example", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1280, 720, window_flags);
// Setup SDL_Renderer instance
@@ -56,7 +56,7 @@
//ImGui::StyleColorsClassic();
// Setup Platform/Renderer backends
- ImGui_ImplSDL2_InitForSDLRenderer(window);
+ ImGui_ImplSDL2_InitForSDLRenderer(window, renderer);
ImGui_ImplSDLRenderer_Init(renderer);
// Load Fonts
@@ -100,7 +100,7 @@
// Start the Dear ImGui frame
ImGui_ImplSDLRenderer_NewFrame();
- ImGui_ImplSDL2_NewFrame(window);
+ ImGui_ImplSDL2_NewFrame();
ImGui::NewFrame();
// 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!).