From 910bf2068d543e4eaaae4e3c3e2f72f514fc728f Mon Sep 17 00:00:00 2001 From: Jared Hendry <105017+jaredh@users.noreply.github.com> Date: Fri, 4 Sep 2026 17:55:42 -0400 Subject: [PATCH 1/2] Improve ImGui fractional scaling support --- .../Silk.NET.Input/Silk.NET.Input.csproj | 3 +- .../ImGuiController.cs | 10 ++++-- src/Windowing/Silk.NET.GLFW/Glfw.cs | 32 +++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/Input/Silk.NET.Input/Silk.NET.Input.csproj b/src/Input/Silk.NET.Input/Silk.NET.Input.csproj index 0a8f41474e..b65264e11c 100644 --- a/src/Input/Silk.NET.Input/Silk.NET.Input.csproj +++ b/src/Input/Silk.NET.Input/Silk.NET.Input.csproj @@ -1,7 +1,8 @@  - netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0;net7.0-android;net7.0-ios;net7.0-maccatalyst + netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0;net7.0-android + $(TargetFrameworks);net7.0-ios;net7.0-maccatalyst true diff --git a/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs b/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs index 18f76a1e76..9c6a2deaf8 100644 --- a/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs +++ b/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs @@ -240,8 +240,8 @@ private void SetPerFrameImGuiData(float deltaSeconds) if (_windowWidth > 0 && _windowHeight > 0) { - io.DisplayFramebufferScale = new Vector2(_view.FramebufferSize.X / _windowWidth, - _view.FramebufferSize.Y / _windowHeight); + io.DisplayFramebufferScale = new Vector2((float) _view.FramebufferSize.X / _windowWidth, + (float) _view.FramebufferSize.Y / _windowHeight); } io.DeltaTime = deltaSeconds; // DeltaTime is in seconds. @@ -427,6 +427,9 @@ private unsafe void SetupRenderState(ImDrawDataPtr drawDataPtr, int framebufferW _gl.PolygonMode(GLEnum.FrontAndBack, GLEnum.Fill); #endif + // Setup viewport, orthographic projection matrix + _gl.Viewport(0, 0, (uint) framebufferWidth, (uint) framebufferHeight); + float L = drawDataPtr.DisplayPos.X; float R = drawDataPtr.DisplayPos.X + drawDataPtr.DisplaySize.X; float T = drawDataPtr.DisplayPos.Y; @@ -488,6 +491,8 @@ private unsafe void RenderImDrawData(ImDrawDataPtr drawDataPtr) _gl.GetInteger(GLEnum.PolygonMode, lastPolygonMode); #endif + Span lastViewport = stackalloc int[4]; + _gl.GetInteger(GLEnum.Viewport, lastViewport); Span lastScissorBox = stackalloc int[4]; _gl.GetInteger(GLEnum.ScissorBox, lastScissorBox); @@ -637,6 +642,7 @@ private unsafe void RenderImDrawData(ImDrawDataPtr drawDataPtr) _gl.PolygonMode(GLEnum.FrontAndBack, (GLEnum) lastPolygonMode[0]); #endif + _gl.Viewport(lastViewport[0], lastViewport[1], (uint) lastViewport[2], (uint) lastViewport[3]); _gl.Scissor(lastScissorBox[0], lastScissorBox[1], (uint) lastScissorBox[2], (uint) lastScissorBox[3]); } diff --git a/src/Windowing/Silk.NET.GLFW/Glfw.cs b/src/Windowing/Silk.NET.GLFW/Glfw.cs index 4cfe23caba..640ecc23cb 100644 --- a/src/Windowing/Silk.NET.GLFW/Glfw.cs +++ b/src/Windowing/Silk.NET.GLFW/Glfw.cs @@ -2063,6 +2063,38 @@ public unsafe partial WindowHandle* CreateWindow /// public unsafe partial void GetFramebufferSize(WindowHandle* window, out int width, out int height); + /// + /// + /// This function retrieves the content scale for the specified window. + /// + /// + /// The content scale is the ratio between the current DPI and the platform's default DPI. + /// + /// + /// If you scale all pixel dimensions by this scale then your content should appear at an appropriate size. + /// This is especially important for text and any UI elements. + /// + /// + /// On platforms where each monitor can have its own content scale, the window content scale + /// depends on which monitor the system considers the window to be on. + /// + /// + /// The window to query. + /// Where to store the x-axis content scale, or out _. + /// Where to store the y-axis content scale, or out _. + /// + /// + /// This function must only be called from the main thread. + /// + /// + /// Possible errors include and . + /// + /// + /// + // ReSharper disable IdentifierTypo + public unsafe partial void GetWindowContentScale(WindowHandle* window, out float xscale, out float yscale); + // ReSharper enable IdentifierTypo + /// /// /// This function returns the value of an input option for the specified window. From c3058c854367c6bb629f1db7e16c9a2099b00a4e Mon Sep 17 00:00:00 2001 From: Jared Hendry <105017+jaredh@users.noreply.github.com> Date: Fri, 4 Sep 2026 22:45:41 -0400 Subject: [PATCH 2/2] Update window size in SetPerFrameImGuiData, Resize not raised on Wayland --- .../ImGuiController.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs b/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs index 9c6a2deaf8..8ae4ae3f78 100644 --- a/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs +++ b/src/OpenGL/Extensions/Silk.NET.OpenGL.Extensions.ImGui/ImGuiController.cs @@ -236,12 +236,19 @@ public void Update(float deltaSeconds) private void SetPerFrameImGuiData(float deltaSeconds) { var io = ImGuiNET.ImGui.GetIO(); + var size = _view.Size; + var framebufferSize = _view.FramebufferSize; + + // Update here since Resize isn't raised on all platforms + _windowWidth = size.X; + _windowHeight = size.Y; + io.DisplaySize = new Vector2(_windowWidth, _windowHeight); if (_windowWidth > 0 && _windowHeight > 0) { - io.DisplayFramebufferScale = new Vector2((float) _view.FramebufferSize.X / _windowWidth, - (float) _view.FramebufferSize.Y / _windowHeight); + io.DisplayFramebufferScale = new Vector2((float) framebufferSize.X / _windowWidth, + (float) framebufferSize.Y / _windowHeight); } io.DeltaTime = deltaSeconds; // DeltaTime is in seconds.