using System.Numerics; using System.Runtime.CompilerServices; using Hexa.NET.ImGui; using Hexa.NET.ImPlot; using Hexa.NET.ImPlot3D; using SDL3_TestingSuite.SDL3; using SDL3; 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(); ImGui.SetNextWindowPos(viewport.WorkPos); ImGui.SetNextWindowSize(viewport.WorkSize); ImGui.Begin("MainWindow", ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.MenuBar | ImGuiWindowFlags.NoDocking | ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoBringToFrontOnFocus); if (ImGui.BeginMenuBar()) { if (ImGui.BeginMenu("Stuff")) { if (ImGui.MenuItem("Quit")) { window.ShouldClose = true; } ImGui.EndMenu(); } 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); } }; window.Run(); } public static class Logger { public static void Log(string? str, [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0) { Console.WriteLine($"{caller}({line}): {str}"); } public static void Log(object? str, [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0) { Log(str?.ToString(), caller, line); } } }