Actual working viewports :)
This commit is contained in:
+38
-24
@@ -2,9 +2,7 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using Hexa.NET.ImGui;
|
using Hexa.NET.ImGui;
|
||||||
using Hexa.NET.ImPlot;
|
using Hexa.NET.ImPlot;
|
||||||
using Hexa.NET.ImPlot3D;
|
|
||||||
using SDL3_TestingSuite.SDL3;
|
using SDL3_TestingSuite.SDL3;
|
||||||
using SDL3;
|
|
||||||
|
|
||||||
namespace SDL3_TestingSuite;
|
namespace SDL3_TestingSuite;
|
||||||
|
|
||||||
@@ -19,15 +17,13 @@ public class Program
|
|||||||
|
|
||||||
public static void Main()
|
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);
|
||||||
SDL3Window window = new SDL3Window("SDL3 Testing Suite", 100, 100, 1280, 720, flags);
|
|
||||||
window.ClearColor.W = 0f;
|
|
||||||
window.RenderCallback = () =>
|
window.RenderCallback = () =>
|
||||||
{
|
{
|
||||||
ImGuiViewportPtr viewport = ImGui.GetMainViewport();
|
ImGuiViewportPtr viewport = ImGui.GetMainViewport();
|
||||||
ImGui.SetNextWindowPos(viewport.WorkPos);
|
ImGui.SetNextWindowPos(viewport.WorkPos);
|
||||||
ImGui.SetNextWindowSize(viewport.WorkSize);
|
ImGui.SetNextWindowSize(viewport.WorkSize);
|
||||||
|
ImGui.SetNextWindowViewport(viewport.ID);
|
||||||
ImGui.Begin("MainWindow", ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.MenuBar | ImGuiWindowFlags.NoDocking | ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoBringToFrontOnFocus);
|
ImGui.Begin("MainWindow", ImGuiWindowFlags.NoBackground | ImGuiWindowFlags.MenuBar | ImGuiWindowFlags.NoDocking | ImGuiWindowFlags.NoTitleBar | ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove | ImGuiWindowFlags.NoCollapse | ImGuiWindowFlags.NoBringToFrontOnFocus);
|
||||||
|
|
||||||
if (ImGui.BeginMenuBar())
|
if (ImGui.BeginMenuBar())
|
||||||
@@ -38,7 +34,7 @@ public class Program
|
|||||||
{
|
{
|
||||||
window.ShouldClose = true;
|
window.ShouldClose = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.EndMenu();
|
ImGui.EndMenu();
|
||||||
}
|
}
|
||||||
ImGui.Spacing();
|
ImGui.Spacing();
|
||||||
@@ -123,46 +119,47 @@ public class Program
|
|||||||
ImGui.End();
|
ImGui.End();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui.Begin("Thing");
|
||||||
float time = (float)ImGui.GetTime() * 5;
|
float time = (float)ImGui.GetTime() * 5;
|
||||||
if (ImPlot.BeginPlot("Moving Rainbow Sine Wave"))
|
if (ImPlot.BeginPlot("Moving Rainbow Sine Wave"))
|
||||||
{
|
{
|
||||||
int count = 200;
|
int count = 200;
|
||||||
|
|
||||||
float[] xs = new float[2];
|
float[] xs = new float[2];
|
||||||
float[] ys = new float[2];
|
float[] ys = new float[2];
|
||||||
|
|
||||||
for (int i = 0; i < count - 1; i++)
|
for (int i = 0; i < count - 1; i++)
|
||||||
{
|
{
|
||||||
float x0 = i * 0.1f;
|
float x0 = i * 0.1f;
|
||||||
float x1 = (i + 1) * 0.1f;
|
float x1 = (i + 1) * 0.1f;
|
||||||
|
|
||||||
float y0 = MathF.Sin(x0 * size + time);
|
float y0 = MathF.Sin(x0 * size + time);
|
||||||
float y1 = MathF.Sin(x1 * size + time);
|
float y1 = MathF.Sin(x1 * size + time);
|
||||||
|
|
||||||
xs[0] = x0;
|
xs[0] = x0;
|
||||||
xs[1] = x1;
|
xs[1] = x1;
|
||||||
|
|
||||||
ys[0] = y0;
|
ys[0] = y0;
|
||||||
ys[1] = y1;
|
ys[1] = y1;
|
||||||
|
|
||||||
float t = i / (float)count;
|
float t = i / (float)count;
|
||||||
|
|
||||||
float r = 0.5f + 1f * MathF.Sin(6.2831f * (t));
|
float r = 0.5f + 1f * MathF.Sin(6.2831f * (t));
|
||||||
float g = 0.5f + 1f * MathF.Sin(6.2831f * (t + 0.33f));
|
float g = 0.5f + 1f * MathF.Sin(6.2831f * (t + 0.33f));
|
||||||
float b = 0.5f + 1f * MathF.Sin(6.2831f * (t + 0.66f));
|
float b = 0.5f + 1f * MathF.Sin(6.2831f * (t + 0.66f));
|
||||||
|
|
||||||
|
|
||||||
ImPlot.PushStyleColor(ImPlotCol.Line, new Vector4(r, g, b, 1f));
|
ImPlot.PushStyleColor(ImPlotCol.Line, new Vector4(r, g, b, 1f));
|
||||||
ImPlot.PlotLine("##seg", ref xs[0], ref ys[0], 2);
|
ImPlot.PlotLine("##seg", ref xs[0], ref ys[0], 2);
|
||||||
ImPlot.PopStyleColor();
|
ImPlot.PopStyleColor();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImPlot.EndPlot();
|
ImPlot.EndPlot();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.SliderFloat("Sine", ref size, 1f, 120f);
|
ImGui.SliderFloat("Sine", ref size, 1f, 120f);
|
||||||
|
ImGui.End();
|
||||||
|
|
||||||
if (_demoWindowVisible)
|
if (_demoWindowVisible)
|
||||||
{
|
{
|
||||||
@@ -177,13 +174,30 @@ public class Program
|
|||||||
|
|
||||||
public static class Logger
|
public static class Logger
|
||||||
{
|
{
|
||||||
public static void Log(string? str, [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0)
|
private const int MessageWidth = 80;
|
||||||
|
private const int CallerWidth = 35;
|
||||||
|
|
||||||
|
public static void Log(object? value, [CallerFilePath] string path = "", [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0)
|
||||||
{
|
{
|
||||||
Console.WriteLine($"{caller}({line}): {str}");
|
Write(value?.ToString(), path, caller, line);
|
||||||
}
|
}
|
||||||
public static void Log(object? str, [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0)
|
|
||||||
|
public static void Log(object?[] values, [CallerFilePath] string path = "", [CallerMemberName] string caller = "", [CallerLineNumber] int line = 0)
|
||||||
{
|
{
|
||||||
Log(str?.ToString(), caller, line);
|
if (values == null)
|
||||||
|
{
|
||||||
|
Write("null", path, caller, line);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Write(string.Join(" ", values), path, caller, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Write(string? str, string path, string caller, int line)
|
||||||
|
{
|
||||||
|
string message = (str ?? string.Empty).PadRight(MessageWidth);
|
||||||
|
string method = caller.PadRight(CallerWidth);
|
||||||
|
|
||||||
|
Console.WriteLine($"{message} | {method} | {path}:{line}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -29,8 +29,8 @@ public static class FontFind
|
|||||||
FileInfo info = new FileInfo(fontPath);
|
FileInfo info = new FileInfo(fontPath);
|
||||||
if (!info.Exists || info.Length <= 0) return null;
|
if (!info.Exists || info.Length <= 0) return null;
|
||||||
|
|
||||||
FontMetrics metrics = FontFind.ReadFontMetrics(fontPath);
|
FontMetrics metrics = ReadFontMetrics(fontPath);
|
||||||
float size = FontFind.GetRecommendedPixelSize(metrics);
|
float size = GetRecommendedPixelSize(metrics);
|
||||||
|
|
||||||
ImFontConfigPtr config = ImGui.ImFontConfig();
|
ImFontConfigPtr config = ImGui.ImFontConfig();
|
||||||
config.FontLoaderFlags |= (uint)ImGuiFreeTypeLoaderFlags.LoadColor;
|
config.FontLoaderFlags |= (uint)ImGuiFreeTypeLoaderFlags.LoadColor;
|
||||||
|
|||||||
+113
-79
@@ -67,28 +67,35 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
public bool RendererOwned;
|
public bool RendererOwned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static SDL3Window Parent;
|
||||||
|
|
||||||
// ReSharper disable NotAccessedField.Local
|
// ReSharper disable NotAccessedField.Local
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
private delegate nint PlatformGetClipboardTextFn(nint ctx);
|
private delegate nint PlatformGetClipboardTextFn(nint ctx);
|
||||||
|
|
||||||
private static readonly PlatformGetClipboardTextFn GetClipboardDelegate = GetClipboardText;
|
private static readonly PlatformGetClipboardTextFn GetClipboardDelegate = GetClipboardText;
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
private delegate void PlatformSetClipboardTextFn(nint ctx, nint text);
|
private delegate void PlatformSetClipboardTextFn(nint ctx, nint text);
|
||||||
|
|
||||||
private static readonly PlatformSetClipboardTextFn SetClipboardDelegate = SetClipboardText;
|
private static readonly PlatformSetClipboardTextFn SetClipboardDelegate = SetClipboardText;
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
private delegate void PlatformSetImeDataFn(nint ctx, nint userData, nint imeData);
|
private delegate void PlatformSetImeDataFn(nint ctx, nint userData, nint imeData);
|
||||||
|
|
||||||
private static readonly PlatformSetImeDataFn SetImeDataDelegate = SetImeData;
|
private static readonly PlatformSetImeDataFn SetImeDataDelegate = SetImeData;
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
private delegate bool PlatformOpenInShellFn(nint ctx, nint url);
|
private delegate bool PlatformOpenInShellFn(nint ctx, nint url);
|
||||||
|
|
||||||
private static readonly PlatformOpenInShellFn OpenInShellDelegate = OpenInShell;
|
private static readonly PlatformOpenInShellFn OpenInShellDelegate = OpenInShell;
|
||||||
// ReSharper restore NotAccessedField.Local
|
// ReSharper restore NotAccessedField.Local
|
||||||
|
|
||||||
public static PlatformData Data => ImGui.GetCurrentContext().Handle != null ? ImGuiUserData<PlatformData>.Get(ImGui.GetIO().BackendPlatformUserData)! : null!;
|
public static PlatformData Data => ImGui.GetCurrentContext().Handle != null ? ImGuiUserData<PlatformData>.Get(ImGui.GetIO().BackendPlatformUserData)! : null!;
|
||||||
|
|
||||||
public static bool Init(nint window, nint renderer)
|
public static bool Init(nint window, nint renderer, SDL3Window parentWindow = null)
|
||||||
{
|
{
|
||||||
|
Parent = parentWindow;
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
ImGuiIOPtr io = ImGui.GetIO();
|
||||||
PlatformData data = new PlatformData
|
PlatformData data = new PlatformData
|
||||||
{
|
{
|
||||||
@@ -184,7 +191,7 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
{
|
{
|
||||||
UpdateMonitors();
|
UpdateMonitors();
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong frequency = SDL.GetPerformanceFrequency();
|
ulong frequency = SDL.GetPerformanceFrequency();
|
||||||
ulong currentTime = SDL.GetPerformanceCounter();
|
ulong currentTime = SDL.GetPerformanceCounter();
|
||||||
if (currentTime <= data.Time)
|
if (currentTime <= data.Time)
|
||||||
@@ -211,11 +218,11 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
io.BackendFlags &= ~ImGuiBackendFlags.HasMouseHoveredViewport;
|
io.BackendFlags &= ~ImGuiBackendFlags.HasMouseHoveredViewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateMouseData(data);
|
UpdateMouseData();
|
||||||
UpdateMouseCursor(data);
|
UpdateMouseCursor();
|
||||||
UpdateIme(data);
|
UpdateIme();
|
||||||
|
|
||||||
UpdateGamepads(data);
|
UpdateGamepads();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool ProcessEvent(SDL.Event e)
|
public static bool ProcessEvent(SDL.Event e)
|
||||||
@@ -230,7 +237,9 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
io.AddMouseSourceEvent(e.Motion.Which == SDL.TouchMouseID ? ImGuiMouseSource.TouchScreen : ImGuiMouseSource.Mouse);
|
io.AddMouseSourceEvent(e.Motion.Which == SDL.TouchMouseID ? ImGuiMouseSource.TouchScreen : ImGuiMouseSource.Mouse);
|
||||||
io.AddMousePosEvent(e.Motion.X, e.Motion.Y);
|
// ImGui expects desktop/global coordinates when viewports are enabled.
|
||||||
|
SDL.GetGlobalMouseState(out float mouseX, out float mouseY);
|
||||||
|
io.AddMousePosEvent(mouseX, mouseY);
|
||||||
return true;
|
return true;
|
||||||
case SDL.EventType.MouseWheel:
|
case SDL.EventType.MouseWheel:
|
||||||
if (GetViewportForWindowId(e.Wheel.WindowID) == null)
|
if (GetViewportForWindowId(e.Wheel.WindowID) == null)
|
||||||
@@ -306,36 +315,105 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateMouseData(PlatformData data)
|
// This code is rather messy because some of the functions we need for full viewport support are not available in SDL < 2.0.4.
|
||||||
{
|
private static void UpdateMouseData()
|
||||||
if (SDL.GetKeyboardFocus() == data.Window && ImGui.GetIO().WantSetMousePos)
|
|
||||||
SDL.WarpMouseInWindow(data.Window, (int)ImGui.GetIO().MousePos.X, (int)ImGui.GetIO().MousePos.Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void UpdateMouseCursor(PlatformData data)
|
|
||||||
{
|
{
|
||||||
|
var bd = Data;
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
ImGuiIOPtr io = ImGui.GetIO();
|
||||||
|
|
||||||
|
// We forward mouse input when hovered or captured (via SDL.MOUSEMOTION) or when focused (below)
|
||||||
|
// - SDL.CaptureMouse() let the OS know e.g. that our drags can extend outside of parent boundaries (we want updated position) and shouldn't trigger other operations outside.
|
||||||
|
// - Debuggers under Linux tends to leave captured mouse on break, which may be very inconvenient, so to mitigate the issue on X11 we we wait until mouse has moved to begin capture.
|
||||||
|
if (bd.MouseCaptureMode == MouseCaptureMode.Enabled)
|
||||||
|
{
|
||||||
|
SDL.CaptureMouse((bd.MouseButtonsDown != 0) ? true : false);
|
||||||
|
}
|
||||||
|
else if (bd.MouseCaptureMode == MouseCaptureMode.EnabledAfterDrag)
|
||||||
|
{
|
||||||
|
bool wantCapture = false;
|
||||||
|
for (int buttonN = 0; buttonN < (int)ImGuiMouseButton.Count && !wantCapture; buttonN++)
|
||||||
|
{
|
||||||
|
if (ImGui.IsMouseDragging((ImGuiMouseButton)buttonN, 1.0f))
|
||||||
|
wantCapture = true;
|
||||||
|
}
|
||||||
|
SDL.CaptureMouse(wantCapture ? true : false);
|
||||||
|
}
|
||||||
|
|
||||||
|
nint focusedWindow = SDL.GetKeyboardFocus();
|
||||||
|
bool isAppFocused = (focusedWindow != nint.Zero && (bd.Window == focusedWindow || GetViewportForWindowId(SDL.GetWindowID(focusedWindow)) != null));
|
||||||
|
|
||||||
|
if (isAppFocused)
|
||||||
|
{
|
||||||
|
// (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user)
|
||||||
|
if (io.WantSetMousePos)
|
||||||
|
{
|
||||||
|
if ((io.ConfigFlags.HasFlag(ImGuiConfigFlags.ViewportsEnable)))
|
||||||
|
SDL.WarpMouseGlobal((int)io.MousePos.X, (int)io.MousePos.Y);
|
||||||
|
else
|
||||||
|
SDL.WarpMouseInWindow(bd.Window, (int)io.MousePos.X, (int)io.MousePos.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// (Optional) Fallback to provide unclamped mouse position when focused but not hovered (SDL.MOUSEMOTION already provides this when hovered or captured)
|
||||||
|
// Note that SDL.GetGlobalMouseState() is in theory slow on X11, but this only runs on rather specific cases. If a problem we may provide a way to opt-out this feature.
|
||||||
|
nint hoveredWindow = SDL.GetMouseFocus();
|
||||||
|
bool isRelativeMouseMode = false /*SDL.GetRelativeMouseMode() != 0*/;
|
||||||
|
if (hoveredWindow == nint.Zero && bd.MouseCanUseGlobalState && bd.MouseButtonsDown == 0 && !isRelativeMouseMode)
|
||||||
|
{
|
||||||
|
// Single-viewport mode: mouse position in client window coordinates (io.MousePos is (0,0) when the mouse is on the upper-left corner of the app window)
|
||||||
|
// Multi-viewport mode: mouse position in OS absolute coordinates (io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor)
|
||||||
|
SDL.GetGlobalMouseState(out float mouseX, out float mouseY);
|
||||||
|
if (!io.ConfigFlags.HasFlag(ImGuiConfigFlags.ViewportsEnable))
|
||||||
|
{
|
||||||
|
SDL.GetWindowPosition(focusedWindow, out int windowX, out int windowY);
|
||||||
|
mouseX -= windowX;
|
||||||
|
mouseY -= windowY;
|
||||||
|
}
|
||||||
|
io.AddMousePosEvent(mouseX, mouseY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// (Optional) When using multiple viewports: call io.AddMouseViewportEvent() with the viewport the OS mouse cursor is hovering.
|
||||||
|
// If ImGuiBackendFlags_HasMouseHoveredViewport is not set by the backend, Dear imGui will ignore this field and infer the information using its flawed heuristic.
|
||||||
|
// - [!] SDL backend does NOT correctly ignore viewports with the _NoInputs flag.
|
||||||
|
// Some backend are not able to handle that correctly. If a backend report an hovered viewport that has the _NoInputs flag (e.g. when dragging a window
|
||||||
|
// for docking, the viewport has the _NoInputs flag in order to allow us to find the viewport under), then Dear ImGui is forced to ignore the value reported
|
||||||
|
// by the backend, and use its flawed heuristic to guess the viewport behind.
|
||||||
|
// - [X] SDL backend correctly reports this regardless of another viewport behind focused and dragged from (we need this to find a useful drag and drop target).
|
||||||
|
if ((io.BackendFlags.HasFlag(ImGuiBackendFlags.HasMouseHoveredViewport)))
|
||||||
|
{
|
||||||
|
uint mouseViewportID = 0;
|
||||||
|
var mouseViewport = GetViewportForWindowId(bd.MouseWindowID);
|
||||||
|
if (mouseViewport != null)
|
||||||
|
mouseViewportID = mouseViewport.Value.ID;
|
||||||
|
io.AddMouseViewportEvent(mouseViewportID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void UpdateMouseCursor()
|
||||||
|
{
|
||||||
|
ImGuiIOPtr io = ImGui.GetIO();
|
||||||
if ((io.ConfigFlags & ImGuiConfigFlags.NoMouseCursorChange) != 0)
|
if ((io.ConfigFlags & ImGuiConfigFlags.NoMouseCursorChange) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ImGuiMouseCursor cursor = ImGui.GetMouseCursor();
|
var bd = Data;
|
||||||
|
|
||||||
if (io.MouseDrawCursor || cursor == ImGuiMouseCursor.None)
|
ImGuiMouseCursor imguiCursor = ImGui.GetMouseCursor();
|
||||||
|
if (io.MouseDrawCursor || imguiCursor == ImGuiMouseCursor.None)
|
||||||
{
|
{
|
||||||
|
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||||
SDL.HideCursor();
|
SDL.HideCursor();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
nint expected = data.MouseCursors[(int)cursor];
|
|
||||||
|
|
||||||
if (data.MouseLastCursor != expected)
|
|
||||||
{
|
{
|
||||||
SDL.SetCursor(expected);
|
// Show OS mouse cursor
|
||||||
data.MouseLastCursor = expected;
|
nint expectedCursor = bd.MouseCursors[(int)imguiCursor] != nint.Zero ? bd.MouseCursors[(int)imguiCursor] : bd.MouseCursors[(int)ImGuiMouseCursor.Arrow];
|
||||||
|
if (bd.MouseLastCursor != expectedCursor)
|
||||||
|
{
|
||||||
|
SDL.SetCursor(expectedCursor); // SDL function doesn't have an early out (see #6113)
|
||||||
|
bd.MouseLastCursor = expectedCursor;
|
||||||
|
}
|
||||||
|
SDL.ShowCursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL.ShowCursor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CloseGamepads()
|
private static void CloseGamepads()
|
||||||
@@ -416,8 +494,9 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
io.AddKeyAnalogEvent(key, mergedValue > 0.1f, mergedValue);
|
io.AddKeyAnalogEvent(key, mergedValue > 0.1f, mergedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateGamepads(PlatformData data)
|
private static void UpdateGamepads()
|
||||||
{
|
{
|
||||||
|
PlatformData data = Data;
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
ImGuiIOPtr io = ImGui.GetIO();
|
||||||
|
|
||||||
if (data.WantUpdateGamepadsList && data.GamepadMode != GamepadMode.Manual)
|
if (data.WantUpdateGamepadsList && data.GamepadMode != GamepadMode.Manual)
|
||||||
@@ -664,8 +743,9 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
data.ImeDirty = true;
|
data.ImeDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void UpdateIme(PlatformData data)
|
public static void UpdateIme()
|
||||||
{
|
{
|
||||||
|
PlatformData data = Data;
|
||||||
ImGuiPlatformImeData imeData = data.ImeData;
|
ImGuiPlatformImeData imeData = data.ImeData;
|
||||||
nint window = SDL.GetKeyboardFocus();
|
nint window = SDL.GetKeyboardFocus();
|
||||||
|
|
||||||
@@ -723,7 +803,6 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
|
|
||||||
private static void CreateWindow(ImGuiViewportPtr viewport)
|
private static void CreateWindow(ImGuiViewportPtr viewport)
|
||||||
{
|
{
|
||||||
Program.Logger.Log(null);
|
|
||||||
PlatformData bd = Data;
|
PlatformData bd = Data;
|
||||||
|
|
||||||
ViewPortData vd = new ViewPortData();
|
ViewPortData vd = new ViewPortData();
|
||||||
@@ -733,10 +812,7 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
|
|
||||||
flags |= SDL.GetWindowFlags(bd.Window) & SDL.WindowFlags.HighPixelDensity;
|
flags |= SDL.GetWindowFlags(bd.Window) & SDL.WindowFlags.HighPixelDensity;
|
||||||
|
|
||||||
string? videoDriver = SDL.GetCurrentVideoDriver();
|
if ((viewport.Flags & ImGuiViewportFlags.NoDecoration) != 0)
|
||||||
bool isWayland = string.Equals(videoDriver, "wayland", StringComparison.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
if ((viewport.Flags & ImGuiViewportFlags.NoDecoration) != 0 && !isWayland)
|
|
||||||
{
|
{
|
||||||
flags |= SDL.WindowFlags.Borderless;
|
flags |= SDL.WindowFlags.Borderless;
|
||||||
}
|
}
|
||||||
@@ -755,7 +831,7 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
flags |= SDL.WindowFlags.AlwaysOnTop;
|
flags |= SDL.WindowFlags.AlwaysOnTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
vd.Window = SDL.CreateWindow("Untitled", (int)viewport.Size.X, (int)viewport.Size.Y, flags);
|
vd.Window = SDL.CreateWindow("Untitled", (int)viewport.Size.X, (int)viewport.Size.Y, flags | SDL.WindowFlags.Transparent);
|
||||||
|
|
||||||
ImGuiViewportPtr? parentViewport = viewport.ParentViewportId != 0 ? ImGui.FindViewportByID(viewport.ParentViewportId) : null;
|
ImGuiViewportPtr? parentViewport = viewport.ParentViewportId != 0 ? ImGui.FindViewportByID(viewport.ParentViewportId) : null;
|
||||||
if (parentViewport != null && parentViewport.Value.Handle != null)
|
if (parentViewport != null && parentViewport.Value.Handle != null)
|
||||||
@@ -783,7 +859,6 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
|
|
||||||
private static void DestroyWindow(ImGuiViewportPtr viewport)
|
private static void DestroyWindow(ImGuiViewportPtr viewport)
|
||||||
{
|
{
|
||||||
Program.Logger.Log(null);
|
|
||||||
ViewPortData? vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData);
|
ViewPortData? vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData);
|
||||||
|
|
||||||
if (vd != null)
|
if (vd != null)
|
||||||
@@ -799,13 +874,10 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
viewport.PlatformUserData = null;
|
viewport.PlatformUserData = null;
|
||||||
viewport.PlatformHandle = null;
|
viewport.PlatformHandle = null;
|
||||||
viewport.PlatformHandleRaw = null;
|
viewport.PlatformHandleRaw = null;
|
||||||
|
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void ShowWindow(ImGuiViewportPtr viewport)
|
private static void ShowWindow(ImGuiViewportPtr viewport)
|
||||||
{
|
{
|
||||||
Program.Logger.Log(null);
|
|
||||||
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
||||||
|
|
||||||
string? oldHint = SDL.GetHint(SDL.Hints.WindowActivateWhenShown);
|
string? oldHint = SDL.GetHint(SDL.Hints.WindowActivateWhenShown);
|
||||||
@@ -815,12 +887,10 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
SDL.ShowWindow(vd.Window);
|
SDL.ShowWindow(vd.Window);
|
||||||
|
|
||||||
SDL.SetHint(SDL.Hints.WindowActivateWhenShown, oldHint);
|
SDL.SetHint(SDL.Hints.WindowActivateWhenShown, oldHint);
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateWindow(ImGuiViewportPtr viewport)
|
private static void UpdateWindow(ImGuiViewportPtr viewport)
|
||||||
{
|
{
|
||||||
Program.Logger.Log(null);
|
|
||||||
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
||||||
|
|
||||||
if ((viewport.Flags & ImGuiViewportFlags.TopMost) != 0)
|
if ((viewport.Flags & ImGuiViewportFlags.TopMost) != 0)
|
||||||
@@ -831,7 +901,6 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
{
|
{
|
||||||
SDL.SetWindowAlwaysOnTop(vd.Window, false);
|
SDL.SetWindowAlwaysOnTop(vd.Window, false);
|
||||||
}
|
}
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vector2 GetWindowPos(ImGuiViewportPtr viewport)
|
private static Vector2 GetWindowPos(ImGuiViewportPtr viewport)
|
||||||
@@ -839,8 +908,6 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
||||||
|
|
||||||
SDL.GetWindowPosition(vd.Window, out int x, out int y);
|
SDL.GetWindowPosition(vd.Window, out int x, out int y);
|
||||||
|
|
||||||
// Program.Logger.Log(null);
|
|
||||||
|
|
||||||
return new Vector2(x, y);
|
return new Vector2(x, y);
|
||||||
}
|
}
|
||||||
@@ -850,7 +917,6 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
||||||
|
|
||||||
SDL.SetWindowPosition(vd.Window, (int)pos.X, (int)pos.Y);
|
SDL.SetWindowPosition(vd.Window, (int)pos.X, (int)pos.Y);
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vector2 GetWindowSize(ImGuiViewportPtr viewport)
|
private static Vector2 GetWindowSize(ImGuiViewportPtr viewport)
|
||||||
@@ -859,7 +925,6 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
|
|
||||||
SDL.GetWindowSize(vd.Window, out int w, out int h);
|
SDL.GetWindowSize(vd.Window, out int w, out int h);
|
||||||
|
|
||||||
// Program.Logger.Log(null);
|
|
||||||
return new Vector2(w, h);
|
return new Vector2(w, h);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -868,7 +933,6 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
||||||
|
|
||||||
SDL.SetWindowSize(vd.Window, (int)size.X, (int)size.Y);
|
SDL.SetWindowSize(vd.Window, (int)size.X, (int)size.Y);
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vector2 GetWindowFramebufferScale(ImGuiViewportPtr viewport)
|
private static Vector2 GetWindowFramebufferScale(ImGuiViewportPtr viewport)
|
||||||
@@ -876,7 +940,6 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
||||||
|
|
||||||
GetWindowSizeAndFramebufferScale(vd.Window, out Vector2 framebufferSize, out Vector2 framebufferScale);
|
GetWindowSizeAndFramebufferScale(vd.Window, out Vector2 framebufferSize, out Vector2 framebufferScale);
|
||||||
// Program.Logger.Log(null);
|
|
||||||
|
|
||||||
return framebufferScale;
|
return framebufferScale;
|
||||||
}
|
}
|
||||||
@@ -886,7 +949,6 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
||||||
|
|
||||||
SDL.SetWindowTitle(vd.Window, title);
|
SDL.SetWindowTitle(vd.Window, title);
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetWindowAlpha(ImGuiViewportPtr viewport, float alpha)
|
private static void SetWindowAlpha(ImGuiViewportPtr viewport, float alpha)
|
||||||
@@ -894,7 +956,6 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
||||||
|
|
||||||
SDL.SetWindowOpacity(vd.Window, alpha);
|
SDL.SetWindowOpacity(vd.Window, alpha);
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetWindowFocus(ImGuiViewportPtr viewport)
|
private static void SetWindowFocus(ImGuiViewportPtr viewport)
|
||||||
@@ -902,13 +963,11 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
||||||
|
|
||||||
SDL.RaiseWindow(vd.Window);
|
SDL.RaiseWindow(vd.Window);
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool GetWindowFocus(ImGuiViewportPtr viewport)
|
private static bool GetWindowFocus(ImGuiViewportPtr viewport)
|
||||||
{
|
{
|
||||||
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
||||||
// Program.Logger.Log(null);
|
|
||||||
|
|
||||||
return (SDL.GetWindowFlags(vd.Window) & SDL.WindowFlags.InputFocus) != 0;
|
return (SDL.GetWindowFlags(vd.Window) & SDL.WindowFlags.InputFocus) != 0;
|
||||||
}
|
}
|
||||||
@@ -916,23 +975,10 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
private static bool GetWindowMinimized(ImGuiViewportPtr viewport)
|
private static bool GetWindowMinimized(ImGuiViewportPtr viewport)
|
||||||
{
|
{
|
||||||
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
ViewPortData vd = ImGuiUserData<ViewPortData>.Get(viewport.PlatformUserData)!;
|
||||||
// Program.Logger.Log(null);
|
|
||||||
|
|
||||||
return (SDL.GetWindowFlags(vd.Window) & SDL.WindowFlags.Minimized) != 0;
|
return (SDL.GetWindowFlags(vd.Window) & SDL.WindowFlags.Minimized) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
private delegate void CreateWindowDelegatelFn(ImGuiViewportPtr ctx);
|
private delegate void CreateWindowDelegatelFn(ImGuiViewportPtr ctx);
|
||||||
@@ -999,16 +1045,6 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
|
|
||||||
private static readonly SetWindowTitleDelegatelFn SetWindowTitleDelegate = SetWindowTitle;
|
private static readonly SetWindowTitleDelegatelFn SetWindowTitleDelegate = SetWindowTitle;
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
||||||
private delegate void RenderWindowDelegatelFn(ImGuiViewportPtr ctx);
|
|
||||||
|
|
||||||
private static readonly RenderWindowDelegatelFn RenderWindowDelegate = RenderWindow;
|
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
||||||
private delegate void SwapBuffersDelegatelFn(ImGuiViewportPtr ctx);
|
|
||||||
|
|
||||||
private static readonly SwapBuffersDelegatelFn SwapBuffersDelegate = SwapBuffers;
|
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
private delegate void SetWindowAlphaDelegatelFn(ImGuiViewportPtr ctx, float alpha);
|
private delegate void SetWindowAlphaDelegatelFn(ImGuiViewportPtr ctx, float alpha);
|
||||||
|
|
||||||
@@ -1016,8 +1052,7 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
|
|
||||||
private static void InitMultiViewportSupport(nint window)
|
private static void InitMultiViewportSupport(nint window)
|
||||||
{
|
{
|
||||||
Program.Logger.Log(null);
|
|
||||||
|
|
||||||
ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO();
|
ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO();
|
||||||
|
|
||||||
platformIO.PlatformCreateWindow = (void*)Marshal.GetFunctionPointerForDelegate(CreateWindowDelegate);
|
platformIO.PlatformCreateWindow = (void*)Marshal.GetFunctionPointerForDelegate(CreateWindowDelegate);
|
||||||
@@ -1048,8 +1083,7 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
|
|
||||||
mainViewport.PlatformUserData = ImGuiUserData<ViewPortData>.Store(vd);
|
mainViewport.PlatformUserData = ImGuiUserData<ViewPortData>.Store(vd);
|
||||||
mainViewport.PlatformHandle = (void*)(nint)SDL.GetWindowID(window);
|
mainViewport.PlatformHandle = (void*)(nint)SDL.GetWindowID(window);
|
||||||
|
|
||||||
Program.Logger.Log(null);
|
|
||||||
|
|
||||||
#if WINDOWS
|
#if WINDOWS
|
||||||
mainViewport.PlatformHandleRaw = SDL.GetPointerProperty(
|
mainViewport.PlatformHandleRaw = SDL.GetPointerProperty(
|
||||||
@@ -1080,7 +1114,7 @@ public unsafe static class ImGuiSDL3Platform
|
|||||||
SDL.GetPointerProperty(SDL.GetWindowProperties(window), SDL.Props.WindowCocoaWindow, 0);
|
SDL.GetPointerProperty(SDL.GetWindowProperties(window), SDL.Props.WindowCocoaWindow, 0);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Dispose()
|
public static void Dispose()
|
||||||
{
|
{
|
||||||
PlatformData? data = Data;
|
PlatformData? data = Data;
|
||||||
@@ -1149,4 +1183,4 @@ public unsafe static class ImGuiUserData<T> where T : class
|
|||||||
if (handle.IsAllocated)
|
if (handle.IsAllocated)
|
||||||
handle.Free();
|
handle.Free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+77
-155
@@ -11,11 +11,7 @@ namespace SDL3_TestingSuite.SDL3;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public unsafe static class ImGuiSDL3Renderer
|
public unsafe static class ImGuiSDL3Renderer
|
||||||
{
|
{
|
||||||
private sealed class TextureState
|
public static SDL3Window Parent;
|
||||||
{
|
|
||||||
public ImTextureDataPtr Source;
|
|
||||||
public readonly Dictionary<nint, nint> RendererTextures = new();
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RendererData
|
public class RendererData
|
||||||
{
|
{
|
||||||
@@ -44,11 +40,6 @@ public unsafe static class ImGuiSDL3Renderer
|
|||||||
|
|
||||||
private static readonly RendererDestroyWindowFn RendererDestroyWindowDelegate = RendererDestroyWindow;
|
private static readonly RendererDestroyWindowFn RendererDestroyWindowDelegate = RendererDestroyWindow;
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
|
||||||
private delegate void RendererSetWindowSizeFn(ImGuiViewportPtr viewport, Vector2 size);
|
|
||||||
|
|
||||||
private static readonly RendererSetWindowSizeFn RendererSetWindowSizeDelegate = RendererSetWindowSize;
|
|
||||||
|
|
||||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
private delegate void RendererRenderWindowFn(ImGuiViewportPtr viewport);
|
private delegate void RendererRenderWindowFn(ImGuiViewportPtr viewport);
|
||||||
|
|
||||||
@@ -61,8 +52,9 @@ public unsafe static class ImGuiSDL3Renderer
|
|||||||
|
|
||||||
public static RendererData Data => ImGui.GetCurrentContext().Handle != null ? ImGuiUserData<RendererData>.Get(ImGui.GetIO().BackendRendererUserData)! : null!;
|
public static RendererData Data => ImGui.GetCurrentContext().Handle != null ? ImGuiUserData<RendererData>.Get(ImGui.GetIO().BackendRendererUserData)! : null!;
|
||||||
|
|
||||||
public static bool Init(nint renderer)
|
public static bool Init(nint renderer, SDL3Window parentWindow = null)
|
||||||
{
|
{
|
||||||
|
Parent = parentWindow;
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
ImGuiIOPtr io = ImGui.GetIO();
|
||||||
|
|
||||||
RendererData bd = new RendererData();
|
RendererData bd = new RendererData();
|
||||||
@@ -77,7 +69,6 @@ public unsafe static class ImGuiSDL3Renderer
|
|||||||
ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO();
|
ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO();
|
||||||
platformIO.RendererCreateWindow = (void*)Marshal.GetFunctionPointerForDelegate(RendererCreateWindowDelegate);
|
platformIO.RendererCreateWindow = (void*)Marshal.GetFunctionPointerForDelegate(RendererCreateWindowDelegate);
|
||||||
platformIO.RendererDestroyWindow = (void*)Marshal.GetFunctionPointerForDelegate(RendererDestroyWindowDelegate);
|
platformIO.RendererDestroyWindow = (void*)Marshal.GetFunctionPointerForDelegate(RendererDestroyWindowDelegate);
|
||||||
platformIO.RendererSetWindowSize = (void*)Marshal.GetFunctionPointerForDelegate(RendererSetWindowSizeDelegate);
|
|
||||||
platformIO.RendererRenderWindow = (void*)Marshal.GetFunctionPointerForDelegate(RendererRenderWindowDelegate);
|
platformIO.RendererRenderWindow = (void*)Marshal.GetFunctionPointerForDelegate(RendererRenderWindowDelegate);
|
||||||
platformIO.RendererSwapBuffers = (void*)Marshal.GetFunctionPointerForDelegate(RendererSwapBuffersDelegate);
|
platformIO.RendererSwapBuffers = (void*)Marshal.GetFunctionPointerForDelegate(RendererSwapBuffersDelegate);
|
||||||
|
|
||||||
@@ -108,22 +99,19 @@ public unsafe static class ImGuiSDL3Renderer
|
|||||||
|
|
||||||
private static void RendererCreateWindow(ImGuiViewportPtr viewport)
|
private static void RendererCreateWindow(ImGuiViewportPtr viewport)
|
||||||
{
|
{
|
||||||
Program.Logger.Log(null);
|
|
||||||
ImGuiSDL3Platform.ViewPortData? vd = ImGuiUserData<ImGuiSDL3Platform.ViewPortData>.Get(viewport.PlatformUserData);
|
ImGuiSDL3Platform.ViewPortData? vd = ImGuiUserData<ImGuiSDL3Platform.ViewPortData>.Get(viewport.PlatformUserData);
|
||||||
if (vd == null || vd.Window == nint.Zero)
|
if (vd == null || vd.Window == nint.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (vd.Renderer == nint.Zero)
|
if (vd.Renderer == nint.Zero)
|
||||||
{
|
{
|
||||||
vd.Renderer = SDL.CreateRenderer(vd.Window, (string?)null);
|
vd.Renderer = SDL.CreateRenderer(vd.Window, null);
|
||||||
vd.RendererOwned = true;
|
vd.RendererOwned = true;
|
||||||
}
|
}
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RendererDestroyWindow(ImGuiViewportPtr viewport)
|
private static void RendererDestroyWindow(ImGuiViewportPtr viewport)
|
||||||
{
|
{
|
||||||
Program.Logger.Log(null);
|
|
||||||
ImGuiSDL3Platform.ViewPortData? vd = ImGuiUserData<ImGuiSDL3Platform.ViewPortData>.Get(viewport.PlatformUserData);
|
ImGuiSDL3Platform.ViewPortData? vd = ImGuiUserData<ImGuiSDL3Platform.ViewPortData>.Get(viewport.PlatformUserData);
|
||||||
if (vd == null)
|
if (vd == null)
|
||||||
return;
|
return;
|
||||||
@@ -135,37 +123,32 @@ public unsafe static class ImGuiSDL3Renderer
|
|||||||
|
|
||||||
vd.Renderer = nint.Zero;
|
vd.Renderer = nint.Zero;
|
||||||
vd.RendererOwned = false;
|
vd.RendererOwned = false;
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void RendererSetWindowSize(ImGuiViewportPtr viewport, Vector2 size)
|
|
||||||
{
|
|
||||||
// SDL renderer windows track size through the platform window callback.
|
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RendererRenderWindow(ImGuiViewportPtr viewport)
|
private static void RendererRenderWindow(ImGuiViewportPtr viewport)
|
||||||
{
|
{
|
||||||
Program.Logger.Log(null);
|
|
||||||
ImGuiSDL3Platform.ViewPortData? vd = ImGuiUserData<ImGuiSDL3Platform.ViewPortData>.Get(viewport.PlatformUserData);
|
ImGuiSDL3Platform.ViewPortData? vd = ImGuiUserData<ImGuiSDL3Platform.ViewPortData>.Get(viewport.PlatformUserData);
|
||||||
if (vd == null || vd.Renderer == nint.Zero)
|
if (vd == null || vd.Renderer == nint.Zero)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Parent != null)
|
||||||
|
{
|
||||||
|
SDL.SetRenderDrawColorFloat(vd.Renderer, Parent.ClearColor.X, Parent.ClearColor.Y, Parent.ClearColor.Z, 0f);
|
||||||
|
SDL.RenderClear(vd.Renderer);
|
||||||
|
}
|
||||||
|
|
||||||
RenderDrawData(viewport.DrawData, vd.Renderer);
|
RenderDrawData(viewport.DrawData, vd.Renderer);
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void RendererSwapBuffers(ImGuiViewportPtr viewport)
|
private static void RendererSwapBuffers(ImGuiViewportPtr viewport)
|
||||||
{
|
{
|
||||||
Program.Logger.Log(null);
|
|
||||||
ImGuiSDL3Platform.ViewPortData? vd = ImGuiUserData<ImGuiSDL3Platform.ViewPortData>.Get(viewport.PlatformUserData);
|
ImGuiSDL3Platform.ViewPortData? vd = ImGuiUserData<ImGuiSDL3Platform.ViewPortData>.Get(viewport.PlatformUserData);
|
||||||
if (vd == null || vd.Renderer == nint.Zero)
|
if (vd == null || vd.Renderer == nint.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
SDL.RenderPresent(vd.Renderer);
|
SDL.RenderPresent(vd.Renderer);
|
||||||
Program.Logger.Log(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RenderDrawData(ImDrawDataPtr drawData, nint renderer)
|
public static void RenderDrawData(ImDrawDataPtr drawData, nint renderer)
|
||||||
@@ -175,9 +158,7 @@ public unsafe static class ImGuiSDL3Renderer
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
SDL.GetRenderScale(renderer, out float renderScaleX, out float renderScaleY);
|
SDL.GetRenderScale(renderer, out float renderScaleX, out float renderScaleY);
|
||||||
Vector2 renderScale = new Vector2(
|
Vector2 renderScale = new Vector2(renderScaleX == 1.0f ? drawData.FramebufferScale.X : 1.0f, renderScaleY == 1.0f ? drawData.FramebufferScale.Y : 1.0f);
|
||||||
renderScaleX == 1.0f ? drawData.FramebufferScale.X : 1.0f,
|
|
||||||
renderScaleY == 1.0f ? drawData.FramebufferScale.Y : 1.0f);
|
|
||||||
|
|
||||||
int fbWidth = (int)(drawData.DisplaySize.X * renderScale.X);
|
int fbWidth = (int)(drawData.DisplaySize.X * renderScale.X);
|
||||||
int fbHeight = (int)(drawData.DisplaySize.Y * renderScale.Y);
|
int fbHeight = (int)(drawData.DisplaySize.Y * renderScale.Y);
|
||||||
@@ -196,13 +177,11 @@ public unsafe static class ImGuiSDL3Renderer
|
|||||||
ViewportEnabled = SDL.RenderViewportSet(renderer),
|
ViewportEnabled = SDL.RenderViewportSet(renderer),
|
||||||
ClipEnabled = SDL.RenderClipEnabled(renderer)
|
ClipEnabled = SDL.RenderClipEnabled(renderer)
|
||||||
};
|
};
|
||||||
SDL.GetRenderViewport(renderer, out var oldViewport);
|
SDL.GetRenderViewport(renderer, out old.Viewport);
|
||||||
old.Viewport = oldViewport;
|
SDL.GetRenderClipRect(renderer, out old.ClipRect);
|
||||||
SDL.GetRenderClipRect(renderer, out var oldClipRect);
|
|
||||||
old.ClipRect = oldClipRect;
|
|
||||||
|
|
||||||
// Set up render state
|
// Set up render state
|
||||||
SDL.SetRenderViewport(renderer, 0);
|
SDL.SetRenderViewport(renderer, nint.Zero);
|
||||||
SDL.SetRenderClipRect(renderer, nint.Zero);
|
SDL.SetRenderClipRect(renderer, nint.Zero);
|
||||||
|
|
||||||
// Set render state in platform IO
|
// Set render state in platform IO
|
||||||
@@ -224,37 +203,35 @@ public unsafe static class ImGuiSDL3Renderer
|
|||||||
{
|
{
|
||||||
continue; // User callback not implemented
|
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
|
X = (int)clipMin.X,
|
||||||
Vector4 clipRect = cmd.ClipRect;
|
Y = (int)clipMin.Y,
|
||||||
Vector2 clipMin = new Vector2((clipRect.X - clipOffset.X) * renderScale.X, (clipRect.Y - clipOffset.Y) * renderScale.Y);
|
W = (int)(clipMax.X - clipMin.X),
|
||||||
Vector2 clipMax = new Vector2((clipRect.Z - clipOffset.X) * renderScale.X, (clipRect.W - clipOffset.Y) * renderScale.Y);
|
H = (int)(clipMax.Y - clipMin.Y)
|
||||||
|
};
|
||||||
|
SDL.SetRenderClipRect(renderer, r);
|
||||||
|
|
||||||
clipMin.X = Math.Max(0, clipMin.X);
|
// Get texture
|
||||||
clipMin.Y = Math.Max(0, clipMin.Y);
|
nint texId = cmd.GetTexID();
|
||||||
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
|
// Convert ImGui vertices to SDL vertices
|
||||||
{
|
if (!RenderDrawCommand(cmdList, cmd, renderer, texId, renderScale, clipOffset))
|
||||||
X = (int)clipMin.X,
|
{
|
||||||
Y = (int)clipMin.Y,
|
Console.WriteLine($"Failed to render ImGui draw command: {SDL.GetError()}");
|
||||||
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()}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -267,108 +244,53 @@ public unsafe static class ImGuiSDL3Renderer
|
|||||||
SDL.SetRenderClipRect(renderer, old.ClipEnabled ? old.ClipRect : 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<TextureState>.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)
|
private static void UpdateTexture(ImTextureDataPtr tex, nint renderer)
|
||||||
{
|
{
|
||||||
TextureState? state = null;
|
|
||||||
if ((nint)tex.BackendUserData != nint.Zero)
|
|
||||||
state = ImGuiUserData<TextureState>.Get(tex.BackendUserData);
|
|
||||||
|
|
||||||
if (state == null)
|
|
||||||
{
|
|
||||||
state = new TextureState();
|
|
||||||
tex.BackendUserData = ImGuiUserData<TextureState>.Store(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
state.Source = tex;
|
|
||||||
tex.SetTexID((nint)tex.BackendUserData);
|
|
||||||
|
|
||||||
if (tex.Status == ImTextureStatus.WantDestroy)
|
if (tex.Status == ImTextureStatus.WantDestroy)
|
||||||
{
|
{
|
||||||
foreach (nint rendererTexture in state.RendererTextures.Values)
|
if (tex.TexID != ImTextureID.Null)
|
||||||
{
|
SDL.DestroyTexture(tex.TexID);
|
||||||
if (rendererTexture != nint.Zero)
|
|
||||||
SDL.DestroyTexture(rendererTexture);
|
|
||||||
}
|
|
||||||
|
|
||||||
state.RendererTextures.Clear();
|
|
||||||
ImGuiUserData<TextureState>.Free(tex.BackendUserData);
|
|
||||||
tex.BackendUserData = (void*)nint.Zero;
|
|
||||||
tex.SetTexID(ImTextureID.Null);
|
tex.SetTexID(ImTextureID.Null);
|
||||||
tex.SetStatus(ImTextureStatus.Destroyed);
|
tex.SetStatus(ImTextureStatus.Destroyed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasRendererTexture = state.RendererTextures.TryGetValue(renderer, out nint sdlTexture) && sdlTexture != nint.Zero;
|
bool needsCreate = tex.TexID == ImTextureID.Null || SDL.GetRendererFromTexture(tex.TexID) != renderer;
|
||||||
if (!hasRendererTexture)
|
if (tex.Status == ImTextureStatus.WantCreate || needsCreate)
|
||||||
{
|
{
|
||||||
sdlTexture = CreateRendererTexture(state, renderer);
|
if (tex.TexID != ImTextureID.Null)
|
||||||
state.RendererTextures[renderer] = sdlTexture;
|
SDL.DestroyTexture(tex.TexID);
|
||||||
|
|
||||||
|
// Create texture on the renderer that is actually drawing this viewport.
|
||||||
|
// SDL textures are renderer-owned and cannot be shared across renderer instances.
|
||||||
|
nint sdlTexture = SDL.CreateTexture(renderer, SDL.PixelFormat.ABGR8888, SDL.TextureAccess.Static, tex.Width, tex.Height);
|
||||||
|
SDL.UpdateTexture(sdlTexture, nint.Zero, (nint)tex.GetPixels(), tex.GetPitch());
|
||||||
|
SDL.SetTextureBlendMode(sdlTexture, SDL.BlendMode.Blend);
|
||||||
|
SDL.SetTextureScaleMode(sdlTexture, SDL.ScaleMode.Linear);
|
||||||
|
|
||||||
|
tex.SetTexID(sdlTexture);
|
||||||
|
tex.SetStatus(ImTextureStatus.Ok);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sdlTexture != nint.Zero && (tex.Status == ImTextureStatus.WantCreate || tex.Status == ImTextureStatus.WantUpdates || !hasRendererTexture))
|
if (tex.Status == ImTextureStatus.WantUpdates)
|
||||||
{
|
{
|
||||||
UploadRendererTexture(tex, renderer, sdlTexture);
|
// Update selected blocks. We only ever write to textures regions which have never been used before!
|
||||||
|
// This backend choose to use tex.Updates[] but you can use tex.UpdateRect to upload a single region.
|
||||||
|
nint sdlTexture = tex.TexID;
|
||||||
|
for (int i = 0; i < tex.Updates.Size; i++)
|
||||||
|
{
|
||||||
|
var r = tex.Updates[i];
|
||||||
|
SDL.Rect sdlR = new SDL.Rect { X = r.X, Y = r.Y, W = r.W, H = r.H };
|
||||||
|
SDL.UpdateTexture(sdlTexture, sdlR, (nint)tex.GetPixelsAt(r.X, r.Y), tex.GetPitch());
|
||||||
|
}
|
||||||
tex.SetStatus(ImTextureStatus.Ok);
|
tex.SetStatus(ImTextureStatus.Ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool RenderDrawCommand(ImDrawListPtr drawList, ImDrawCmd cmd, nint renderer, nint texId, Vector2 scale)
|
|
||||||
|
private static bool RenderDrawCommand(ImDrawListPtr drawList, ImDrawCmd cmd, nint renderer, nint texId, Vector2 scale, Vector2 displayPos)
|
||||||
{
|
{
|
||||||
uint indexOffset = cmd.IdxOffset;
|
uint indexOffset = cmd.IdxOffset;
|
||||||
uint vertexOffset = cmd.VtxOffset;
|
uint vertexOffset = cmd.VtxOffset;
|
||||||
@@ -391,21 +313,21 @@ public unsafe static class ImGuiSDL3Renderer
|
|||||||
byte b = (byte)((col >> 16) & 0xFF);
|
byte b = (byte)((col >> 16) & 0xFF);
|
||||||
byte a = (byte)((col >> 24) & 0xFF);
|
byte a = (byte)((col >> 24) & 0xFF);
|
||||||
|
|
||||||
vertices[i] = new SDL.Vertex()
|
vertices[i] = new SDL.Vertex
|
||||||
{
|
{
|
||||||
Position = new SDL.FPoint()
|
Position = new SDL.FPoint
|
||||||
{
|
{
|
||||||
X = srcVert.Pos.X * scale.X,
|
X = (srcVert.Pos.X - displayPos.X) * scale.X,
|
||||||
Y = srcVert.Pos.Y * scale.Y
|
Y = (srcVert.Pos.Y - displayPos.Y) * scale.Y
|
||||||
},
|
},
|
||||||
Color = new SDL.FColor()
|
Color = new SDL.FColor
|
||||||
{
|
{
|
||||||
R = r / 255f,
|
R = r / 255f,
|
||||||
G = g / 255f,
|
G = g / 255f,
|
||||||
B = b / 255f,
|
B = b / 255f,
|
||||||
A = a / 255f
|
A = a / 255f
|
||||||
},
|
},
|
||||||
TexCoord = new SDL.FPoint()
|
TexCoord = new SDL.FPoint
|
||||||
{
|
{
|
||||||
X = srcVert.Uv.X,
|
X = srcVert.Uv.X,
|
||||||
Y = srcVert.Uv.Y
|
Y = srcVert.Uv.Y
|
||||||
@@ -427,7 +349,7 @@ public unsafe static class ImGuiSDL3Renderer
|
|||||||
{
|
{
|
||||||
var texture = texures[i];
|
var texture = texures[i];
|
||||||
texture.Status = ImTextureStatus.WantDestroy;
|
texture.Status = ImTextureStatus.WantDestroy;
|
||||||
UpdateTexture(texture, nint.Zero);
|
UpdateTexture(texture, Data.Renderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-8
@@ -1,12 +1,8 @@
|
|||||||
using System;
|
using System.Diagnostics;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using Hexa.NET.ImGui;
|
using Hexa.NET.ImGui;
|
||||||
using Hexa.NET.ImGui.Utilities;
|
|
||||||
using Hexa.NET.ImGuizmo;
|
using Hexa.NET.ImGuizmo;
|
||||||
using Hexa.NET.ImPlot;
|
using Hexa.NET.ImPlot;
|
||||||
using Hexa.NET.ImPlot3D;
|
|
||||||
using SDL3;
|
using SDL3;
|
||||||
|
|
||||||
namespace SDL3_TestingSuite.SDL3;
|
namespace SDL3_TestingSuite.SDL3;
|
||||||
@@ -54,7 +50,7 @@ public sealed unsafe class SDL3Window : IDisposable
|
|||||||
|
|
||||||
ImGuiIOPtr io = ImGui.GetIO();
|
ImGuiIOPtr io = ImGui.GetIO();
|
||||||
io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard | ImGuiConfigFlags.NavEnableGamepad | ImGuiConfigFlags.DockingEnable;
|
io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard | ImGuiConfigFlags.NavEnableGamepad | ImGuiConfigFlags.DockingEnable;
|
||||||
// io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable;
|
io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable;
|
||||||
io.Fonts.Flags |= ImFontAtlasFlags.NoBakedLines;
|
io.Fonts.Flags |= ImFontAtlasFlags.NoBakedLines;
|
||||||
|
|
||||||
io.Fonts.AddFontDefault();
|
io.Fonts.AddFontDefault();
|
||||||
@@ -96,8 +92,8 @@ public sealed unsafe class SDL3Window : IDisposable
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Init platform and renderer
|
// Init platform and renderer
|
||||||
ImGuiSDL3Platform.Init(Window, Renderer);
|
ImGuiSDL3Platform.Init(Window, Renderer, this);
|
||||||
ImGuiSDL3Renderer.Init(Renderer);
|
ImGuiSDL3Renderer.Init(Renderer, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Run()
|
public void Run()
|
||||||
|
|||||||
Reference in New Issue
Block a user