mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 13:01:52 +00:00
Added ImGui
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
[submodule "vendor/directx"]
|
[submodule "vendor/directx"]
|
||||||
path = GlitchyEngine/vendor/directx
|
path = GlitchyEngine/vendor/directx
|
||||||
url = https://github.com/aharabada/directx-beef.git
|
url = https://github.com/aharabada/directx-beef.git
|
||||||
|
[submodule "GlitchyEngine/vendor/imgui-beef"]
|
||||||
|
path = GlitchyEngine/vendor/imgui-beef
|
||||||
|
url = https://github.com/qzole/imgui-beef.git
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "vendor/directx/DirectX"}}
|
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"}}
|
||||||
|
|
||||||
[Workspace]
|
[Workspace]
|
||||||
StartupProject = "Sandbox"
|
StartupProject = "Sandbox"
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ namespace GlitchLog
|
|||||||
Runtime.Assert(Debug.IsDebuggerPresent, "The DebugLogger requires a debugger to be present.");
|
Runtime.Assert(Debug.IsDebuggerPresent, "The DebugLogger requires a debugger to be present.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if GL_NOLOG || GL_NOTRACE
|
#if GL_NOLOG || GL_NOTRACE
|
||||||
[SkipCall]
|
[SkipCall]
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*"}
|
Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", imgui-beef = "*", imgui-impl-win32 = "*", imgui-impl-dx11 = "*"}
|
||||||
|
|
||||||
[Project]
|
[Project]
|
||||||
Name = "GlitchyEngine"
|
Name = "GlitchyEngine"
|
||||||
|
|||||||
@@ -1,20 +1,33 @@
|
|||||||
|
using System;
|
||||||
using GlitchyEngine.Events;
|
using GlitchyEngine.Events;
|
||||||
using GlitchyEngine.Platform.Windows;
|
using GlitchyEngine.Platform.Windows;
|
||||||
|
using GlitchyEngine.Platform.DX11;
|
||||||
|
|
||||||
namespace GlitchyEngine
|
namespace GlitchyEngine
|
||||||
{
|
{
|
||||||
public class Application
|
public class Application
|
||||||
{
|
{
|
||||||
|
static Application s_Instance = null;
|
||||||
|
|
||||||
private Window _window ~ delete _;
|
private Window _window ~ delete _;
|
||||||
private bool _running = true;
|
private bool _running = true;
|
||||||
|
|
||||||
private LayerStack _layerStack = new LayerStack() ~ delete _;
|
private LayerStack _layerStack = new LayerStack() ~ delete _;
|
||||||
|
|
||||||
|
private GameTime _gameTime = new GameTime(true) ~ delete _;
|
||||||
|
|
||||||
public bool IsRunning => _running;
|
public bool IsRunning => _running;
|
||||||
|
public Window Window => _window;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public static Application Get => s_Instance;
|
||||||
|
|
||||||
public this()
|
public this()
|
||||||
{
|
{
|
||||||
_window = Window.CreateWindow(WindowDescription());
|
Runtime.Assert(s_Instance == null, "Tried to create a second application.");
|
||||||
|
s_Instance = this;
|
||||||
|
|
||||||
|
_window = GlitchyEngine.Window.CreateWindow(WindowDescription());
|
||||||
_window.EventCallback = new => OnEvent;
|
_window.EventCallback = new => OnEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,10 +48,16 @@ namespace GlitchyEngine
|
|||||||
{
|
{
|
||||||
while(_running)
|
while(_running)
|
||||||
{
|
{
|
||||||
|
DirectX.ImmediateContext.ClearRenderTargetView(DirectX.BackBufferTarget, .(1, 0, 1));
|
||||||
|
|
||||||
|
_gameTime.Tick();
|
||||||
|
|
||||||
for(Layer layer in _layerStack)
|
for(Layer layer in _layerStack)
|
||||||
layer.Update();
|
layer.Update(_gameTime);
|
||||||
|
|
||||||
_window.Update();
|
_window.Update();
|
||||||
|
|
||||||
|
DirectX.Present();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ namespace GlitchyEngine.Events
|
|||||||
|
|
||||||
public class WindowResizeEvent : Event, IEvent
|
public class WindowResizeEvent : Event, IEvent
|
||||||
{
|
{
|
||||||
public int32 _width, _height;
|
private int32 _width, _height;
|
||||||
public bool _isResizing;
|
private bool _isResizing;
|
||||||
|
|
||||||
/// The new width of the window.
|
/// The new width of the window.
|
||||||
public int32 Width = _width;
|
public int32 Width = _width;
|
||||||
@@ -57,8 +57,8 @@ namespace GlitchyEngine.Events
|
|||||||
|
|
||||||
public class WindowMoveEvent : Event, IEvent
|
public class WindowMoveEvent : Event, IEvent
|
||||||
{
|
{
|
||||||
public int32 _x, _y;
|
private int32 _x, _y;
|
||||||
public bool _isMoving;
|
private bool _isMoving;
|
||||||
|
|
||||||
/// The new x-coordinate of the window.
|
/// The new x-coordinate of the window.
|
||||||
public int32 X = _x;
|
public int32 X = _x;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace GlitchyEngine.Events
|
|||||||
None = 0,
|
None = 0,
|
||||||
WindowClose, WindowResize, WindowFocus, WindowLostFocus, WindowMoved,
|
WindowClose, WindowResize, WindowFocus, WindowLostFocus, WindowMoved,
|
||||||
AppTick, AppUpdate, AppRender,
|
AppTick, AppUpdate, AppRender,
|
||||||
KeyPressed, KeyReleased,
|
KeyPressed, KeyReleased, KeyTyped,
|
||||||
MouseButtonPressed, MouseButtonReleased, MouseMoved, MouseScrolled
|
MouseButtonPressed, MouseButtonReleased, MouseMoved, MouseScrolled
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,4 +53,29 @@ namespace GlitchyEngine.Events
|
|||||||
strBuffer.AppendF("KeyReleasedEvent: {}", _keyCode);
|
strBuffer.AppendF("KeyReleasedEvent: {}", _keyCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class KeyTypedEvent : Event, IEvent
|
||||||
|
{
|
||||||
|
private char16 _char;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public char16 Char => _char;
|
||||||
|
|
||||||
|
public override EventCategory Category => .Input | .Keyboard
|
||||||
|
|
||||||
|
public override EventType EventType => .KeyTyped;
|
||||||
|
public static EventType StaticType => .KeyTyped;
|
||||||
|
|
||||||
|
public override StringView Name => "KeyTyped";
|
||||||
|
|
||||||
|
public this(char16 char)
|
||||||
|
{
|
||||||
|
_char = char;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ToString(String strBuffer)
|
||||||
|
{
|
||||||
|
strBuffer.AppendF("KeyTypedEvent: {}", _char);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,90 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace GlitchyEngine
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A timer providing functionality to meassure frame times and game runtime.
|
||||||
|
*/
|
||||||
|
public class GameTime : Stopwatch
|
||||||
|
{
|
||||||
|
private uint64 _frameCount;
|
||||||
|
|
||||||
|
private TimeSpan _totalTime;
|
||||||
|
private TimeSpan _frameTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
The amount of time that has passed since the timer was started.
|
||||||
|
*/
|
||||||
|
public TimeSpan TotalTime => _totalTime;
|
||||||
|
/**
|
||||||
|
The amount of time that has passed since the start of the last frame.
|
||||||
|
*/
|
||||||
|
public TimeSpan FrameTime => _frameTime;
|
||||||
|
/**
|
||||||
|
The number of frames that have been computed since the timer was started.
|
||||||
|
*/
|
||||||
|
public uint64 FrameCount => _frameCount;
|
||||||
|
|
||||||
|
private Stopwatch _stopWatch ~ delete _;
|
||||||
|
|
||||||
|
public this() : base(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes a new instance of a GameTime.
|
||||||
|
* @param startNow If set to true, the timer will start immediately.
|
||||||
|
* If set to false, the timer has to be started manually.
|
||||||
|
*/
|
||||||
|
public this(bool startNow) : base(startNow){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts or continues the internal timer.
|
||||||
|
*/
|
||||||
|
public new void Start()
|
||||||
|
{
|
||||||
|
_stopWatch.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restarts the internal timer and resets the counters.
|
||||||
|
*/
|
||||||
|
public new void Restart()
|
||||||
|
{
|
||||||
|
_totalTime = 0;
|
||||||
|
_frameTime = 0;
|
||||||
|
_frameCount = 0;
|
||||||
|
base.Restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops the internal timer.
|
||||||
|
*/
|
||||||
|
public new void Stop()
|
||||||
|
{
|
||||||
|
base.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the timer.
|
||||||
|
*/
|
||||||
|
public new void Reset()
|
||||||
|
{
|
||||||
|
_totalTime = 0;
|
||||||
|
_frameTime = 0;
|
||||||
|
_frameCount = 0;
|
||||||
|
base.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells the timer that a frame has passed and updates the counters.
|
||||||
|
*/
|
||||||
|
public void Tick()
|
||||||
|
{
|
||||||
|
TimeSpan old = _totalTime;
|
||||||
|
_totalTime = Elapsed;
|
||||||
|
_frameTime = _totalTime - old;
|
||||||
|
|
||||||
|
_frameCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,182 @@
|
|||||||
|
using System;
|
||||||
|
using imgui_beef;
|
||||||
|
using GlitchyEngine.Events;
|
||||||
|
|
||||||
|
// Temporary
|
||||||
|
using DirectX.Windows.VirtualKeyCodes;
|
||||||
|
using GlitchyEngine.Platform.DX11;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.ImGui
|
||||||
|
{
|
||||||
|
public class ImGuiLayer : Layer
|
||||||
|
{
|
||||||
|
public this() : base("ImGuiLayer") { }
|
||||||
|
|
||||||
|
public override void OnAttach()
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Trace("Initializing 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] = VK_TAB;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.LeftArrow] = VK_LEFT;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.RightArrow] = VK_RIGHT;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.UpArrow] = VK_UP;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.DownArrow] = VK_DOWN;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.PageUp] = VK_PRIOR;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.PageDown] = VK_NEXT;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.Home] = VK_HOME;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.End] = VK_END;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.Insert] = VK_INSERT;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.Delete] = VK_DELETE;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.Backspace] = VK_BACK;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.Space] = VK_SPACE;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.Enter] = VK_RETURN;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.Escape] = VK_ESCAPE;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.KeyPadEnter] = VK_RETURN;
|
||||||
|
io.KeyMap[(int32)ImGui.Key.A] = (int32)'A';
|
||||||
|
io.KeyMap[(int32)ImGui.Key.C] = (int32)'C';
|
||||||
|
io.KeyMap[(int32)ImGui.Key.V] = (int32)'V';
|
||||||
|
io.KeyMap[(int32)ImGui.Key.X] = (int32)'X';
|
||||||
|
io.KeyMap[(int32)ImGui.Key.Y] = (int32)'Y';
|
||||||
|
io.KeyMap[(int32)ImGui.Key.Z] = (int32)'Z';
|
||||||
|
|
||||||
|
// Todo: temporary, needs to be platform independant
|
||||||
|
ImGuiImplDx11.Init(Platform.DX11.DirectX.Device, Platform.DX11.DirectX.ImmediateContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnDetach()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void OnEvent(Event event)
|
||||||
|
{
|
||||||
|
EventDispatcher dispatcher = scope EventDispatcher(event);
|
||||||
|
|
||||||
|
dispatcher.Dispatch<WindowResizeEvent>(scope (e) =>
|
||||||
|
{
|
||||||
|
ref ImGui.IO io = ref ImGui.GetIO();
|
||||||
|
io.DisplaySize = .(e.Width, e.Height);
|
||||||
|
io.DisplayFramebufferScale = .(1.0f, 1.0f);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatcher.Dispatch<MouseMovedEvent>(scope (e) =>
|
||||||
|
{
|
||||||
|
ref ImGui.IO io = ref ImGui.GetIO();
|
||||||
|
io.MousePos = ImGui.Vec2(e.PositionX, e.PositionY);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatcher.Dispatch<MouseButtonPressedEvent>(scope (e) =>
|
||||||
|
{
|
||||||
|
ref ImGui.IO io = ref ImGui.GetIO();
|
||||||
|
|
||||||
|
switch(e.MouseButton)
|
||||||
|
{
|
||||||
|
case .LeftButton:
|
||||||
|
io.MouseDown[(uint)ImGui.MouseButton.Left] = true;
|
||||||
|
case .RightButton:
|
||||||
|
io.MouseDown[(uint)ImGui.MouseButton.Right] = true;
|
||||||
|
case .MiddleButton:
|
||||||
|
io.MouseDown[(uint)ImGui.MouseButton.Middle] = true;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatcher.Dispatch<MouseButtonReleasedEvent>(scope (e) =>
|
||||||
|
{
|
||||||
|
ref ImGui.IO io = ref ImGui.GetIO();
|
||||||
|
|
||||||
|
switch(e.MouseButton)
|
||||||
|
{
|
||||||
|
case .LeftButton:
|
||||||
|
io.MouseDown[(uint)ImGui.MouseButton.Left] = false;
|
||||||
|
case .RightButton:
|
||||||
|
io.MouseDown[(uint)ImGui.MouseButton.Right] = false;
|
||||||
|
case .MiddleButton:
|
||||||
|
io.MouseDown[(uint)ImGui.MouseButton.Middle] = false;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatcher.Dispatch<MouseScrolledEvent>(scope (e) =>
|
||||||
|
{
|
||||||
|
ref ImGui.IO io = ref ImGui.GetIO();
|
||||||
|
io.MouseWheel += e.YOffset;
|
||||||
|
io.MouseWheelH += e.XOffset; // Todo: horizontal mousewheel inverted?!
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatcher.Dispatch<KeyPressedEvent>(scope (e) =>
|
||||||
|
{
|
||||||
|
ref ImGui.IO io = ref ImGui.GetIO();
|
||||||
|
io.KeysDown[e.KeyCode] = true;
|
||||||
|
|
||||||
|
io.KeyCtrl = io.KeysDown[VK_CONTROL];
|
||||||
|
io.KeyShift = io.KeysDown[VK_SHIFT];
|
||||||
|
io.KeyAlt = io.KeysDown[VK_MENU];
|
||||||
|
io.KeySuper = io.KeysDown[VK_LWIN] || io.KeysDown[VK_RWIN];
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatcher.Dispatch<KeyReleasedEvent>(scope (e) =>
|
||||||
|
{
|
||||||
|
ref ImGui.IO io = ref ImGui.GetIO();
|
||||||
|
io.KeysDown[e.KeyCode] = false;
|
||||||
|
|
||||||
|
io.KeyCtrl = io.KeysDown[VK_CONTROL];
|
||||||
|
io.KeyShift = io.KeysDown[VK_SHIFT];
|
||||||
|
io.KeyAlt = io.KeysDown[VK_MENU];
|
||||||
|
io.KeySuper = io.KeysDown[VK_LWIN] || io.KeysDown[VK_RWIN];
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
dispatcher.Dispatch<KeyTypedEvent>(scope (e) =>
|
||||||
|
{
|
||||||
|
ref ImGui.IO io = ref ImGui.GetIO();
|
||||||
|
io.AddInputCharacterUTF16((int16)e.Char);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool showDemo = true;
|
||||||
|
public override void Update(GameTime gameTime)
|
||||||
|
{
|
||||||
|
var v = DirectX.ImmediateContext;
|
||||||
|
|
||||||
|
v.OutputMerger.SetRenderTargets(1, &DirectX.BackBufferTarget, null);
|
||||||
|
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,21 +5,22 @@ namespace GlitchyEngine
|
|||||||
{
|
{
|
||||||
public abstract class Layer
|
public abstract class Layer
|
||||||
{
|
{
|
||||||
protected String _debugName;
|
protected String _debugName ~ delete _;
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public StringView Name => _debugName;
|
public StringView Name => _debugName;
|
||||||
|
|
||||||
[AllowAppend]
|
//[AllowAppend]
|
||||||
public this(StringView name = "Layer")
|
public this(StringView name = "Layer")
|
||||||
{
|
{
|
||||||
String debugName = append String(name);
|
//String debugName = append String(name);
|
||||||
_debugName = debugName;
|
//_debugName = debugName;
|
||||||
|
_debugName = new String(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void OnAttach() { }
|
public virtual void OnAttach() { }
|
||||||
public virtual void OnDetach() { }
|
public virtual void OnDetach() { }
|
||||||
public virtual void Update() { }
|
public virtual void Update(GameTime gameTime) { }
|
||||||
public virtual void OnEvent(Event event) { }
|
public virtual void OnEvent(Event event) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ namespace GlitchyEngine
|
|||||||
public void PushLayer(Layer ownLayer)
|
public void PushLayer(Layer ownLayer)
|
||||||
{
|
{
|
||||||
_layers.Insert(_insertIndex++, ownLayer);
|
_layers.Insert(_insertIndex++, ownLayer);
|
||||||
|
ownLayer.OnAttach();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,6 +31,7 @@ namespace GlitchyEngine
|
|||||||
public void PushOverlay(Layer ownOverlay)
|
public void PushOverlay(Layer ownOverlay)
|
||||||
{
|
{
|
||||||
_layers.Add(ownOverlay);
|
_layers.Add(ownOverlay);
|
||||||
|
ownOverlay.OnAttach();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,6 +43,7 @@ namespace GlitchyEngine
|
|||||||
if(_layers.Remove(layer))
|
if(_layers.Remove(layer))
|
||||||
{
|
{
|
||||||
_insertIndex--;
|
_insertIndex--;
|
||||||
|
layer.OnDetach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +53,10 @@ namespace GlitchyEngine
|
|||||||
*/
|
*/
|
||||||
public void PopOverlay(Layer overlay)
|
public void PopOverlay(Layer overlay)
|
||||||
{
|
{
|
||||||
_layers.Remove(overlay);
|
if(_layers.Remove(overlay))
|
||||||
|
{
|
||||||
|
overlay.OnDetach();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,128 @@
|
|||||||
|
using System;
|
||||||
|
using DirectX;
|
||||||
|
using DirectX.D3D11;
|
||||||
|
using DirectX.Common;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using DirectX.DXGI;
|
||||||
|
using DirectX.DXGI.DXGI1_2;
|
||||||
|
using static System.Windows;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Platform.DX11
|
||||||
|
{
|
||||||
|
public static class DirectX
|
||||||
|
{
|
||||||
|
public static ID3D11Device* Device;
|
||||||
|
public static ID3D11DeviceContext* ImmediateContext;
|
||||||
|
|
||||||
|
public static IDXGIDevice* DxgiDevice;
|
||||||
|
public static IDXGISwapChain1* SwapChain;
|
||||||
|
|
||||||
|
public static ID3D11RenderTargetView* BackBufferTarget;
|
||||||
|
public static Viewport BackBufferViewport;
|
||||||
|
|
||||||
|
static HWnd _windowHandle;
|
||||||
|
|
||||||
|
static ~this()
|
||||||
|
{
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Init(HWnd windowHandle, uint32 width, uint32 height)
|
||||||
|
{
|
||||||
|
_windowHandle = windowHandle;
|
||||||
|
|
||||||
|
InitDevice();
|
||||||
|
UpdateSwapchain(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the Device and ImmediateContext.
|
||||||
|
*/
|
||||||
|
static void InitDevice()
|
||||||
|
{
|
||||||
|
IUnknown.ReleaseAndNull!(ref Device);
|
||||||
|
IUnknown.ReleaseAndNull!(ref ImmediateContext);
|
||||||
|
|
||||||
|
Log.EngineLogger.Trace("Creating D3D11 Device and Context...");
|
||||||
|
|
||||||
|
DeviceCreationFlags deviceFlags = .None;
|
||||||
|
#if DEBUG
|
||||||
|
deviceFlags |= .Debug;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FeatureLevel[] levels = scope .(.Level_11_0);
|
||||||
|
|
||||||
|
FeatureLevel deviceLevel = ?;
|
||||||
|
var deviceResult = D3D11.CreateDevice(null, .Hardware, 0, deviceFlags, levels, &Device, &deviceLevel, &ImmediateContext);
|
||||||
|
Debug.Assert(deviceResult.Succeeded, scope $"Failed to create D3D11 Device. Message(0x{(int32)deviceResult}): {deviceResult}");
|
||||||
|
|
||||||
|
Log.EngineLogger.Trace("D3D11 Device and Context created (Feature level: {})", deviceLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the swapchain.
|
||||||
|
*/
|
||||||
|
public static void UpdateSwapchain(uint32 width, uint32 height)
|
||||||
|
{
|
||||||
|
uint32 backBufferCount = 2;
|
||||||
|
Format backBufferFormat = .R8G8B8A8_UNorm;
|
||||||
|
Format backBufferViewFormat = .R8G8B8A8_UNorm; // _SRGB
|
||||||
|
|
||||||
|
if(SwapChain != null)
|
||||||
|
{
|
||||||
|
BackBufferTarget.Release();
|
||||||
|
|
||||||
|
SwapChain.ResizeBuffers(backBufferCount, width, height, backBufferFormat, .None);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Device.QueryInterface(out DxgiDevice);
|
||||||
|
|
||||||
|
DxgiDevice.GetAdapter(let adapter);
|
||||||
|
adapter.GetParent<IDXGIFactory2>(let factory);
|
||||||
|
adapter.Release();
|
||||||
|
|
||||||
|
SwapChainDescription1 swDesc = .();
|
||||||
|
swDesc.Width = width;
|
||||||
|
swDesc.Height = height;
|
||||||
|
swDesc.Format = backBufferFormat;
|
||||||
|
swDesc.SampleDescription = .(1, 0);
|
||||||
|
swDesc.BufferUsage = .RenderTargetOutput;
|
||||||
|
swDesc.BufferCount = backBufferCount;
|
||||||
|
swDesc.SwapEffect = .FlipDiscard;
|
||||||
|
|
||||||
|
SwapChainFullscreenDescription fsSwapChainDesc = .();
|
||||||
|
fsSwapChainDesc.Windowed = true;
|
||||||
|
|
||||||
|
factory.CreateSwapChainForHwnd((.)Device, _windowHandle, ref swDesc, &fsSwapChainDesc, null, &SwapChain);
|
||||||
|
|
||||||
|
factory.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
SwapChain.GetBuffer<ID3D11Texture2D>(0, let backBuffer);
|
||||||
|
|
||||||
|
RenderTargetViewDescription rtvDesc = .(backBuffer, .Texture2D, backBufferViewFormat);
|
||||||
|
Device.CreateRenderTargetView(backBuffer, &rtvDesc, &BackBufferTarget);
|
||||||
|
|
||||||
|
BackBufferViewport = Viewport(0, 0, width, height, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
backBuffer.Release();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Shutdown()
|
||||||
|
{
|
||||||
|
IUnknown.ReleaseAndNull!(ref Device);
|
||||||
|
IUnknown.ReleaseAndNull!(ref ImmediateContext);
|
||||||
|
|
||||||
|
IUnknown.ReleaseAndNull!(ref DxgiDevice);
|
||||||
|
IUnknown.ReleaseAndNull!(ref SwapChain);
|
||||||
|
|
||||||
|
IUnknown.ReleaseAndNull!(ref BackBufferTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Present()
|
||||||
|
{
|
||||||
|
SwapChain.Present(Application.Get.Window.IsVSync ? 1 : 0, .None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,9 @@ using DirectX.Windows.Kernel32;
|
|||||||
using DirectX.Windows.WindowMessages;
|
using DirectX.Windows.WindowMessages;
|
||||||
using GlitchyEngine.Events;
|
using GlitchyEngine.Events;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using imgui_beef;
|
||||||
|
using GlitchyEngine.Platform.DX11;
|
||||||
|
using static System.Windows;
|
||||||
|
|
||||||
namespace GlitchyEngine.Platform.Windows
|
namespace GlitchyEngine.Platform.Windows
|
||||||
{
|
{
|
||||||
@@ -22,6 +25,8 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
|
|
||||||
private String _title ~ delete _;
|
private String _title ~ delete _;
|
||||||
|
|
||||||
|
private bool _isVSync = true;
|
||||||
|
|
||||||
public override int32 MinWidth
|
public override int32 MinWidth
|
||||||
{
|
{
|
||||||
get => _minMaxInfo.MinimumTrackingSize.x;
|
get => _minMaxInfo.MinimumTrackingSize.x;
|
||||||
@@ -93,7 +98,7 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if(_title == null)
|
if (_title == null)
|
||||||
LoadTitle();
|
LoadTitle();
|
||||||
|
|
||||||
return _title;
|
return _title;
|
||||||
@@ -104,8 +109,8 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
|
|
||||||
public override bool IsVSync
|
public override bool IsVSync
|
||||||
{
|
{
|
||||||
get;
|
get => _isVSync;
|
||||||
set;
|
set => _isVSync = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GE_WINDOWS
|
#if GE_WINDOWS
|
||||||
@@ -135,7 +140,7 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
_windowClass.WindowProcedure = => MessageHandler;
|
_windowClass.WindowProcedure = => MessageHandler;
|
||||||
_windowClass.HInstance = (.)_instanceHandle;
|
_windowClass.HInstance = (.)_instanceHandle;
|
||||||
|
|
||||||
if(desc.Icon.Ptr != null)
|
if (desc.Icon.Ptr != null)
|
||||||
_windowClass.Icon = LoadImageW(0, desc.Icon.ToScopedNativeWChar!(), .Icon, 0, 0, .LoadFromFile);
|
_windowClass.Icon = LoadImageW(0, desc.Icon.ToScopedNativeWChar!(), .Icon, 0, 0, .LoadFromFile);
|
||||||
else
|
else
|
||||||
_windowClass.Icon = 0;
|
_windowClass.Icon = 0;
|
||||||
@@ -144,7 +149,7 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
_windowClass.BackgroundBrush = (HBRUSH)SystemColor.WindowFrame;
|
_windowClass.BackgroundBrush = (HBRUSH)SystemColor.WindowFrame;
|
||||||
_windowClass.ClassName = "GlitchyEngineWindow".ToScopedNativeWChar!();
|
_windowClass.ClassName = "GlitchyEngineWindow".ToScopedNativeWChar!();
|
||||||
|
|
||||||
if(RegisterClassExW(ref _windowClass) == 0)
|
if (RegisterClassExW(ref _windowClass) == 0)
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Error("Failed to register window class.", (HResult)GetLastError());
|
Log.EngineLogger.Error("Failed to register window class.", (HResult)GetLastError());
|
||||||
Runtime.FatalError("Failed to register window class");
|
Runtime.FatalError("Failed to register window class");
|
||||||
@@ -160,22 +165,27 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
LoadWindowRectangle();
|
LoadWindowRectangle();
|
||||||
|
|
||||||
Log.EngineLogger.Trace("Created window \"{}\" ({}, {})", Title, Width, Height);
|
Log.EngineLogger.Trace("Created window \"{}\" ({}, {})", Title, Width, Height);
|
||||||
|
|
||||||
|
DirectX.Init(_windowHandle, (.)Width, (.)Height);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _isResizingOrMoving;
|
private bool _isResizingOrMoving;
|
||||||
private bool _isMinimized;
|
private bool _isMinimized;
|
||||||
|
|
||||||
|
[CLink]
|
||||||
|
static extern IntBool IsWindowUnicode(HWND whnd);
|
||||||
|
|
||||||
private static LRESULT MessageHandler(HWND hwnd, uint32 uMsg, WPARAM wParam, LPARAM lParam)
|
private static LRESULT MessageHandler(HWND hwnd, uint32 uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
void* windowPtr = (void*)GetWindowLongPtrW(hwnd, GWL_USERDATA);
|
void* windowPtr = (void*)GetWindowLongPtrW(hwnd, GWL_USERDATA);
|
||||||
WindowsWindow window = (WindowsWindow)Internal.UnsafeCastToObject(windowPtr);
|
WindowsWindow window = (WindowsWindow)Internal.UnsafeCastToObject(windowPtr);
|
||||||
|
|
||||||
if(window == null)
|
if (window == null)
|
||||||
{
|
{
|
||||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(uMsg)
|
switch (uMsg)
|
||||||
{
|
{
|
||||||
////
|
////
|
||||||
//// Sizing and Moving
|
//// Sizing and Moving
|
||||||
@@ -184,20 +194,20 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
// Window min/max size requested
|
// Window min/max size requested
|
||||||
case WM_GETMINMAXINFO:
|
case WM_GETMINMAXINFO:
|
||||||
{
|
{
|
||||||
MinMaxInfo *info = (.)(void*)lParam;
|
MinMaxInfo* info = (.)(void*)lParam;
|
||||||
info.MinimumTrackingSize = window._minMaxInfo.MinimumTrackingSize;
|
info.MinimumTrackingSize = window._minMaxInfo.MinimumTrackingSize;
|
||||||
info.MaximumTrackingSize = window._minMaxInfo.MaximumTrackingSize;
|
info.MaximumTrackingSize = window._minMaxInfo.MaximumTrackingSize;
|
||||||
}
|
}
|
||||||
// Window size changed
|
// Window size changed
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
{
|
{
|
||||||
if(wParam == (.)ResizingType.Minimized)
|
if (wParam == (.)ResizingType.Minimized)
|
||||||
{
|
{
|
||||||
window._isMinimized = true;
|
window._isMinimized = true;
|
||||||
}
|
}
|
||||||
else if (window._isMinimized)
|
else if (window._isMinimized)
|
||||||
{
|
{
|
||||||
window._isMinimized = false;
|
window._isMinimized = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -210,13 +220,13 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
// Window position changed
|
// Window position changed
|
||||||
case WM_MOVE:
|
case WM_MOVE:
|
||||||
{
|
{
|
||||||
if(wParam == (.)ResizingType.Minimized)
|
if (wParam == (.)ResizingType.Minimized)
|
||||||
{
|
{
|
||||||
window._isMinimized = true;
|
window._isMinimized = true;
|
||||||
}
|
}
|
||||||
else if (window._isMinimized)
|
else if (window._isMinimized)
|
||||||
{
|
{
|
||||||
window._isMinimized = false;
|
window._isMinimized = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -228,12 +238,14 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
}
|
}
|
||||||
// Window resizing/moving started
|
// Window resizing/moving started
|
||||||
case WM_ENTERSIZEMOVE:
|
case WM_ENTERSIZEMOVE:
|
||||||
window._isResizingOrMoving = true;
|
window._isResizingOrMoving = true;
|
||||||
// Window resizing/moving ended
|
// Window resizing/moving ended
|
||||||
case WM_EXITSIZEMOVE:
|
case WM_EXITSIZEMOVE:
|
||||||
{
|
{
|
||||||
window._isResizingOrMoving = false;
|
window._isResizingOrMoving = false;
|
||||||
|
|
||||||
|
DirectX.UpdateSwapchain((.)window.Width, (.)window.Height);
|
||||||
|
|
||||||
var resEvent = scope WindowResizeEvent(window._clientRect.Width, window._clientRect.Height, false);
|
var resEvent = scope WindowResizeEvent(window._clientRect.Width, window._clientRect.Height, false);
|
||||||
window._eventCallback(resEvent);
|
window._eventCallback(resEvent);
|
||||||
var moveEvent = scope WindowMoveEvent(window._clientRect.X, window._clientRect.Y, false);
|
var moveEvent = scope WindowMoveEvent(window._clientRect.X, window._clientRect.Y, false);
|
||||||
@@ -296,7 +308,7 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
case WM_XBUTTONDOWN:
|
case WM_XBUTTONDOWN:
|
||||||
{
|
{
|
||||||
MouseButton button = .None;
|
MouseButton button = .None;
|
||||||
if(HighOrder!((int64)wParam) == 1)
|
if (HighOrder!((int64)wParam) == 1)
|
||||||
button = .XButton1;
|
button = .XButton1;
|
||||||
else
|
else
|
||||||
button = .XButton2;
|
button = .XButton2;
|
||||||
@@ -307,7 +319,7 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
case WM_XBUTTONUP:
|
case WM_XBUTTONUP:
|
||||||
{
|
{
|
||||||
MouseButton button = .None;
|
MouseButton button = .None;
|
||||||
if(HighOrder!((int64)wParam) == 1)
|
if (HighOrder!((int64)wParam) == 1)
|
||||||
button = .XButton1;
|
button = .XButton1;
|
||||||
else
|
else
|
||||||
button = .XButton2;
|
button = .XButton2;
|
||||||
@@ -344,6 +356,13 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
////
|
////
|
||||||
//// Application
|
//// Application
|
||||||
////
|
////
|
||||||
|
case WM_CHAR:
|
||||||
|
{
|
||||||
|
var event = scope KeyTypedEvent((char16)wParam);
|
||||||
|
window._eventCallback(event);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Window title changed
|
// Window title changed
|
||||||
case WM_SETTEXT:
|
case WM_SETTEXT:
|
||||||
@@ -355,8 +374,8 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
case WM_SYSCOMMAND:
|
case WM_SYSCOMMAND:
|
||||||
{
|
{
|
||||||
/* Remove beeping sound when ALT + some key is pressed. */
|
/* Remove beeping sound when ALT + some key is pressed. */
|
||||||
if ( wParam == SC_KEYMENU )
|
if (wParam == SC_KEYMENU)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Window closing
|
// Window closing
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
@@ -396,6 +415,9 @@ namespace GlitchyEngine.Platform.Windows
|
|||||||
SetWindowPos(_windowHandle, 0, _clientRect.X, _clientRect.Y, _clientRect.Width, _clientRect.Height, 0);
|
SetWindowPos(_windowHandle, 0, _clientRect.X, _clientRect.Y, _clientRect.Width, _clientRect.Height, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[LinkName(.C)]
|
||||||
|
private static extern IntBool SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int32 X, int32 Y, int32 cx, int32 cy, uint32 uFlags);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the window title via WinApi and stores it in _title.
|
* Gets the window title via WinApi and stores it in _title.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ using GlitchLog;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using GlitchyEngine.Platform.Windows;
|
using GlitchyEngine.Platform.Windows;
|
||||||
|
|
||||||
|
using imgui_beef;
|
||||||
|
|
||||||
namespace GlitchyEngine
|
namespace GlitchyEngine
|
||||||
{
|
{
|
||||||
class Program
|
class Program
|
||||||
|
|||||||
+1
Submodule GlitchyEngine/vendor/imgui-beef added at cdc410faf5
@@ -3,6 +3,7 @@ using GlitchyEngine;
|
|||||||
using GlitchyEngine.Events;
|
using GlitchyEngine.Events;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using GlitchLog;
|
using GlitchLog;
|
||||||
|
using GlitchyEngine.ImGui;
|
||||||
|
|
||||||
namespace Sandbox
|
namespace Sandbox
|
||||||
{
|
{
|
||||||
@@ -11,13 +12,13 @@ namespace Sandbox
|
|||||||
[AllowAppend]
|
[AllowAppend]
|
||||||
public this() : base("Example") { }
|
public this() : base("Example") { }
|
||||||
|
|
||||||
public override void Update()
|
public override void Update(GameTime gameTime)
|
||||||
{
|
{
|
||||||
Log.ClientLogger.Info("ExampleLayer.Update");
|
Log.ClientLogger.Info("ExampleLayer.Update");
|
||||||
|
|
||||||
// Just for temporary vsyncing
|
// Just for temporary vsyncing
|
||||||
// Todo: remove
|
// Todo: remove
|
||||||
DwmFlush();
|
//DwmFlush();
|
||||||
}
|
}
|
||||||
|
|
||||||
[CLink, Import("Dwmapi.lib")]
|
[CLink, Import("Dwmapi.lib")]
|
||||||
@@ -34,6 +35,7 @@ namespace Sandbox
|
|||||||
public this()
|
public this()
|
||||||
{
|
{
|
||||||
PushLayer(new ExampleLayer());
|
PushLayer(new ExampleLayer());
|
||||||
|
PushOverlay(new ImGuiLayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Export, LinkName("CreateApplication")]
|
[Export, LinkName("CreateApplication")]
|
||||||
|
|||||||
Reference in New Issue
Block a user