174 lines
4.6 KiB
C#
174 lines
4.6 KiB
C#
using System;
|
|
using System.Diagnostics;
|
|
using System.Numerics;
|
|
using System.Runtime.InteropServices;
|
|
using ImGuiNET;
|
|
using SDL3;
|
|
|
|
namespace SDL3_TestingSuite.SDL3;
|
|
|
|
public sealed class SDL3Window : IDisposable
|
|
{
|
|
public readonly nint Window;
|
|
public readonly nint Renderer;
|
|
|
|
internal Action? RenderCallback { get; set; }
|
|
|
|
public Vector4 ClearColor = new Vector4(0.06f, 0.05882353f, 0.05882353f, 1f);
|
|
|
|
private readonly Stopwatch _timer = Stopwatch.StartNew();
|
|
private TimeSpan _time = TimeSpan.Zero;
|
|
|
|
private SDL.Rect _screenClipRect;
|
|
private nint _imGuiContext;
|
|
|
|
public bool Disposed => _disposed;
|
|
private bool _disposed;
|
|
|
|
private FileSystemWatcher? _watcher;
|
|
|
|
public SDL3Window(string name, int posX, int posY, int width, int height, SDL.WindowFlags flags = SDL.WindowFlags.Resizable | SDL.WindowFlags.HighPixelDensity)
|
|
{
|
|
if (!SDL.Init(SDL.InitFlags.Events | SDL.InitFlags.Video | SDL.InitFlags.Gamepad))
|
|
throw new Exception($"SDL_Init failed: {SDL.GetError()}");
|
|
|
|
// Create window & renderer
|
|
if (!SDL.CreateWindowAndRenderer(name, width, height, flags, out Window, out Renderer))
|
|
throw new Exception($"SDL_CreateWindowAndRenderer failed: {SDL.GetError()}");
|
|
|
|
SDL.SetWindowPosition(Window, posX, posY);
|
|
SDL.SetRenderVSync(Renderer, 1);
|
|
SDL.ShowWindow(Window);
|
|
|
|
// Create ImGui context
|
|
_imGuiContext = ImGui.CreateContext();
|
|
|
|
ImGuiIOPtr io = ImGui.GetIO();
|
|
io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard | ImGuiConfigFlags.NavEnableGamepad | ImGuiConfigFlags.DockingEnable;
|
|
// io.ConfigFlags |= ImGuiConfigFlags.ViewportsEnable;
|
|
io.Fonts.Flags |= ImFontAtlasFlags.NoBakedLines;
|
|
|
|
// Init platform and renderer
|
|
ImGuiSDL3Platform.Init(Window, Renderer);
|
|
ImGuiSDL3Renderer.Init(Renderer);
|
|
}
|
|
|
|
public void Run()
|
|
{
|
|
while (!_disposed)
|
|
{
|
|
ImGui.GetIO().DeltaTime = (float)(_timer.Elapsed - _time).TotalSeconds;
|
|
_time = _timer.Elapsed;
|
|
|
|
PollEvents();
|
|
|
|
Update();
|
|
|
|
RenderCallback?.Invoke();
|
|
|
|
Render();
|
|
|
|
if (ShouldClose)
|
|
{
|
|
Dispose();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!_disposed)
|
|
Dispose();
|
|
}
|
|
|
|
public bool ShouldClose;
|
|
|
|
private void PollEvents()
|
|
{
|
|
if (ImGui.GetIO().WantTextInput && !SDL.TextInputActive(Window))
|
|
SDL.StartTextInput(Window);
|
|
else if (!ImGui.GetIO().WantTextInput && SDL.TextInputActive(Window))
|
|
SDL.StopTextInput(Window);
|
|
|
|
while (SDL.PollEvent(out SDL.Event ev))
|
|
{
|
|
ImGuiSDL3Platform.ProcessEvent(ev);
|
|
|
|
switch ((SDL.EventType)ev.Type)
|
|
{
|
|
case SDL.EventType.Terminating:
|
|
case SDL.EventType.WindowCloseRequested:
|
|
case SDL.EventType.Quit:
|
|
ShouldClose = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
ImGuiSDL3Platform.NewFrame();
|
|
ImGuiSDL3Renderer.NewFrame();
|
|
ImGui.NewFrame();
|
|
}
|
|
|
|
private void Render()
|
|
{
|
|
ImGuiIOPtr io = ImGui.GetIO();
|
|
|
|
ImGui.Render();
|
|
SDL.SetRenderScale(Renderer, io.DisplayFramebufferScale.X, io.DisplayFramebufferScale.Y);
|
|
SDL.SetRenderDrawColorFloat(Renderer, ClearColor.X, ClearColor.Y, ClearColor.Z, ClearColor.W);
|
|
SDL.RenderClear(Renderer);
|
|
ImGuiSDL3Renderer.RenderDrawData(ImGui.GetDrawData(), Renderer);
|
|
|
|
if ((io.ConfigFlags & ImGuiConfigFlags.ViewportsEnable) != 0)
|
|
{
|
|
ImGui.UpdatePlatformWindows();
|
|
ImGui.RenderPlatformWindowsDefault();
|
|
}
|
|
|
|
SDL.RenderPresent(Renderer);
|
|
}
|
|
|
|
~SDL3Window()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
private void Dispose(bool disposing)
|
|
{
|
|
if (_disposed) return;
|
|
_disposed = true;
|
|
|
|
if (disposing)
|
|
{
|
|
ImGuiSDL3Renderer.Dispose();
|
|
ImGuiSDL3Platform.Dispose();
|
|
|
|
RenderCallback = null;
|
|
}
|
|
|
|
if (_imGuiContext != nint.Zero)
|
|
{
|
|
ImGui.SetCurrentContext(nint.Zero);
|
|
ImGui.DestroyContext(_imGuiContext);
|
|
_imGuiContext = nint.Zero;
|
|
}
|
|
|
|
if (Renderer != nint.Zero)
|
|
{
|
|
SDL.DestroyRenderer(Renderer);
|
|
}
|
|
|
|
if (Window != nint.Zero)
|
|
{
|
|
SDL.DestroyWindow(Window);
|
|
}
|
|
}
|
|
|
|
} |