From 6bfeffa49d450e7fc7b518e626a44c30549b32dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Mon, 16 Nov 2020 21:16:19 +0100 Subject: [PATCH] Fixed ImGui and added docking and viewport support --- BeefSpace.toml | 2 +- GlitchyEngine/BeefProj.toml | 3 +- GlitchyEngine/src/Application.bf | 8 ++ GlitchyEngine/src/ImGui/ImGuiLayer.bf | 101 +++++++++++--------- GlitchyEngine/src/ImGui/ImGuiRenderEvent.bf | 23 +++++ GlitchyEngine/src/Platform/DX11/DirectX.bf | 8 ++ GlitchyEngine/src/Program.bf | 2 +- Sandbox/BeefProj.toml | 3 + Sandbox/src/SandboxApp.bf | 13 +++ 9 files changed, 115 insertions(+), 48 deletions(-) create mode 100644 GlitchyEngine/src/ImGui/ImGuiRenderEvent.bf diff --git a/BeefSpace.toml b/BeefSpace.toml index 560156f..1e613e2 100644 --- a/BeefSpace.toml +++ b/BeefSpace.toml @@ -1,5 +1,5 @@ FileVersion = 1 -Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, imgui-beef = {Path = "GlitchyEngine/vendor/imgui-beef/imgui-beef"}, imgui-impl-win32 = {Path = "GlitchyEngine/vendor/imgui-beef/imgui-impl-win32"}, imgui-impl-dx11 = {Path = "GlitchyEngine/vendor/imgui-beef/imgui-impl-dx11"}} +Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, ImGui = {Path = "GlitchyEngine/vendor/imgui-beef/ImGui"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui-beef/ImGuiImplWin32"}, ImGuiImplDx11 = {Path = "GlitchyEngine/vendor/imgui-beef/ImGuiImplDX11"}} [Workspace] StartupProject = "Sandbox" diff --git a/GlitchyEngine/BeefProj.toml b/GlitchyEngine/BeefProj.toml index d8cbb75..a9efd7f 100644 --- a/GlitchyEngine/BeefProj.toml +++ b/GlitchyEngine/BeefProj.toml @@ -1,5 +1,5 @@ FileVersion = 1 -Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", imgui-beef = "*", imgui-impl-win32 = "*", imgui-impl-dx11 = "*"} +Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", ImGui = "*", ImGuiImplDx11 = "*", ImGuiImplWin32 = "*"} [Project] Name = "GlitchyEngine" @@ -8,6 +8,7 @@ Name = "GlitchyEngine" PreprocessorMacros = ["DEBUG", "GE_WINDOWS"] [Configs.Debug.Win64] +CLibType = "DynamicDebug" PreprocessorMacros = ["DEBUG", "GE_WINDOWS"] [Configs.Release.Win32] diff --git a/GlitchyEngine/src/Application.bf b/GlitchyEngine/src/Application.bf index a62d9b2..0690f31 100644 --- a/GlitchyEngine/src/Application.bf +++ b/GlitchyEngine/src/Application.bf @@ -2,6 +2,7 @@ using System; using GlitchyEngine.Events; using GlitchyEngine.Platform.Windows; using GlitchyEngine.Platform.DX11; +using GlitchyEngine.ImGui; namespace GlitchyEngine { @@ -14,6 +15,8 @@ namespace GlitchyEngine private LayerStack _layerStack = new LayerStack() ~ delete _; + private ImGuiLayer _imGuiLayer; + private GameTime _gameTime = new GameTime(true) ~ delete _; public bool IsRunning => _running; @@ -29,6 +32,9 @@ namespace GlitchyEngine _window = GlitchyEngine.Window.CreateWindow(WindowDescription()); _window.EventCallback = new => OnEvent; + + _imGuiLayer = new ImGuiLayer(); + PushLayer(_imGuiLayer); } public void OnEvent(Event e) @@ -59,6 +65,8 @@ namespace GlitchyEngine _window.Update(); + _imGuiLayer.ImGuiRender(); + DirectX.Present(); } } diff --git a/GlitchyEngine/src/ImGui/ImGuiLayer.bf b/GlitchyEngine/src/ImGui/ImGuiLayer.bf index c09073c..22d6e05 100644 --- a/GlitchyEngine/src/ImGui/ImGuiLayer.bf +++ b/GlitchyEngine/src/ImGui/ImGuiLayer.bf @@ -1,5 +1,5 @@ using System; -using imgui_beef; +using ImGui; using GlitchyEngine.Events; // Temporary @@ -18,41 +18,34 @@ namespace GlitchyEngine.ImGui ImGui.CHECKVERSION(); ImGui.CreateContext(); ImGui.StyleColorsDark(); - - ref ImGui.IO io = ref ImGui.GetIO(); - io.BackendFlags |= .HasMouseCursors | .HasSetMousePos; - // Todo: Temporary, needs own keymap - // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime. - io.KeyMap[(int32)ImGui.Key.Tab] = (int32)Key.Tab; - io.KeyMap[(int32)ImGui.Key.LeftArrow] = (int32)Key.Left; - io.KeyMap[(int32)ImGui.Key.RightArrow] = (int32)Key.Right; - io.KeyMap[(int32)ImGui.Key.UpArrow] = (int32)Key.Up; - io.KeyMap[(int32)ImGui.Key.DownArrow] = (int32)Key.Down; - io.KeyMap[(int32)ImGui.Key.PageUp] = (int32)Key.Prior; - io.KeyMap[(int32)ImGui.Key.PageDown] = (int32)Key.Next; - io.KeyMap[(int32)ImGui.Key.Home] = (int32)Key.Home; - io.KeyMap[(int32)ImGui.Key.End] = (int32)Key.End; - io.KeyMap[(int32)ImGui.Key.Insert] = (int32)Key.Insert; - io.KeyMap[(int32)ImGui.Key.Delete] = (int32)Key.Delete; - io.KeyMap[(int32)ImGui.Key.Backspace] = (int32)Key.Backspace; - io.KeyMap[(int32)ImGui.Key.Space] = (int32)Key.Space; - io.KeyMap[(int32)ImGui.Key.Enter] = (int32)Key.Return; - io.KeyMap[(int32)ImGui.Key.Escape] = (int32)Key.Escape; - io.KeyMap[(int32)ImGui.Key.KeyPadEnter] = (int32)Key.Return; - io.KeyMap[(int32)ImGui.Key.A] = (int32)(int32)Key.A; - io.KeyMap[(int32)ImGui.Key.C] = (int32)(int32)Key.C; - io.KeyMap[(int32)ImGui.Key.V] = (int32)(int32)Key.V; - io.KeyMap[(int32)ImGui.Key.X] = (int32)(int32)Key.X; - io.KeyMap[(int32)ImGui.Key.Y] = (int32)(int32)Key.Y; - io.KeyMap[(int32)ImGui.Key.Z] = (int32)(int32)Key.Z; - - // Todo: temporary, needs to be platform independant - ImGuiImplDx11.Init(Platform.DX11.DirectX.Device, Platform.DX11.DirectX.ImmediateContext); + ref ImGui.IO io = ref ImGui.GetIO(); + io.ConfigFlags |= .NavEnableKeyboard; + io.ConfigFlags |= .DockingEnable; + io.ConfigFlags |= .ViewportsEnable; + + ref ImGui.Style style = ref ImGui.GetStyle(); + + if(io.ConfigFlags.HasFlag(.ViewportsEnable)) + { + style.WindowRounding = 0.0f; + style.Colors[(int)ImGui.Col.WindowBg].w = 1.0f; + } + + //ImGui.Dock + +#if GE_WINDOWS + // Todo: temporary, needs to be platform independent + ImGuiImplDX11.Init(Platform.DX11.DirectX.Device, Platform.DX11.DirectX.ImmediateContext); + ImGuiImplWin32.Init((Windows.HWnd)(int)Application.Get().Window.NativeWindow); +#endif } public override void OnDetach() { + ImGuiImplDX11.Shutdown(); + ImGuiImplWin32.Shutdown(); + ImGui.DestroyContext(); } public override void OnEvent(Event event) @@ -61,9 +54,9 @@ namespace GlitchyEngine.ImGui dispatcher.Dispatch(scope (e) => { - ref ImGui.IO io = ref ImGui.GetIO(); - io.DisplaySize = .(e.Width, e.Height); - io.DisplayFramebufferScale = .(1.0f, 1.0f); + //ref ImGui.IO io = ref ImGui.GetIO(); + //io.DisplaySize = .(e.Width, e.Height); + //io.DisplayFramebufferScale = .(1.0f, 1.0f); return false; }); @@ -150,32 +143,50 @@ namespace GlitchyEngine.ImGui dispatcher.Dispatch(scope (e) => { ref ImGui.IO io = ref ImGui.GetIO(); - io.AddInputCharacterUTF16((int16)e.Char); + io.AddInputCharacterUTF16((uint16)e.Char); return false; }); } - bool showDemo = true; - public override void Update(GameTime gameTime) + public void Begin() { var v = DirectX.ImmediateContext; - v.OutputMerger.SetRenderTargets(1, &DirectX.BackBufferTarget, null); + + ImGuiImplDX11.NewFrame(); + ImGuiImplWin32.NewFrame(); + ImGui.NewFrame(); + } + bool showDemo = true; + public void ImGuiRender() + { + Begin(); + + var event = scope ImGuiRenderEvent(); + Application.Get().OnEvent(event); + + ImGui.ShowDemoWindow(&showDemo); + + End(); + } + + public void End() + { ref ImGui.IO io = ref ImGui.GetIO(); let window = Application.Get().Window; io.DisplaySize = .(window.Width, window.Height); - io.DeltaTime = (float)gameTime.FrameTime.TotalSeconds; - - ImGuiImplDx11.NewFrame(); - ImGui.NewFrame(); - - ImGui.ShowDemoWindow(&showDemo); ImGui.Render(); - ImGuiImplDx11.RenderDrawData(ImGui.GetDrawData()); + ImGuiImplDX11.RenderDrawData(ref ImGui.GetDrawData()); + + if(io.ConfigFlags.HasFlag(.ViewportsEnable)) + { + ImGui.UpdatePlatformWindows(); + ImGui.RenderPlatformWindowsDefault(); + } } } } diff --git a/GlitchyEngine/src/ImGui/ImGuiRenderEvent.bf b/GlitchyEngine/src/ImGui/ImGuiRenderEvent.bf new file mode 100644 index 0000000..d706b47 --- /dev/null +++ b/GlitchyEngine/src/ImGui/ImGuiRenderEvent.bf @@ -0,0 +1,23 @@ +using GlitchyEngine.Events; + +namespace GlitchyEngine.Events +{ + extension EventType + { + case ImGuiRender; + } +} + +namespace GlitchyEngine.ImGui +{ + public class ImGuiRenderEvent : Event, IEvent + { + public override EventType EventType => .ImGuiRender; + + public override EventCategory Category => .Application; + + public override System.StringView Name => "ImGuiRender"; + + public static EventType StaticType => .ImGuiRender; + } +} diff --git a/GlitchyEngine/src/Platform/DX11/DirectX.bf b/GlitchyEngine/src/Platform/DX11/DirectX.bf index caa261c..f554e83 100644 --- a/GlitchyEngine/src/Platform/DX11/DirectX.bf +++ b/GlitchyEngine/src/Platform/DX11/DirectX.bf @@ -59,11 +59,19 @@ namespace GlitchyEngine.Platform.DX11 Log.EngineLogger.Trace("D3D11 Device and Context created (Feature level: {})", deviceLevel); } + static uint32 _width, _height; + /** * Initializes the swapchain. */ public static void UpdateSwapchain(uint32 width, uint32 height) { + if(_width == width && _height == height) + return; + + _width = width; + _height = height; + Log.EngineLogger.Trace("Updating swap chain ({}, {})", width, height); uint32 backBufferCount = 2; diff --git a/GlitchyEngine/src/Program.bf b/GlitchyEngine/src/Program.bf index 37012c1..a2c792d 100644 --- a/GlitchyEngine/src/Program.bf +++ b/GlitchyEngine/src/Program.bf @@ -3,7 +3,7 @@ using GlitchLog; using System.Diagnostics; using GlitchyEngine.Platform.Windows; -using imgui_beef; +//using imgui_beef; namespace GlitchyEngine { diff --git a/Sandbox/BeefProj.toml b/Sandbox/BeefProj.toml index 329a7fd..1d2c71d 100644 --- a/Sandbox/BeefProj.toml +++ b/Sandbox/BeefProj.toml @@ -5,3 +5,6 @@ Dependencies = {GlitchyEngine = "*", corlib = "*"} Name = "Sandbox" TargetType = "BeefGUIApplication" StartupObject = "GlitchyEngine.Program" + +[Configs.Debug.Win64] +CLibType = "DynamicDebug" diff --git a/Sandbox/src/SandboxApp.bf b/Sandbox/src/SandboxApp.bf index 07c7331..1e5d7e7 100644 --- a/Sandbox/src/SandboxApp.bf +++ b/Sandbox/src/SandboxApp.bf @@ -21,6 +21,19 @@ namespace Sandbox public override void OnEvent(Event event) { Log.ClientLogger.Trace("{}", event); + + EventDispatcher dispatcher = scope EventDispatcher(event); + + dispatcher.Dispatch(scope (e) => OnImGuiRender(e)); + } + + private bool OnImGuiRender(ImGuiRenderEvent e) + { + ImGui.ImGui.Begin("Test"); + + ImGui.ImGui.End(); + + return false; } }