Fix viewports
This commit is contained in:
parent
42b978e8c9
commit
d8b41b0827
@ -65,7 +65,7 @@ internal static void Run(string[] args)
|
||||
}
|
||||
|
||||
MainWindow.OnCloseEvent += (w) => {
|
||||
quit = true;
|
||||
Quit();
|
||||
};
|
||||
|
||||
AudioDevice = new AudioDevice();
|
||||
|
@ -37,8 +37,7 @@ internal class GuiController : IDisposable
|
||||
private readonly Shader imGuiFragmentShader;
|
||||
private readonly Sampler imGuiSampler;
|
||||
private readonly GuiTextureStorage textureStorage = new GuiTextureStorage();
|
||||
private readonly Dictionary<Window, GCHandle> windowToHandle = new Dictionary<Window, GCHandle>(16);
|
||||
private readonly Dictionary<ImGuiViewportPtr, Window> imguiToWindow = new Dictionary<ImGuiViewportPtr, Window>(16);
|
||||
private readonly GuiViewportWindow mainViewportWindow;
|
||||
|
||||
private Texture fontTexture = null;
|
||||
private uint vertexCount = 0;
|
||||
@ -49,6 +48,7 @@ internal class GuiController : IDisposable
|
||||
|
||||
public GuiController(GraphicsDevice graphicsDevice, Window mainWindow, Color clearColor, ImGuiConfigFlags configFlags = ImGuiConfigFlags.NavEnableKeyboard | ImGuiConfigFlags.DockingEnable | ImGuiConfigFlags.ViewportsEnable)
|
||||
{
|
||||
this.graphicsDevice = graphicsDevice;
|
||||
this.mainWindow = mainWindow;
|
||||
this.clearColor = clearColor;
|
||||
|
||||
@ -110,9 +110,7 @@ public GuiController(GraphicsDevice graphicsDevice, Window mainWindow, Color cle
|
||||
ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO();
|
||||
ImGuiViewportPtr mainViewport = platformIO.Viewports[0];
|
||||
mainViewport.PlatformHandle = mainWindow.Handle;
|
||||
GCHandle handle = GCHandle.Alloc(mainWindow);
|
||||
mainViewport.PlatformUserData = (IntPtr)handle;
|
||||
AddWindow(mainWindow, mainViewport, handle);
|
||||
mainViewportWindow = new GuiViewportWindow(graphicsDevice, mainViewport, mainWindow);
|
||||
|
||||
unsafe
|
||||
{
|
||||
@ -177,7 +175,7 @@ private void UpdatePerFrameImGuiData(float deltaSeconds)
|
||||
io.DeltaTime = deltaSeconds; // DeltaTime is in seconds.
|
||||
}
|
||||
|
||||
private void UpdateInput()
|
||||
private static void UpdateInput()
|
||||
{
|
||||
ImGuiIOPtr io = ImGui.GetIO();
|
||||
|
||||
@ -242,7 +240,7 @@ private void UpdateInput()
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateCursor()
|
||||
private static void UpdateCursor()
|
||||
{
|
||||
ImGuiIOPtr io = ImGui.GetIO();
|
||||
|
||||
@ -255,7 +253,7 @@ private void UpdateCursor()
|
||||
|
||||
if (imGuiCursor == ImGuiMouseCursor.None || io.MouseDrawCursor)
|
||||
{
|
||||
SDL2.SDL.SDL_ShowCursor(0);
|
||||
_ = SDL2.SDL.SDL_ShowCursor(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -273,7 +271,7 @@ private void UpdateCursor()
|
||||
_ => SDL2.SDL.SDL_CreateSystemCursor(SDL2.SDL.SDL_SystemCursor.SDL_SYSTEM_CURSOR_ARROW),
|
||||
};
|
||||
SDL2.SDL.SDL_SetCursor(sdlCursor);
|
||||
SDL2.SDL.SDL_ShowCursor(1);
|
||||
_ = SDL2.SDL.SDL_ShowCursor(1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -318,9 +316,9 @@ public void Render()
|
||||
for (int i = 0; i < platformIO.Viewports.Size; i++)
|
||||
{
|
||||
ImGuiViewportPtr vp = platformIO.Viewports[i];
|
||||
Window window = (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
GuiViewportWindow window = (GuiViewportWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
|
||||
if (!window.Claimed)
|
||||
if (!window.Window.Claimed)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -328,7 +326,7 @@ public void Render()
|
||||
UpdateImGuiBuffers(vp.DrawData);
|
||||
|
||||
CommandBuffer commandBuffer = graphicsDevice.AcquireCommandBuffer();
|
||||
Texture swapchainTexture = commandBuffer.AcquireSwapchainTexture(window);
|
||||
Texture swapchainTexture = commandBuffer.AcquireSwapchainTexture(window.Window);
|
||||
|
||||
if (swapchainTexture != null)
|
||||
{
|
||||
@ -357,7 +355,7 @@ public void Render()
|
||||
{
|
||||
RenderCommandLists(commandBuffer, swapchainTexture, drawDataPtr);
|
||||
graphicsDevice.Submit(commandBuffer);
|
||||
graphicsDevice.Wait();
|
||||
//graphicsDevice.Wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -534,80 +532,33 @@ out int bytesPerPixel
|
||||
#region Window
|
||||
private void CreateWindow(ImGuiViewportPtr vp)
|
||||
{
|
||||
// TODO: Handle all flags.
|
||||
ScreenMode screenMode = vp.Flags.HasFlag(ImGuiViewportFlags.NoDecoration) ? ScreenMode.WindowedBorderless : ScreenMode.Windowed;
|
||||
bool systemResizable = !vp.Flags.HasFlag(ImGuiViewportFlags.NoDecoration);
|
||||
|
||||
WindowCreateInfo info = new WindowCreateInfo("Window Title", (uint)vp.Pos.X, (uint)vp.Pos.Y, screenMode, systemResizable, false);
|
||||
|
||||
Window window = new Window(graphicsDevice, info);
|
||||
graphicsDevice.ClaimWindow(window, SwapchainComposition.SDR, PresentMode.Immediate); // What PresentMode do we need?
|
||||
|
||||
GCHandle handle = GCHandle.Alloc(window);
|
||||
vp.PlatformUserData = (IntPtr)handle;
|
||||
|
||||
AddWindow(window, vp, handle);
|
||||
GuiViewportWindow window = new GuiViewportWindow(graphicsDevice, vp);
|
||||
}
|
||||
|
||||
private void DestroyWindow(ImGuiViewportPtr vp)
|
||||
{
|
||||
//Window window = (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
if (vp.PlatformUserData == IntPtr.Zero) return;
|
||||
|
||||
if(imguiToWindow.TryGetValue(vp, out Window window))
|
||||
{
|
||||
graphicsDevice.UnclaimWindow(window);
|
||||
GuiViewportWindow window = (GuiViewportWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
window.Dispose();
|
||||
|
||||
if (windowToHandle.TryGetValue(window, out GCHandle handle))
|
||||
{
|
||||
handle.Free();
|
||||
windowToHandle.Remove(window);
|
||||
}
|
||||
|
||||
imguiToWindow.Remove(vp);
|
||||
window.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddWindow(Window window, ImGuiViewportPtr vp, GCHandle handle)
|
||||
{
|
||||
window.OnResizedEvent += ((win, w, h) => {
|
||||
vp.PlatformRequestResize = true;
|
||||
});
|
||||
|
||||
window.OnMovedEvent += ((win, x, y) =>
|
||||
{
|
||||
vp.PlatformRequestMove = true;
|
||||
});
|
||||
|
||||
window.OnCloseEvent += (win) =>
|
||||
{
|
||||
ImGuiPlatformIOPtr platformIO = ImGui.GetPlatformIO();
|
||||
|
||||
for (int i = 0; i < platformIO.Viewports.Capacity; i++)
|
||||
{
|
||||
ImGuiViewportPtr vp = platformIO.Viewports[i];
|
||||
DestroyWindow(vp);
|
||||
}
|
||||
};
|
||||
|
||||
windowToHandle.Add(window, handle);
|
||||
imguiToWindow.Add(vp, window);
|
||||
vp.PlatformUserData = IntPtr.Zero;
|
||||
}
|
||||
|
||||
private void ShowWindow(ImGuiViewportPtr vp)
|
||||
{
|
||||
if (vp.PlatformUserData == IntPtr.Zero) return;
|
||||
|
||||
Window window = (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_ShowWindow(window.Handle);
|
||||
GuiViewportWindow window = (GuiViewportWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_ShowWindow(window.Window.Handle);
|
||||
}
|
||||
|
||||
private unsafe void GetWindowPos(ImGuiViewportPtr vp, Vector2* outPos)
|
||||
{
|
||||
if (vp.PlatformUserData == IntPtr.Zero) return;
|
||||
|
||||
Window window = (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_GetWindowPosition(window.Handle, out int x, out int y);
|
||||
GuiViewportWindow window = (GuiViewportWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_GetWindowPosition(window.Window.Handle, out int x, out int y);
|
||||
*outPos = new Vector2(x, y);
|
||||
}
|
||||
|
||||
@ -615,24 +566,24 @@ private void SetWindowPos(ImGuiViewportPtr vp, Vector2 pos)
|
||||
{
|
||||
if (vp.PlatformUserData == IntPtr.Zero) return;
|
||||
|
||||
Window window = (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_SetWindowPosition(window.Handle, (int)pos.X, (int)pos.Y);
|
||||
GuiViewportWindow window = (GuiViewportWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_SetWindowPosition(window.Window.Handle, (int)pos.X, (int)pos.Y);
|
||||
}
|
||||
|
||||
private void SetWindowSize(ImGuiViewportPtr vp, Vector2 size)
|
||||
{
|
||||
if (vp.PlatformUserData == IntPtr.Zero) return;
|
||||
|
||||
Window window = (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_SetWindowSize(window.Handle, (int)size.X, (int)size.Y);
|
||||
GuiViewportWindow window = (GuiViewportWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_SetWindowSize(window.Window.Handle, (int)size.X, (int)size.Y);
|
||||
}
|
||||
|
||||
private unsafe void GetWindowSize(ImGuiViewportPtr vp, Vector2* outSize)
|
||||
{
|
||||
if (vp.PlatformUserData == IntPtr.Zero) return;
|
||||
|
||||
Window window = (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_GetWindowSize(window.Handle, out int w, out int h);
|
||||
GuiViewportWindow window = (GuiViewportWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_GetWindowSize(window.Window.Handle, out int w, out int h);
|
||||
*outSize = new Vector2(w, h);
|
||||
}
|
||||
|
||||
@ -640,26 +591,28 @@ private void SetWindowFocus(ImGuiViewportPtr vp)
|
||||
{
|
||||
if (vp.PlatformUserData == IntPtr.Zero) return;
|
||||
|
||||
Window window = (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
GuiViewportWindow window = (GuiViewportWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
//SDL2.SDL.SDL_SetWindowInputFocus(window.Handle);
|
||||
SDL2.SDL.SDL_RaiseWindow(window.Handle);
|
||||
SDL2.SDL.SDL_RaiseWindow(window.Window.Handle);
|
||||
}
|
||||
|
||||
private byte GetWindowFocus(ImGuiViewportPtr vp)
|
||||
{
|
||||
if (vp.PlatformUserData == IntPtr.Zero) return (byte)0;
|
||||
|
||||
Window window = (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_WindowFlags flags = (SDL2.SDL.SDL_WindowFlags)SDL2.SDL.SDL_GetWindowFlags(window.Handle);
|
||||
GuiViewportWindow window = (GuiViewportWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_WindowFlags flags = (SDL2.SDL.SDL_WindowFlags)SDL2.SDL.SDL_GetWindowFlags(window.Window.Handle);
|
||||
|
||||
return (flags & SDL2.SDL.SDL_WindowFlags.SDL_WINDOW_INPUT_FOCUS) != 0 ? (byte)1 : (byte)0;
|
||||
}
|
||||
|
||||
private byte GetWindowMinimized(ImGuiViewportPtr vp)
|
||||
{
|
||||
if (vp.PlatformUserData == IntPtr.Zero) return (byte)0;
|
||||
if (vp.PlatformUserData == IntPtr.Zero) return 0;
|
||||
|
||||
GuiViewportWindow window = (GuiViewportWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_WindowFlags flags = (SDL2.SDL.SDL_WindowFlags)SDL2.SDL.SDL_GetWindowFlags(window.Window.Handle);
|
||||
|
||||
Window window = (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
SDL2.SDL.SDL_WindowFlags flags = (SDL2.SDL.SDL_WindowFlags)SDL2.SDL.SDL_GetWindowFlags(window.Handle);
|
||||
return (flags & SDL2.SDL.SDL_WindowFlags.SDL_WINDOW_MINIMIZED) != 0 ? (byte)1 : (byte)0;
|
||||
}
|
||||
|
||||
@ -667,14 +620,14 @@ private unsafe void SetWindowTitle(ImGuiViewportPtr vp, IntPtr title)
|
||||
{
|
||||
if (vp.PlatformUserData == IntPtr.Zero) return;
|
||||
|
||||
Window window = (Window)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
GuiViewportWindow window = (GuiViewportWindow)GCHandle.FromIntPtr(vp.PlatformUserData).Target;
|
||||
byte* titlePtr = (byte*)title;
|
||||
int count = 0;
|
||||
while (titlePtr[count] != 0)
|
||||
{
|
||||
count += 1;
|
||||
}
|
||||
SDL2.SDL.SDL_SetWindowTitle(window.Handle, System.Text.Encoding.ASCII.GetString(titlePtr, count));
|
||||
SDL2.SDL.SDL_SetWindowTitle(window.Window.Handle, System.Text.Encoding.ASCII.GetString(titlePtr, count));
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -688,16 +641,5 @@ public void Dispose()
|
||||
imGuiPipeline?.Dispose();
|
||||
imGuiSampler?.Dispose();
|
||||
resourceUploader?.Dispose();
|
||||
|
||||
foreach (KeyValuePair<Window, GCHandle> window in windowToHandle)
|
||||
{
|
||||
if (window.Key == mainWindow) continue;
|
||||
|
||||
graphicsDevice.UnclaimWindow(window.Key);
|
||||
window.Key.Dispose();
|
||||
window.Value.Free();
|
||||
}
|
||||
windowToHandle.Clear();
|
||||
imguiToWindow.Clear();
|
||||
}
|
||||
}
|
87
Nerfed.Runtime/Gui/GuiViewportWindow.cs
Normal file
87
Nerfed.Runtime/Gui/GuiViewportWindow.cs
Normal file
@ -0,0 +1,87 @@
|
||||
using ImGuiNET;
|
||||
using Nerfed.Runtime.Graphics;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Nerfed.Runtime.Gui
|
||||
{
|
||||
internal class GuiViewportWindow
|
||||
{
|
||||
private readonly GCHandle gcHandle;
|
||||
private readonly GraphicsDevice gd;
|
||||
private readonly ImGuiViewportPtr vp;
|
||||
private readonly Window window;
|
||||
|
||||
public Window Window => window;
|
||||
|
||||
public GuiViewportWindow(GraphicsDevice gd, ImGuiViewportPtr vp, Window window)
|
||||
{
|
||||
this.gd = gd;
|
||||
this.vp = vp;
|
||||
this.window = window;
|
||||
|
||||
gcHandle = GCHandle.Alloc(this);
|
||||
|
||||
if (!window.Claimed)
|
||||
{
|
||||
gd.ClaimWindow(window, SwapchainComposition.SDR, PresentMode.Immediate); // What PresentMode do we need?
|
||||
}
|
||||
|
||||
vp.PlatformUserData = (IntPtr)gcHandle;
|
||||
}
|
||||
|
||||
public GuiViewportWindow(GraphicsDevice gd, ImGuiViewportPtr vp)
|
||||
{
|
||||
this.gd = gd;
|
||||
this.vp = vp;
|
||||
|
||||
gcHandle = GCHandle.Alloc(this);
|
||||
|
||||
// TODO: Handle all flags.
|
||||
ScreenMode screenMode = ScreenMode.Windowed;
|
||||
bool systemResizable = true;
|
||||
|
||||
if ((vp.Flags & ImGuiViewportFlags.NoDecoration) == ImGuiViewportFlags.NoDecoration)
|
||||
{
|
||||
screenMode = ScreenMode.WindowedBorderless;
|
||||
systemResizable = false;
|
||||
}
|
||||
|
||||
WindowCreateInfo info = new WindowCreateInfo("Window Title", (uint)vp.Pos.X, (uint)vp.Pos.Y, screenMode, systemResizable, false);
|
||||
|
||||
window = new Window(gd, info);
|
||||
gd.ClaimWindow(window, SwapchainComposition.SDR, PresentMode.Immediate); // What PresentMode do we need?
|
||||
|
||||
window.OnMovedEvent += HandleOnMovedEvent;
|
||||
window.OnResizedEvent += HandleOnResizedEvent;
|
||||
window.OnCloseEvent += HandleOnCloseEvent;
|
||||
|
||||
vp.PlatformUserData = (IntPtr)gcHandle;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
window.OnMovedEvent -= HandleOnMovedEvent;
|
||||
window.OnResizedEvent -= HandleOnResizedEvent;
|
||||
window.OnCloseEvent -= HandleOnCloseEvent;
|
||||
|
||||
gd.UnclaimWindow(window);
|
||||
window.Dispose();
|
||||
gcHandle.Free();
|
||||
}
|
||||
|
||||
private void HandleOnMovedEvent(Window window, int x, int y)
|
||||
{
|
||||
vp.PlatformRequestMove = true;
|
||||
}
|
||||
|
||||
private void HandleOnResizedEvent(Window window, uint w, uint h)
|
||||
{
|
||||
vp.PlatformRequestResize = true;
|
||||
}
|
||||
|
||||
private void HandleOnCloseEvent(Window window)
|
||||
{
|
||||
vp.PlatformRequestClose = true;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user