diff --git a/Program.cs b/Program.cs index 00692fc..9af2dbf 100644 --- a/Program.cs +++ b/Program.cs @@ -1,8 +1,6 @@ using System.Numerics; using System.Runtime.CompilerServices; -using Hexa.NET.ImGui; -using Hexa.NET.ImPlot; -using Hexa.NET.ImPlot3D; +using ImGuiNET; using SDL3_TestingSuite.SDL3; using SDL3; @@ -11,17 +9,11 @@ namespace SDL3_TestingSuite; public class Program { private static bool _demoWindowVisible = true; - private static bool _fontStuff; - private static readonly Dictionary?> GlyphsByName = new Dictionary?>(); - private static bool _initialized; - private static ImFontPtr _font; - private static float size = 1f; public static void Main() { const SDL.WindowFlags flags = SDL.WindowFlags.Resizable | SDL.WindowFlags.HighPixelDensity | SDL.WindowFlags.Transparent; SDL3Window window = new SDL3Window("SDL3 Testing Suite", 100, 100, 1280, 720, flags); - window.ClearColor.W = 0f; window.RenderCallback = () => { ImGuiViewportPtr viewport = ImGui.GetMainViewport(); @@ -43,132 +35,15 @@ public class Program } ImGui.Spacing(); ImGui.MenuItem("Demo Window", "", ref _demoWindowVisible); - ImGui.Spacing(); - ImGui.MenuItem("Font Stuff", "", ref _fontStuff); ImGui.EndMenuBar(); } ImGui.End(); - if (_fontStuff) - { - ImGui.SetNextWindowSize(new Vector2(250, 500), ImGuiCond.FirstUseEver); - if (ImGui.Begin("FontStuff", ref _fontStuff)) - { - ImGui.ShowFontSelector("Font"); - - bool change = false; - if (ImGui.GetFont() != _font) - { - _font = ImGui.GetFont(); - change = true; - } - - string fontName = _font.GetDebugNameS(); - fontName = string.IsNullOrEmpty(fontName) ? _font.FontId.ToString() : fontName; - if (!_initialized || change) - { - if (!GlyphsByName.TryGetValue(fontName, out List glyphs)) - { - glyphs = new List(); - - ImFontPtr font = _font; - - for (uint codepoint = 0; codepoint <= 0x10FFFF; codepoint++) - { - if (codepoint >= 0xD800 && codepoint <= 0xDFFF) - { - continue; - } - - if (!font.IsGlyphInFont(codepoint)) continue; - - glyphs.Add(codepoint); - } - - GlyphsByName[fontName] = glyphs; - Logger.Log($"Initialized font {fontName} with {glyphs.Count} glyphs"); - } - - _initialized = true; - } - - ImGui.PushFont(null, 24); - - if (GlyphsByName.TryGetValue(fontName, out List glyphs2)) - { - float cursorXStart = ImGui.GetCursorPosX(); - float maxWidth = ImGui.GetContentRegionAvail().X; - - foreach (uint codepoint in glyphs2) - { - string text = char.ConvertFromUtf32((int)codepoint); - float glyphWidth = ImGui.CalcTextSize(text).X; - - float cursorX = ImGui.GetCursorPosX(); - if (cursorX > cursorXStart && (cursorX + glyphWidth) > (cursorXStart + maxWidth)) - { - ImGui.NewLine(); - } - - ImGui.TextUnformatted(text); - - ImGui.SameLine(); - } - } - - ImGui.PopFont(); - - ImGui.End(); - } - } - - float time = (float)ImGui.GetTime() * 5; - if (ImPlot.BeginPlot("Moving Rainbow Sine Wave")) - { - int count = 200; - - float[] xs = new float[2]; - float[] ys = new float[2]; - - for (int i = 0; i < count - 1; i++) - { - float x0 = i * 0.1f; - float x1 = (i + 1) * 0.1f; - - float y0 = MathF.Sin(x0 * size + time); - float y1 = MathF.Sin(x1 * size + time); - - xs[0] = x0; - xs[1] = x1; - - ys[0] = y0; - ys[1] = y1; - - float t = i / (float)count; - - float r = 0.5f + 1f * MathF.Sin(6.2831f * (t)); - float g = 0.5f + 1f * MathF.Sin(6.2831f * (t + 0.33f)); - float b = 0.5f + 1f * MathF.Sin(6.2831f * (t + 0.66f)); - - - ImPlot.PushStyleColor(ImPlotCol.Line, new Vector4(r, g, b, 1f)); - ImPlot.PlotLine("##seg", ref xs[0], ref ys[0], 2); - ImPlot.PopStyleColor(); - - } - - ImPlot.EndPlot(); - } - - ImGui.SliderFloat("Sine", ref size, 1f, 120f); - if (_demoWindowVisible) { ImGui.ShowDemoWindow(ref _demoWindowVisible); - ImPlot.ShowDemoWindow(ref _demoWindowVisible); - // ImPlot3D.ShowDemoWindow(ref _demoWindowVisible); } }; diff --git a/SDL3 TestingSuite.csproj b/SDL3 TestingSuite.csproj index 6821cfd..5e0fddd 100644 --- a/SDL3 TestingSuite.csproj +++ b/SDL3 TestingSuite.csproj @@ -11,12 +11,12 @@ - - - - - - + + + + + + diff --git a/SDL3 TestingSuite.sln.DotSettings.user b/SDL3 TestingSuite.sln.DotSettings.user index 5335a82..3ae7077 100644 --- a/SDL3 TestingSuite.sln.DotSettings.user +++ b/SDL3 TestingSuite.sln.DotSettings.user @@ -1,2 +1,3 @@  - ForceIncluded \ No newline at end of file + ForceIncluded + ForceIncluded \ No newline at end of file diff --git a/SDL3/FontFind.cs b/SDL3/FontFind.cs deleted file mode 100644 index d3c862c..0000000 --- a/SDL3/FontFind.cs +++ /dev/null @@ -1,162 +0,0 @@ -using Hexa.NET.ImGui; - -namespace SDL3_TestingSuite.SDL3; - -public struct FontMetrics -{ - public ushort UnitsPerEm; - - public short TypoAscender; - public short TypoDescender; - public short TypoLineGap; - - public short WinAscent; - public short WinDescent; - - public int TypoLineHeight; - public int WinLineHeight; -} - -public static class FontFind -{ - extension(ImGuiIOPtr io) - { - public unsafe ImFontPtr AddFont(string fontPath) - { - try - { - if (fontPath == null || io.Handle == null) return null; - FileInfo info = new FileInfo(fontPath); - if (!info.Exists || info.Length <= 0) return null; - - FontMetrics metrics = FontFind.ReadFontMetrics(fontPath); - float size = FontFind.GetRecommendedPixelSize(metrics); - - ImFontConfigPtr config = ImGui.ImFontConfig(); - config.FontLoaderFlags |= (uint)ImGuiFreeTypeLoaderFlags.LoadColor; - ImFontPtr font = io.Fonts.AddFontFromFileTTF(fontPath, size, config); - Program.Logger.Log("Added font: " + Path.GetFileName(fontPath)); - return font; - } - catch (Exception e) - { - Console.WriteLine(e); - } - return null; - } - public unsafe bool RemoveFont(string? fontName) - { - if (fontName == null || io.Handle == null) return false; - - bool flag = false; - ImVector fonts = io.Fonts.Fonts; - List toRemove = new List(); - - for (int i = 0; i < fonts.Size; i++) - { - ImFontPtr font = fonts[i]; - if (font.GetDebugNameS() == fontName) - { - toRemove.Add(font); - flag = true; - } - } - - foreach (ImFontPtr font in toRemove) - { - io.Fonts.RemoveFont(font); - Program.Logger.Log("Removed font: " + fontName); - } - - return flag; - } - } - - public static FontMetrics ReadFontMetrics(string fontPath) - { - byte[] data = File.ReadAllBytes(fontPath); - - ushort numTables = ReadU16Be(4); - const int tableDir = 12; - - int headOffset = 0; - int os2Offset = 0; - - for (int i = 0; i < numTables; i++) - { - int entry = tableDir + i * 16; - string tag = ReadTag(entry); - - uint offset = ReadU32Be(entry + 8); - - if (tag == "head") - headOffset = (int)offset; - - if (tag == "OS/2") - os2Offset = (int)offset; - } - - FontMetrics metrics = new FontMetrics(); - - metrics.UnitsPerEm = ReadU16Be(headOffset + 18); - - if (os2Offset != 0) - { - metrics.TypoAscender = ReadS16Be(os2Offset + 68); - metrics.TypoDescender = ReadS16Be(os2Offset + 70); - metrics.TypoLineGap = ReadS16Be(os2Offset + 72); - - metrics.WinAscent = ReadS16Be(os2Offset + 74); - metrics.WinDescent = ReadS16Be(os2Offset + 76); - } - - metrics.TypoLineHeight = - metrics.TypoAscender - metrics.TypoDescender + metrics.TypoLineGap; - - metrics.WinLineHeight = - metrics.WinAscent + metrics.WinDescent; - - return metrics; - - ushort ReadU16Be(int o) - { - return (ushort)((data[o] << 8) | data[o + 1]); - } - - short ReadS16Be(int o) - { - return (short)ReadU16Be(o); - } - - uint ReadU32Be(int o) - { - return (uint)((data[o] << 24) | (data[o + 1] << 16) | (data[o + 2] << 8) | data[o + 3]); - } - - string ReadTag(int o) - { - char c1 = (char)data[o]; - char c2 = (char)data[o + 1]; - char c3 = (char)data[o + 2]; - char c4 = (char)data[o + 3]; - return new string(new char[] { c1, c2, c3, c4 }); - } - } - - public static int GetRecommendedPixelSize(FontMetrics metrics) - { - if (metrics.UnitsPerEm == 0 || metrics.TypoLineHeight == 0) - return 16; - - const float targetLineHeightPx = 18.0f; - - float scale = targetLineHeightPx * metrics.UnitsPerEm / metrics.TypoLineHeight; - - int size = (int)MathF.Round(scale); - - if (size < 10) size = 10; - if (size > 72) size = 72; - - return size; - } -} \ No newline at end of file diff --git a/SDL3/ImGuiSDL3Platform.cs b/SDL3/ImGuiSDL3Platform.cs index 5123369..c5694dd 100644 --- a/SDL3/ImGuiSDL3Platform.cs +++ b/SDL3/ImGuiSDL3Platform.cs @@ -1,7 +1,7 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using Hexa.NET.ImGui; +using ImGuiNET; using SDL3; namespace SDL3_TestingSuite.SDL3; @@ -32,7 +32,7 @@ public unsafe static class ImGuiSDL3Platform // Mouse Handling public uint MouseWindowID; public int MouseButtonsDown; - public readonly nint[] MouseCursors = new nint[(int)ImGuiMouseCursor.Count]; + public readonly nint[] MouseCursors = new nint[(int)ImGuiMouseCursor.COUNT]; public nint MouseLastCursor; public int MouseLastLeaveFrame; public bool MouseCanUseGlobalState; @@ -85,7 +85,7 @@ public unsafe static class ImGuiSDL3Platform private static readonly PlatformOpenInShellFn OpenInShellDelegate = OpenInShell; // ReSharper restore NotAccessedField.Local - public static PlatformData Data => ImGui.GetCurrentContext().Handle != null ? ImGuiUserData.Get(ImGui.GetIO().BackendPlatformUserData)! : null!; + public static PlatformData Data => ImGui.GetCurrentContext() != nint.Zero ? ImGuiUserData.Get(ImGui.GetIO().BackendPlatformUserData)! : null!; public static bool Init(nint window, nint renderer) { @@ -124,10 +124,10 @@ public unsafe static class ImGuiSDL3Platform #endif ImGuiPlatformIOPtr platformIo = ImGui.GetPlatformIO(); - platformIo.PlatformGetClipboardTextFn = (void*)Marshal.GetFunctionPointerForDelegate(GetClipboardDelegate); - platformIo.PlatformSetClipboardTextFn = (void*)Marshal.GetFunctionPointerForDelegate(SetClipboardDelegate); - platformIo.PlatformSetImeDataFn = (void*)Marshal.GetFunctionPointerForDelegate(SetImeDataDelegate); - platformIo.PlatformOpenInShellFn = (void*)Marshal.GetFunctionPointerForDelegate(OpenInShellDelegate); + platformIo.Platform_GetClipboardTextFn = Marshal.GetFunctionPointerForDelegate(GetClipboardDelegate); + platformIo.Platform_SetClipboardTextFn = Marshal.GetFunctionPointerForDelegate(SetClipboardDelegate); + platformIo.Platform_SetImeDataFn = Marshal.GetFunctionPointerForDelegate(SetImeDataDelegate); + platformIo.Platform_OpenInShellFn = Marshal.GetFunctionPointerForDelegate(OpenInShellDelegate); UpdateMonitors(); @@ -137,13 +137,13 @@ public unsafe static class ImGuiSDL3Platform data.MouseCursors[(int)ImGuiMouseCursor.Arrow] = SDL.CreateSystemCursor(SDL.SystemCursor.Default); data.MouseCursors[(int)ImGuiMouseCursor.TextInput] = SDL.CreateSystemCursor(SDL.SystemCursor.Text); data.MouseCursors[(int)ImGuiMouseCursor.ResizeAll] = SDL.CreateSystemCursor(SDL.SystemCursor.Move); - data.MouseCursors[(int)ImGuiMouseCursor.ResizeNs] = SDL.CreateSystemCursor(SDL.SystemCursor.NSResize); - data.MouseCursors[(int)ImGuiMouseCursor.ResizeEw] = SDL.CreateSystemCursor(SDL.SystemCursor.EWResize); - data.MouseCursors[(int)ImGuiMouseCursor.ResizeNesw] = SDL.CreateSystemCursor(SDL.SystemCursor.NESWResize); - data.MouseCursors[(int)ImGuiMouseCursor.ResizeNwse] = SDL.CreateSystemCursor(SDL.SystemCursor.NWSEResize); + data.MouseCursors[(int)ImGuiMouseCursor.ResizeNS] = SDL.CreateSystemCursor(SDL.SystemCursor.NSResize); + data.MouseCursors[(int)ImGuiMouseCursor.ResizeEW] = SDL.CreateSystemCursor(SDL.SystemCursor.EWResize); + data.MouseCursors[(int)ImGuiMouseCursor.ResizeNESW] = SDL.CreateSystemCursor(SDL.SystemCursor.NESWResize); + data.MouseCursors[(int)ImGuiMouseCursor.ResizeNWSE] = SDL.CreateSystemCursor(SDL.SystemCursor.NWSEResize); data.MouseCursors[(int)ImGuiMouseCursor.Hand] = SDL.CreateSystemCursor(SDL.SystemCursor.Pointer); - data.MouseCursors[(int)ImGuiMouseCursor.Wait] = SDL.CreateSystemCursor(SDL.SystemCursor.Wait); - data.MouseCursors[(int)ImGuiMouseCursor.Progress] = SDL.CreateSystemCursor(SDL.SystemCursor.Progress); + // data.MouseCursors[(int)ImGuiMouseCursor.Wait] = SDL.CreateSystemCursor(SDL.SystemCursor.Wait); + // data.MouseCursors[(int)ImGuiMouseCursor.Progress] = SDL.CreateSystemCursor(SDL.SystemCursor.Progress); data.MouseCursors[(int)ImGuiMouseCursor.NotAllowed] = SDL.CreateSystemCursor(SDL.SystemCursor.NotAllowed); SetupPlatformHandles(ImGui.GetMainViewport(), window); @@ -266,7 +266,7 @@ public unsafe static class ImGuiSDL3Platform if (GetViewportForWindowId(e.Text.WindowID) == null) return false; - ImGui.GetIO().AddInputCharactersUTF8((byte*)e.Text.Text); + ImGuiNative.ImGuiIO_AddInputCharactersUTF8(io, (byte*)e.Text.Text); return true; case SDL.EventType.KeyDown: case SDL.EventType.KeyUp: @@ -479,32 +479,51 @@ public unsafe static class ImGuiSDL3Platform UpdateGamepadAnalog(data, io, ImGuiKey.GamepadRStickDown, SDL.GamepadAxis.RightY, thumbDeadZone, 32767); } - public static void UpdateMonitors() + public static unsafe void UpdateMonitors() { PlatformData bd = Data; + ImGuiPlatformIOPtr platformio = ImGui.GetPlatformIO(); - platformio.Monitors.Resize(0); - bd.WantUpdateMonitors = false; + + if (platformio.NativePtr == null) + return; var displays = SDL.GetDisplays(out int displayCount); - for (int n = 0; n < displayCount; n++) + + if (displays == null || displayCount <= 0) + return; + + if (platformio.Monitors.Data == IntPtr.Zero) + return; + + bd.WantUpdateMonitors = false; + + ImGuiPlatformMonitor* dst = (ImGuiPlatformMonitor*)platformio.Monitors.Data; + + for (int i = 0; i < displayCount; i++) { - // Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime. - var displayID = displays[n]; + var displayID = displays[i]; + ImGuiPlatformMonitor monitor = new ImGuiPlatformMonitor(); + SDL.GetDisplayBounds(displayID, out SDL.Rect r); monitor.MainPos = monitor.WorkPos = new Vector2(r.X, r.Y); monitor.MainSize = monitor.WorkSize = new Vector2(r.W, r.H); + if (SDL.GetDisplayUsableBounds(displayID, out SDL.Rect r2) && r2.W > 0 && r2.H > 0) { monitor.WorkPos = new Vector2(r2.X, r2.Y); monitor.WorkSize = new Vector2(r2.W, r2.H); } - monitor.DpiScale = SDL.GetDisplayContentScale(displayID); // See https://wiki.libsdl.org/SDL3/README-highdpi for details. - monitor.PlatformHandle = (void*)n; + + monitor.DpiScale = SDL.GetDisplayContentScale(displayID); + if (monitor.DpiScale <= 0.0f) - continue; // Some accessibility applications are declaring virtual monitors with a DPI of 0, see #7902. - platformio.Monitors.PushBack(monitor); + continue; + + monitor.PlatformHandle = (void*)i; + + dst[i] = monitor; } } @@ -571,16 +590,16 @@ public unsafe static class ImGuiSDL3Platform SDL.Keycode.RAlt => ImGuiKey.RightAlt, SDL.Keycode.RGUI => ImGuiKey.RightSuper, SDL.Keycode.Application => ImGuiKey.Menu, - SDL.Keycode.Alpha0 => ImGuiKey.Key0, - SDL.Keycode.Alpha1 => ImGuiKey.Key1, - SDL.Keycode.Alpha2 => ImGuiKey.Key2, - SDL.Keycode.Alpha3 => ImGuiKey.Key3, - SDL.Keycode.Alpha4 => ImGuiKey.Key4, - SDL.Keycode.Alpha5 => ImGuiKey.Key5, - SDL.Keycode.Alpha6 => ImGuiKey.Key6, - SDL.Keycode.Alpha7 => ImGuiKey.Key7, - SDL.Keycode.Alpha8 => ImGuiKey.Key8, - SDL.Keycode.Alpha9 => ImGuiKey.Key9, + SDL.Keycode.Alpha0 => ImGuiKey._0, + SDL.Keycode.Alpha1 => ImGuiKey._1, + SDL.Keycode.Alpha2 => ImGuiKey._2, + SDL.Keycode.Alpha3 => ImGuiKey._3, + SDL.Keycode.Alpha4 => ImGuiKey._4, + SDL.Keycode.Alpha5 => ImGuiKey._5, + SDL.Keycode.Alpha6 => ImGuiKey._6, + SDL.Keycode.Alpha7 => ImGuiKey._7, + SDL.Keycode.Alpha8 => ImGuiKey._8, + SDL.Keycode.Alpha9 => ImGuiKey._9, SDL.Keycode.A => ImGuiKey.A, SDL.Keycode.B => ImGuiKey.B, SDL.Keycode.C => ImGuiKey.C, @@ -723,7 +742,6 @@ public unsafe static class ImGuiSDL3Platform private static void CreateWindow(ImGuiViewportPtr viewport) { - Program.Logger.Log(null); PlatformData bd = Data; ViewPortData vd = new ViewPortData(); @@ -758,7 +776,7 @@ public unsafe static class ImGuiSDL3Platform vd.Window = SDL.CreateWindow("Untitled", (int)viewport.Size.X, (int)viewport.Size.Y, flags); ImGuiViewportPtr? parentViewport = viewport.ParentViewportId != 0 ? ImGui.FindViewportByID(viewport.ParentViewportId) : null; - if (parentViewport != null && parentViewport.Value.Handle != null) + if (parentViewport != null) { vd.ParentWindow = GetSDLWindowFromViewport(parentViewport.Value); if (vd.ParentWindow != nint.Zero) @@ -783,7 +801,6 @@ public unsafe static class ImGuiSDL3Platform private static void DestroyWindow(ImGuiViewportPtr viewport) { - Program.Logger.Log(null); ViewPortData? vd = ImGuiUserData.Get(viewport.PlatformUserData); if (vd != null) @@ -796,16 +813,14 @@ public unsafe static class ImGuiSDL3Platform ImGuiUserData.Free(viewport.PlatformUserData); - viewport.PlatformUserData = null; - viewport.PlatformHandle = null; - viewport.PlatformHandleRaw = null; - - Program.Logger.Log(null); + viewport.PlatformUserData = nint.Zero; + viewport.PlatformHandle = nint.Zero; + viewport.PlatformHandleRaw = nint.Zero; + } private static void ShowWindow(ImGuiViewportPtr viewport) { - Program.Logger.Log(null); ViewPortData vd = ImGuiUserData.Get(viewport.PlatformUserData)!; string? oldHint = SDL.GetHint(SDL.Hints.WindowActivateWhenShown); @@ -815,12 +830,10 @@ public unsafe static class ImGuiSDL3Platform SDL.ShowWindow(vd.Window); SDL.SetHint(SDL.Hints.WindowActivateWhenShown, oldHint); - Program.Logger.Log(null); } private static void UpdateWindow(ImGuiViewportPtr viewport) { - Program.Logger.Log(null); ViewPortData vd = ImGuiUserData.Get(viewport.PlatformUserData)!; if ((viewport.Flags & ImGuiViewportFlags.TopMost) != 0) @@ -831,7 +844,6 @@ public unsafe static class ImGuiSDL3Platform { SDL.SetWindowAlwaysOnTop(vd.Window, false); } - Program.Logger.Log(null); } private static Vector2 GetWindowPos(ImGuiViewportPtr viewport) @@ -850,7 +862,6 @@ public unsafe static class ImGuiSDL3Platform ViewPortData vd = ImGuiUserData.Get(viewport.PlatformUserData)!; SDL.SetWindowPosition(vd.Window, (int)pos.X, (int)pos.Y); - Program.Logger.Log(null); } private static Vector2 GetWindowSize(ImGuiViewportPtr viewport) @@ -868,7 +879,6 @@ public unsafe static class ImGuiSDL3Platform ViewPortData vd = ImGuiUserData.Get(viewport.PlatformUserData)!; SDL.SetWindowSize(vd.Window, (int)size.X, (int)size.Y); - Program.Logger.Log(null); } private static Vector2 GetWindowFramebufferScale(ImGuiViewportPtr viewport) @@ -886,7 +896,6 @@ public unsafe static class ImGuiSDL3Platform ViewPortData vd = ImGuiUserData.Get(viewport.PlatformUserData)!; SDL.SetWindowTitle(vd.Window, title); - Program.Logger.Log(null); } private static void SetWindowAlpha(ImGuiViewportPtr viewport, float alpha) @@ -894,7 +903,6 @@ public unsafe static class ImGuiSDL3Platform ViewPortData vd = ImGuiUserData.Get(viewport.PlatformUserData)!; SDL.SetWindowOpacity(vd.Window, alpha); - Program.Logger.Log(null); } private static void SetWindowFocus(ImGuiViewportPtr viewport) @@ -902,7 +910,6 @@ public unsafe static class ImGuiSDL3Platform ViewPortData vd = ImGuiUserData.Get(viewport.PlatformUserData)!; SDL.RaiseWindow(vd.Window); - Program.Logger.Log(null); } private static bool GetWindowFocus(ImGuiViewportPtr viewport) @@ -924,13 +931,11 @@ public unsafe static class ImGuiSDL3Platform private static void RenderWindow(ImGuiViewportPtr viewport) { // Renderer-backed viewport rendering is handled by ImGuiSDL3Renderer. - Program.Logger.Log(null); } private static void SwapBuffers(ImGuiViewportPtr viewport) { // Renderer-backed viewport presentation is handled by ImGuiSDL3Renderer. - Program.Logger.Log(null); } @@ -1016,24 +1021,25 @@ public unsafe static class ImGuiSDL3Platform private static void InitMultiViewportSupport(nint window) { - Program.Logger.Log(null); ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO(); - platformIO.PlatformCreateWindow = (void*)Marshal.GetFunctionPointerForDelegate(CreateWindowDelegate); - platformIO.PlatformDestroyWindow = (void*)Marshal.GetFunctionPointerForDelegate(DestroyWindowDelegate); - platformIO.PlatformShowWindow = (void*)Marshal.GetFunctionPointerForDelegate(ShowWindowDelegate); - platformIO.PlatformSetWindowPos = (void*)Marshal.GetFunctionPointerForDelegate(SetWindowPosDelegate); - platformIO.PlatformGetWindowPos = (void*)Marshal.GetFunctionPointerForDelegate(GetWindowPosDelegate); - platformIO.PlatformSetWindowSize = (void*)Marshal.GetFunctionPointerForDelegate(SetWindowSizeDelegate); - platformIO.PlatformGetWindowSize = (void*)Marshal.GetFunctionPointerForDelegate(GetWindowSizeDelegate); - platformIO.PlatformSetWindowFocus = (void*)Marshal.GetFunctionPointerForDelegate(SetWindowFocusDelegate); - platformIO.PlatformGetWindowFocus = (void*)Marshal.GetFunctionPointerForDelegate(GetWindowFocusDelegate); - platformIO.PlatformGetWindowMinimized = (void*)Marshal.GetFunctionPointerForDelegate(GetWindowMinimizedDelegate); - platformIO.PlatformSetWindowTitle = (void*)Marshal.GetFunctionPointerForDelegate(SetWindowTitleDelegate); - platformIO.PlatformSetWindowAlpha = (void*)Marshal.GetFunctionPointerForDelegate(SetWindowAlphaDelegate); - platformIO.PlatformUpdateWindow = (void*)Marshal.GetFunctionPointerForDelegate(UpdateWindowDelegate); - platformIO.PlatformGetWindowFramebufferScale = (void*)Marshal.GetFunctionPointerForDelegate(GetWindowFramebufferScaleDelegate); + platformIO.Platform_CreateWindow = Marshal.GetFunctionPointerForDelegate(CreateWindowDelegate); + platformIO.Platform_DestroyWindow = Marshal.GetFunctionPointerForDelegate(DestroyWindowDelegate); + platformIO.Platform_ShowWindow = Marshal.GetFunctionPointerForDelegate(ShowWindowDelegate); + platformIO.Platform_SetWindowPos = Marshal.GetFunctionPointerForDelegate(SetWindowPosDelegate); + platformIO.Platform_GetWindowPos = Marshal.GetFunctionPointerForDelegate(GetWindowPosDelegate); + platformIO.Platform_SetWindowSize = Marshal.GetFunctionPointerForDelegate(SetWindowSizeDelegate); + platformIO.Platform_GetWindowSize = Marshal.GetFunctionPointerForDelegate(GetWindowSizeDelegate); + platformIO.Platform_SetWindowFocus = Marshal.GetFunctionPointerForDelegate(SetWindowFocusDelegate); + platformIO.Platform_GetWindowFocus = Marshal.GetFunctionPointerForDelegate(GetWindowFocusDelegate); + platformIO.Platform_GetWindowMinimized = Marshal.GetFunctionPointerForDelegate(GetWindowMinimizedDelegate); + platformIO.Platform_SetWindowTitle = Marshal.GetFunctionPointerForDelegate(SetWindowTitleDelegate); + platformIO.Platform_RenderWindow = Marshal.GetFunctionPointerForDelegate(RenderWindowDelegate); + platformIO.Platform_SwapBuffers = Marshal.GetFunctionPointerForDelegate(SwapBuffersDelegate); + platformIO.Platform_SetWindowAlpha = Marshal.GetFunctionPointerForDelegate(SetWindowAlphaDelegate); + platformIO.Platform_UpdateWindow = Marshal.GetFunctionPointerForDelegate(UpdateWindowDelegate); + // platformIO.Platform_GetWindowFramebufferScale = Marshal.GetFunctionPointerForDelegate(GetWindowFramebufferScaleDelegate); ImGuiViewportPtr mainViewport = ImGui.GetMainViewport(); @@ -1047,9 +1053,8 @@ public unsafe static class ImGuiSDL3Platform }; mainViewport.PlatformUserData = ImGuiUserData.Store(vd); - mainViewport.PlatformHandle = (void*)(nint)SDL.GetWindowID(window); - - Program.Logger.Log(null); + mainViewport.PlatformHandle = (nint)SDL.GetWindowID(window); + #if WINDOWS mainViewport.PlatformHandleRaw = SDL.GetPointerProperty( @@ -1062,18 +1067,18 @@ public unsafe static class ImGuiSDL3Platform public static ImGuiViewportPtr? GetViewportForWindowId(uint id) { - return ImGui.FindViewportByPlatformHandle((void*)(nint)id); + return ImGui.FindViewportByPlatformHandle((nint)id); } private static nint GetSDLWindowFromViewport(ImGuiViewportPtr viewport) { - return SDL.GetWindowFromID((uint)(nint)viewport.PlatformHandle); + return SDL.GetWindowFromID((uint)viewport.PlatformHandle); } private static void SetupPlatformHandles(ImGuiViewportPtr viewport, nint window) { - viewport.PlatformHandle = (void*)(nint)SDL.GetWindowID(window); - viewport.PlatformHandleRaw = (void*)nint.Zero; + viewport.PlatformHandle = (nint)SDL.GetWindowID(window); + viewport.PlatformHandleRaw = nint.Zero; #if _WIN32 && !__WINTR__ SDL.GetPointerProperty(SDL.GetWindowProperties(window), SDL.Props.WindowWin32HWNDPointer, 0); #elif __APPLE__ && SDL_VIDEO_DRIVER_COCOA @@ -1096,12 +1101,12 @@ public unsafe static class ImGuiSDL3Platform ImGuiIOPtr io = ImGui.GetIO(); ImGuiPlatformIOPtr platformIo = ImGui.GetPlatformIO(); - platformIo.PlatformGetClipboardTextFn = null; - platformIo.PlatformSetClipboardTextFn = null; - platformIo.PlatformSetImeDataFn = null; - platformIo.PlatformOpenInShellFn = null; + platformIo.Platform_GetClipboardTextFn = nint.Zero; + platformIo.Platform_SetClipboardTextFn = nint.Zero; + platformIo.Platform_SetImeDataFn = nint.Zero; + platformIo.Platform_OpenInShellFn = nint.Zero; ImGuiUserData.Free(io.BackendPlatformUserData); - io.BackendPlatformUserData = null; + io.BackendPlatformUserData = nint.Zero; } } @@ -1119,32 +1124,32 @@ public enum MouseCaptureMode Disabled } -public unsafe static class ImGuiUserData where T : class +public static class ImGuiUserData where T : class { - public static void* Store(T value) + public static nint Store(T value) { if (value == null) - return null; + return nint.Zero; GCHandle handle = GCHandle.Alloc(value, GCHandleType.Normal); - return (void*)GCHandle.ToIntPtr(handle); + return GCHandle.ToIntPtr(handle); } - public static T Get(void* ptr) + public static T Get(nint ptr) { - if (ptr == null) - return null; + if (ptr == nint.Zero) + return null!; - GCHandle handle = GCHandle.FromIntPtr((nint)ptr); - return (T)handle.Target; + GCHandle handle = GCHandle.FromIntPtr(ptr); + return (T)handle.Target!; } - public static void Free(void* ptr) + public static void Free(nint ptr) { - if (ptr == null) + if (ptr == nint.Zero) return; - GCHandle handle = GCHandle.FromIntPtr((nint)ptr); + GCHandle handle = GCHandle.FromIntPtr(ptr); if (handle.IsAllocated) handle.Free(); diff --git a/SDL3/ImGuiSDL3Renderer.cs b/SDL3/ImGuiSDL3Renderer.cs index b03dd0d..beeae22 100644 --- a/SDL3/ImGuiSDL3Renderer.cs +++ b/SDL3/ImGuiSDL3Renderer.cs @@ -1,6 +1,6 @@ using System.Numerics; using System.Runtime.InteropServices; -using Hexa.NET.ImGui; +using ImGuiNET; using SDL3; namespace SDL3_TestingSuite.SDL3; @@ -11,12 +11,6 @@ namespace SDL3_TestingSuite.SDL3; /// public unsafe static class ImGuiSDL3Renderer { - private sealed class TextureState - { - public ImTextureDataPtr Source; - public readonly Dictionary RendererTextures = new(); - } - public class RendererData { public nint Renderer; // Main viewport's renderer @@ -59,7 +53,9 @@ public unsafe static class ImGuiSDL3Renderer private static readonly RendererSwapBuffersFn RendererSwapBuffersDelegate = RendererSwapBuffers; - public static RendererData Data => ImGui.GetCurrentContext().Handle != null ? ImGuiUserData.Get(ImGui.GetIO().BackendRendererUserData)! : null!; + public static RendererData Data => ImGui.GetCurrentContext() != nint.Zero ? ImGuiUserData.Get(ImGui.GetIO().BackendRendererUserData)! : null!; + + private static nint _fontTexture = nint.Zero; public static bool Init(nint renderer) { @@ -67,19 +63,17 @@ public unsafe static class ImGuiSDL3Renderer RendererData bd = new RendererData(); io.BackendRendererUserData = ImGuiUserData.Store(bd); - io.BackendRendererName = (byte*)Marshal.StringToHGlobalAnsi("NepImGuiSDL3Renderer"); io.BackendFlags |= ImGuiBackendFlags.RendererHasVtxOffset; // We can honor the ImDrawCmd.VtxOffset field, allowing for large meshes. - io.BackendFlags |= ImGuiBackendFlags.RendererHasTextures; // We can honor ImGuiPlatformIO.Textures[] requests during render. io.BackendFlags |= ImGuiBackendFlags.RendererHasViewports; bd.Renderer = renderer; ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO(); - platformIO.RendererCreateWindow = (void*)Marshal.GetFunctionPointerForDelegate(RendererCreateWindowDelegate); - platformIO.RendererDestroyWindow = (void*)Marshal.GetFunctionPointerForDelegate(RendererDestroyWindowDelegate); - platformIO.RendererSetWindowSize = (void*)Marshal.GetFunctionPointerForDelegate(RendererSetWindowSizeDelegate); - platformIO.RendererRenderWindow = (void*)Marshal.GetFunctionPointerForDelegate(RendererRenderWindowDelegate); - platformIO.RendererSwapBuffers = (void*)Marshal.GetFunctionPointerForDelegate(RendererSwapBuffersDelegate); + platformIO.Renderer_CreateWindow = Marshal.GetFunctionPointerForDelegate(RendererCreateWindowDelegate); + platformIO.Renderer_DestroyWindow = Marshal.GetFunctionPointerForDelegate(RendererDestroyWindowDelegate); + platformIO.Renderer_SetWindowSize = Marshal.GetFunctionPointerForDelegate(RendererSetWindowSizeDelegate); + platformIO.Renderer_RenderWindow = Marshal.GetFunctionPointerForDelegate(RendererRenderWindowDelegate); + platformIO.Renderer_SwapBuffers = Marshal.GetFunctionPointerForDelegate(RendererSwapBuffersDelegate); return true; } @@ -90,21 +84,24 @@ public unsafe static class ImGuiSDL3Renderer var platformIO = ImGui.GetPlatformIO(); DestroyDeviceObjects(); - - io.BackendRendererName = null; - io.BackendRendererUserData = null; - io.BackendFlags &= ~(ImGuiBackendFlags.RendererHasVtxOffset | ImGuiBackendFlags.RendererHasTextures); - platformIO.RendererTextureMaxWidth = 0; - platformIO.RendererTextureMaxHeight = 0; - platformIO.RendererRenderState = null; - platformIO.RendererCreateWindow = null; - platformIO.RendererDestroyWindow = null; - platformIO.RendererSetWindowSize = null; - platformIO.RendererRenderWindow = null; - platformIO.RendererSwapBuffers = null; + + io.BackendRendererUserData = nint.Zero; + io.BackendFlags &= ~ImGuiBackendFlags.RendererHasVtxOffset; + platformIO.Renderer_RenderState = nint.Zero; + platformIO.Renderer_CreateWindow = nint.Zero; + platformIO.Renderer_DestroyWindow = nint.Zero; + platformIO.Renderer_SetWindowSize = nint.Zero; + platformIO.Renderer_RenderWindow = nint.Zero; + platformIO.Renderer_SwapBuffers = nint.Zero; } - public static void NewFrame() { } + public static void NewFrame() + { + if (_fontTexture == nint.Zero) + { + CreateDeviceObjects(); + } + } private static void RendererCreateWindow(ImGuiViewportPtr viewport) { @@ -171,7 +168,7 @@ public unsafe static class ImGuiSDL3Renderer public static void RenderDrawData(ImDrawDataPtr drawData, nint renderer) { // Skip if no data to render - if (drawData.Handle == null || drawData.CmdListsCount == 0) + if (drawData.NativePtr == null || drawData.CmdListsCount == 0) return; SDL.GetRenderScale(renderer, out float renderScaleX, out float renderScaleY); @@ -184,12 +181,6 @@ public unsafe static class ImGuiSDL3Renderer if (fbWidth <= 0 || fbHeight <= 0) return; - for (int i = 0; i < drawData.Textures.Size; i++) - { - var texture = drawData.Textures[i]; - UpdateTexture(texture, renderer); - } - // Backup SDL renderer state BackupSDLRendererState old = new BackupSDLRendererState { @@ -207,7 +198,7 @@ public unsafe static class ImGuiSDL3Renderer // Set render state in platform IO ImGuiPlatformIOPtr platformIo = ImGui.GetPlatformIO(); - platformIo.RendererRenderState = (void*)renderer; + platformIo.Renderer_RenderState = renderer; Vector2 clipOffset = drawData.DisplayPos; @@ -218,157 +209,54 @@ public unsafe static class ImGuiSDL3Renderer for (int cmdIndex = 0; cmdIndex < cmdList.CmdBuffer.Size; cmdIndex++) { - ImDrawCmd cmd = cmdList.CmdBuffer[cmdIndex]; + ImDrawCmdPtr cmd = cmdList.CmdBuffer[cmdIndex]; - if (cmd.UserCallback != null) + if (cmd.UserCallback != nint.Zero) { continue; // User callback not implemented } - else + + // Apply clipping rectangle + Vector4 clipRect = cmd.ClipRect; + Vector2 clipMin = new Vector2((clipRect.X - clipOffset.X) * renderScale.X, (clipRect.Y - clipOffset.Y) * renderScale.Y); + Vector2 clipMax = new Vector2((clipRect.Z - clipOffset.X) * renderScale.X, (clipRect.W - clipOffset.Y) * renderScale.Y); + + clipMin.X = Math.Max(0, clipMin.X); + clipMin.Y = Math.Max(0, clipMin.Y); + clipMax.X = Math.Min(fbWidth, clipMax.X); + clipMax.Y = Math.Min(fbHeight, clipMax.Y); + if (clipMax.X <= clipMin.X || clipMax.Y <= clipMin.Y) + continue; + + SDL.Rect r = new SDL.Rect { - // Apply clipping rectangle - Vector4 clipRect = cmd.ClipRect; - Vector2 clipMin = new Vector2((clipRect.X - clipOffset.X) * renderScale.X, (clipRect.Y - clipOffset.Y) * renderScale.Y); - Vector2 clipMax = new Vector2((clipRect.Z - clipOffset.X) * renderScale.X, (clipRect.W - clipOffset.Y) * renderScale.Y); + X = (int)clipMin.X, + Y = (int)clipMin.Y, + W = (int)(clipMax.X - clipMin.X), + H = (int)(clipMax.Y - clipMin.Y) + }; + SDL.SetRenderClipRect(renderer, r); - clipMin.X = Math.Max(0, clipMin.X); - clipMin.Y = Math.Max(0, clipMin.Y); - clipMax.X = Math.Min(fbWidth, clipMax.X); - clipMax.Y = Math.Min(fbHeight, clipMax.Y); - if (clipMax.X <= clipMin.X || clipMax.Y <= clipMin.Y) - continue; + // Get texture + nint texId = cmd.GetTexID(); - SDL.Rect r = new SDL.Rect - { - X = (int)clipMin.X, - Y = (int)clipMin.Y, - W = (int)(clipMax.X - clipMin.X), - H = (int)(clipMax.Y - clipMin.Y) - }; - SDL.SetRenderClipRect(renderer, r); - - // Get texture - nint texId = ResolveTextureId(cmd.GetTexID(), renderer); - - // Convert ImGui vertices to SDL vertices - if (!RenderDrawCommand(cmdList, cmd, renderer, texId, renderScale)) - { - Console.WriteLine($"Failed to render ImGui draw command: {SDL.GetError()}"); - } + // Convert ImGui vertices to SDL vertices + if (!RenderDrawCommand(cmdList, cmd, renderer, texId, renderScale)) + { + Console.WriteLine($"Failed to render ImGui draw command: {SDL.GetError()}"); } } } // Reset render state - platformIo.RendererRenderState = null; + platformIo.Renderer_RenderState = nint.Zero; // Restore renderer state SDL.SetRenderViewport(renderer, old.ViewportEnabled ? old.Viewport : new SDL.Rect()); SDL.SetRenderClipRect(renderer, old.ClipEnabled ? old.ClipRect : new SDL.Rect()); } - private static nint ResolveTextureId(ImTextureID texId, nint renderer) - { - if (texId == ImTextureID.Null) - return nint.Zero; - - TextureState? state = ImGuiUserData.Get((void*)(nint)texId); - if (state == null) - return (nint)texId; - - if (!state.RendererTextures.TryGetValue(renderer, out nint rendererTexture) || rendererTexture == nint.Zero) - { - rendererTexture = CreateRendererTexture(state, renderer); - state.RendererTextures[renderer] = rendererTexture; - } - - return rendererTexture; - } - - private static nint CreateRendererTexture(TextureState state, nint renderer) - { - ImTextureDataPtr tex = state.Source; - // We keep ARGB8888 here because this project already relies on that upload path. - nint sdlTexture = SDL.CreateTexture(renderer, SDL.PixelFormat.ARGB8888, SDL.TextureAccess.Static, tex.Width, tex.Height); - if (sdlTexture == nint.Zero) - return nint.Zero; - - SDL.UpdateTexture(sdlTexture, nint.Zero, (nint)tex.GetPixels(), tex.GetPitch()); - SDL.SetTextureBlendMode(sdlTexture, SDL.BlendMode.Blend); - SDL.SetTextureScaleMode(sdlTexture, SDL.ScaleMode.Linear); - return sdlTexture; - } - - private static void UploadRendererTexture(ImTextureDataPtr tex, nint renderer, nint sdlTexture) - { - if (tex.Status == ImTextureStatus.WantUpdates) - { - for (int i = 0; i < tex.Updates.Size; i++) - { - var r = tex.Updates[i]; - SDL.Rect rect = new SDL.Rect - { - X = r.X, - Y = r.Y, - W = r.W, - H = r.H - }; - SDL.UpdateTexture(sdlTexture, rect, (nint)tex.GetPixelsAt(r.X, r.Y), tex.GetPitch()); - } - } - else - { - SDL.UpdateTexture(sdlTexture, nint.Zero, (nint)tex.GetPixels(), tex.GetPitch()); - } - } - - private static void UpdateTexture(ImTextureDataPtr tex, nint renderer) - { - TextureState? state = null; - if ((nint)tex.BackendUserData != nint.Zero) - state = ImGuiUserData.Get(tex.BackendUserData); - - if (state == null) - { - state = new TextureState(); - tex.BackendUserData = ImGuiUserData.Store(state); - } - - state.Source = tex; - tex.SetTexID((nint)tex.BackendUserData); - - if (tex.Status == ImTextureStatus.WantDestroy) - { - foreach (nint rendererTexture in state.RendererTextures.Values) - { - if (rendererTexture != nint.Zero) - SDL.DestroyTexture(rendererTexture); - } - - state.RendererTextures.Clear(); - ImGuiUserData.Free(tex.BackendUserData); - tex.BackendUserData = (void*)nint.Zero; - tex.SetTexID(ImTextureID.Null); - tex.SetStatus(ImTextureStatus.Destroyed); - return; - } - - bool hasRendererTexture = state.RendererTextures.TryGetValue(renderer, out nint sdlTexture) && sdlTexture != nint.Zero; - if (!hasRendererTexture) - { - sdlTexture = CreateRendererTexture(state, renderer); - state.RendererTextures[renderer] = sdlTexture; - } - - if (sdlTexture != nint.Zero && (tex.Status == ImTextureStatus.WantCreate || tex.Status == ImTextureStatus.WantUpdates || !hasRendererTexture)) - { - UploadRendererTexture(tex, renderer, sdlTexture); - tex.SetStatus(ImTextureStatus.Ok); - } - - } - - private static bool RenderDrawCommand(ImDrawListPtr drawList, ImDrawCmd cmd, nint renderer, nint texId, Vector2 scale) + private static bool RenderDrawCommand(ImDrawListPtr drawList, ImDrawCmdPtr cmd, nint renderer, nint texId, Vector2 scale) { uint indexOffset = cmd.IdxOffset; uint vertexOffset = cmd.VtxOffset; @@ -382,9 +270,9 @@ public unsafe static class ImGuiSDL3Renderer ushort idx = drawList.IdxBuffer[(int)indexOffset + i]; int vertIdx = (int)(vertexOffset + idx); - ImDrawVert srcVert = drawList.VtxBuffer[vertIdx]; + ImDrawVertPtr srcVert = drawList.VtxBuffer[vertIdx]; - uint col = srcVert.Col; + uint col = srcVert.col; byte r = (byte)((col >> 0) & 0xFF); byte g = (byte)((col >> 8) & 0xFF); @@ -395,8 +283,8 @@ public unsafe static class ImGuiSDL3Renderer { Position = new SDL.FPoint() { - X = srcVert.Pos.X * scale.X, - Y = srcVert.Pos.Y * scale.Y + X = srcVert.pos.X * scale.X, + Y = srcVert.pos.Y * scale.Y }, Color = new SDL.FColor() { @@ -407,8 +295,8 @@ public unsafe static class ImGuiSDL3Renderer }, TexCoord = new SDL.FPoint() { - X = srcVert.Uv.X, - Y = srcVert.Uv.Y + X = srcVert.uv.X, + Y = srcVert.uv.Y } }; @@ -418,16 +306,65 @@ public unsafe static class ImGuiSDL3Renderer return SDL.RenderGeometry(renderer, texId, vertices, vertices.Length, indices, indices.Length); } - public static void CreateDeviceObjects() { } - - public static void DestroyDeviceObjects() + public static void CreateDeviceObjects() { - var texures = ImGui.GetPlatformIO().Textures; - for (int i = 0; i < texures.Size; i++) + ImGuiIOPtr io = ImGui.GetIO(); + var data = Data; + + io.Fonts.AddFontDefault(); + + // TODO: Load custom fonts from "Fonts" directory + //string fontsPath = Path.Combine(Plugin.AssemblyDirectory, "Fonts"); + //if (Path.Exists(fontsPath)) + //{ + // string[] fonts = Directory.GetFiles(fontsPath, "*.ttf"); + // if (fonts.Length > 0) + // { + // foreach (string font in fonts) + // { + // io.Fonts.AddFontFromFileTTF(font, 20f); + // } + // } + //} + + // Build texture atlas + io.Fonts.GetTexDataAsRGBA32(out byte* pixels, out int width, out int height); + + // Create surface from pixel data + nint surface = SDL.CreateSurfaceFrom(width, height, SDL.PixelFormat.RGBA8888, (nint)pixels, width * 4); + if (surface == nint.Zero) { - var texture = texures[i]; - texture.Status = ImTextureStatus.WantDestroy; - UpdateTexture(texture, nint.Zero); + SDL.LogError(SDL.LogCategory.Application, $"Failed to create font surface: {SDL.GetError()}"); + return; } + + // Create texture + _fontTexture = SDL.CreateTextureFromSurface(data.Renderer, surface); + if (_fontTexture == nint.Zero) + { + SDL.LogError(SDL.LogCategory.Application, $"Failed to create font texture: {SDL.GetError()}"); + return; + } + + // Update texture directly without converting pixel format + if (!SDL.UpdateTexture(_fontTexture, nint.Zero, (nint)pixels, width * 4)) + { + SDL.LogError(SDL.LogCategory.Application, $"Failed to update font texture: {SDL.GetError()}"); + return; + } + + // Ensure proper blending for font rendering + SDL.SetTextureBlendMode(_fontTexture, SDL.BlendMode.Blend); + + // Use nearest neighbor filtering for crisp font rendering at small sizes + SDL.SetTextureScaleMode(_fontTexture, SDL.ScaleMode.Linear); + + // Store our identifier + io.Fonts.SetTexID(_fontTexture); + + SDL.DestroySurface(surface); + io.Fonts.ClearTexData(); } + + public static void DestroyDeviceObjects() { } } diff --git a/SDL3/SDL3Window.cs b/SDL3/SDL3Window.cs index 57dc562..f03ae92 100644 --- a/SDL3/SDL3Window.cs +++ b/SDL3/SDL3Window.cs @@ -2,16 +2,12 @@ using System.Diagnostics; using System.Numerics; using System.Runtime.InteropServices; -using Hexa.NET.ImGui; -using Hexa.NET.ImGui.Utilities; -using Hexa.NET.ImGuizmo; -using Hexa.NET.ImPlot; -using Hexa.NET.ImPlot3D; +using ImGuiNET; using SDL3; namespace SDL3_TestingSuite.SDL3; -public sealed unsafe class SDL3Window : IDisposable +public sealed class SDL3Window : IDisposable { public readonly nint Window; public readonly nint Renderer; @@ -24,7 +20,7 @@ public sealed unsafe class SDL3Window : IDisposable private TimeSpan _time = TimeSpan.Zero; private SDL.Rect _screenClipRect; - private ImGuiContextPtr _imGuiContext; + private nint _imGuiContext; public bool Disposed => _disposed; private bool _disposed; @@ -45,56 +41,13 @@ public sealed unsafe class SDL3Window : IDisposable SDL.ShowWindow(Window); // Create ImGui context - var context = ImGui.CreateContext(); - ImPlot.CreateContext(); - ImPlot.SetImGuiContext(context); - ImGuizmo.SetImGuiContext(context); - // ImPlot3D.SetImGuiContext(context); - // ImPlot3D.CreateContext(); + _imGuiContext = ImGui.CreateContext(); ImGuiIOPtr io = ImGui.GetIO(); io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard | ImGuiConfigFlags.NavEnableGamepad | ImGuiConfigFlags.DockingEnable; // io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable; io.Fonts.Flags |= ImFontAtlasFlags.NoBakedLines; - io.Fonts.AddFontDefault(); - - try - { - string fontsPath = Path.Combine(AppContext.BaseDirectory, "Fonts"); - if (!Path.Exists(fontsPath)) Directory.CreateDirectory(fontsPath); - - _watcher = new FileSystemWatcher(fontsPath); - _watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime; - _watcher.Created += (a, b) => - { - if (!File.Exists(b.FullPath)) return; - - if (Path.GetExtension(b.FullPath) != ".ttf") return; - - ImGui.GetIO().AddFont(b.FullPath); - }; - _watcher.Deleted += (a, b) => - { - if (Path.GetExtension(b.FullPath) != ".ttf") return; - - ImGui.GetIO().RemoveFont(b.Name); - }; - - _watcher.IncludeSubdirectories = false; - _watcher.EnableRaisingEvents = true; - - string[] fonts = Directory.GetFiles(fontsPath, "*.ttf", SearchOption.AllDirectories); - foreach (string font in fonts) - { - io.AddFont(font); - } - } - catch (Exception e) - { - Console.WriteLine(e); - } - // Init platform and renderer ImGuiSDL3Platform.Init(Window, Renderer); ImGuiSDL3Renderer.Init(Renderer); @@ -200,11 +153,11 @@ public sealed unsafe class SDL3Window : IDisposable RenderCallback = null; } - if (_imGuiContext.Handle != null) + if (_imGuiContext != nint.Zero) { - ImGui.SetCurrentContext(null); + ImGui.SetCurrentContext(nint.Zero); ImGui.DestroyContext(_imGuiContext); - _imGuiContext = null; + _imGuiContext = nint.Zero; } if (Renderer != nint.Zero)