mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Added ImGui
This commit is contained in:
@@ -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 GlitchyEngine.Events;
|
||||
using System.Diagnostics;
|
||||
using imgui_beef;
|
||||
using GlitchyEngine.Platform.DX11;
|
||||
using static System.Windows;
|
||||
|
||||
namespace GlitchyEngine.Platform.Windows
|
||||
{
|
||||
@@ -22,6 +25,8 @@ namespace GlitchyEngine.Platform.Windows
|
||||
|
||||
private String _title ~ delete _;
|
||||
|
||||
private bool _isVSync = true;
|
||||
|
||||
public override int32 MinWidth
|
||||
{
|
||||
get => _minMaxInfo.MinimumTrackingSize.x;
|
||||
@@ -38,7 +43,7 @@ namespace GlitchyEngine.Platform.Windows
|
||||
get => _minMaxInfo.MaximumTrackingSize.x;
|
||||
set => _minMaxInfo.MaximumTrackingSize.x = value;
|
||||
}
|
||||
|
||||
|
||||
public override int32 MaxHeight
|
||||
{
|
||||
get => _minMaxInfo.MaximumTrackingSize.y;
|
||||
@@ -93,7 +98,7 @@ namespace GlitchyEngine.Platform.Windows
|
||||
{
|
||||
get
|
||||
{
|
||||
if(_title == null)
|
||||
if (_title == null)
|
||||
LoadTitle();
|
||||
|
||||
return _title;
|
||||
@@ -104,8 +109,8 @@ namespace GlitchyEngine.Platform.Windows
|
||||
|
||||
public override bool IsVSync
|
||||
{
|
||||
get;
|
||||
set;
|
||||
get => _isVSync;
|
||||
set => _isVSync = value;
|
||||
}
|
||||
|
||||
#if GE_WINDOWS
|
||||
@@ -135,16 +140,16 @@ namespace GlitchyEngine.Platform.Windows
|
||||
_windowClass.WindowProcedure = => MessageHandler;
|
||||
_windowClass.HInstance = (.)_instanceHandle;
|
||||
|
||||
if(desc.Icon.Ptr != null)
|
||||
if (desc.Icon.Ptr != null)
|
||||
_windowClass.Icon = LoadImageW(0, desc.Icon.ToScopedNativeWChar!(), .Icon, 0, 0, .LoadFromFile);
|
||||
else
|
||||
_windowClass.Icon = 0;
|
||||
|
||||
|
||||
_windowClass.Cursor = LoadCursorW(0, IDC_ARROW);
|
||||
_windowClass.BackgroundBrush = (HBRUSH)SystemColor.WindowFrame;
|
||||
_windowClass.ClassName = "GlitchyEngineWindow".ToScopedNativeWChar!();
|
||||
|
||||
if(RegisterClassExW(ref _windowClass) == 0)
|
||||
if (RegisterClassExW(ref _windowClass) == 0)
|
||||
{
|
||||
Log.EngineLogger.Error("Failed to register window class.", (HResult)GetLastError());
|
||||
Runtime.FatalError("Failed to register window class");
|
||||
@@ -158,24 +163,29 @@ namespace GlitchyEngine.Platform.Windows
|
||||
SetWindowLongPtrW(_windowHandle, GWL_USERDATA, (int)myPtr);
|
||||
|
||||
LoadWindowRectangle();
|
||||
|
||||
|
||||
Log.EngineLogger.Trace("Created window \"{}\" ({}, {})", Title, Width, Height);
|
||||
|
||||
DirectX.Init(_windowHandle, (.)Width, (.)Height);
|
||||
}
|
||||
|
||||
private bool _isResizingOrMoving;
|
||||
private bool _isMinimized;
|
||||
|
||||
[CLink]
|
||||
static extern IntBool IsWindowUnicode(HWND whnd);
|
||||
|
||||
private static LRESULT MessageHandler(HWND hwnd, uint32 uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
void* windowPtr = (void*)GetWindowLongPtrW(hwnd, GWL_USERDATA);
|
||||
WindowsWindow window = (WindowsWindow)Internal.UnsafeCastToObject(windowPtr);
|
||||
|
||||
if(window == null)
|
||||
|
||||
if (window == null)
|
||||
{
|
||||
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
switch(uMsg)
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
////
|
||||
//// Sizing and Moving
|
||||
@@ -184,20 +194,20 @@ namespace GlitchyEngine.Platform.Windows
|
||||
// Window min/max size requested
|
||||
case WM_GETMINMAXINFO:
|
||||
{
|
||||
MinMaxInfo *info = (.)(void*)lParam;
|
||||
MinMaxInfo* info = (.)(void*)lParam;
|
||||
info.MinimumTrackingSize = window._minMaxInfo.MinimumTrackingSize;
|
||||
info.MaximumTrackingSize = window._minMaxInfo.MaximumTrackingSize;
|
||||
}
|
||||
// Window size changed
|
||||
case WM_SIZE:
|
||||
{
|
||||
if(wParam == (.)ResizingType.Minimized)
|
||||
if (wParam == (.)ResizingType.Minimized)
|
||||
{
|
||||
window._isMinimized = true;
|
||||
window._isMinimized = true;
|
||||
}
|
||||
else if (window._isMinimized)
|
||||
{
|
||||
window._isMinimized = false;
|
||||
window._isMinimized = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -210,13 +220,13 @@ namespace GlitchyEngine.Platform.Windows
|
||||
// Window position changed
|
||||
case WM_MOVE:
|
||||
{
|
||||
if(wParam == (.)ResizingType.Minimized)
|
||||
if (wParam == (.)ResizingType.Minimized)
|
||||
{
|
||||
window._isMinimized = true;
|
||||
window._isMinimized = true;
|
||||
}
|
||||
else if (window._isMinimized)
|
||||
{
|
||||
window._isMinimized = false;
|
||||
window._isMinimized = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -228,12 +238,14 @@ namespace GlitchyEngine.Platform.Windows
|
||||
}
|
||||
// Window resizing/moving started
|
||||
case WM_ENTERSIZEMOVE:
|
||||
window._isResizingOrMoving = true;
|
||||
window._isResizingOrMoving = true;
|
||||
// Window resizing/moving ended
|
||||
case WM_EXITSIZEMOVE:
|
||||
{
|
||||
window._isResizingOrMoving = false;
|
||||
|
||||
DirectX.UpdateSwapchain((.)window.Width, (.)window.Height);
|
||||
|
||||
var resEvent = scope WindowResizeEvent(window._clientRect.Width, window._clientRect.Height, false);
|
||||
window._eventCallback(resEvent);
|
||||
var moveEvent = scope WindowMoveEvent(window._clientRect.X, window._clientRect.Y, false);
|
||||
@@ -296,7 +308,7 @@ namespace GlitchyEngine.Platform.Windows
|
||||
case WM_XBUTTONDOWN:
|
||||
{
|
||||
MouseButton button = .None;
|
||||
if(HighOrder!((int64)wParam) == 1)
|
||||
if (HighOrder!((int64)wParam) == 1)
|
||||
button = .XButton1;
|
||||
else
|
||||
button = .XButton2;
|
||||
@@ -307,7 +319,7 @@ namespace GlitchyEngine.Platform.Windows
|
||||
case WM_XBUTTONUP:
|
||||
{
|
||||
MouseButton button = .None;
|
||||
if(HighOrder!((int64)wParam) == 1)
|
||||
if (HighOrder!((int64)wParam) == 1)
|
||||
button = .XButton1;
|
||||
else
|
||||
button = .XButton2;
|
||||
@@ -334,7 +346,7 @@ namespace GlitchyEngine.Platform.Windows
|
||||
case WM_MOUSEMOVE:
|
||||
{
|
||||
SplitHighAndLowOrder!(lParam, let x, let y);
|
||||
|
||||
|
||||
var event = scope MouseMovedEvent(x, y);
|
||||
window._eventCallback(event);
|
||||
}
|
||||
@@ -344,6 +356,13 @@ namespace GlitchyEngine.Platform.Windows
|
||||
////
|
||||
//// Application
|
||||
////
|
||||
case WM_CHAR:
|
||||
{
|
||||
var event = scope KeyTypedEvent((char16)wParam);
|
||||
window._eventCallback(event);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Window title changed
|
||||
case WM_SETTEXT:
|
||||
@@ -355,8 +374,8 @@ namespace GlitchyEngine.Platform.Windows
|
||||
case WM_SYSCOMMAND:
|
||||
{
|
||||
/* Remove beeping sound when ALT + some key is pressed. */
|
||||
if ( wParam == SC_KEYMENU )
|
||||
return 0;
|
||||
if (wParam == SC_KEYMENU)
|
||||
return 0;
|
||||
}
|
||||
// Window closing
|
||||
case WM_CLOSE:
|
||||
@@ -380,7 +399,7 @@ namespace GlitchyEngine.Platform.Windows
|
||||
DispatchMessageW(&message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void LoadWindowRectangle()
|
||||
{
|
||||
GetWindowRect(_windowHandle, let rectangle);
|
||||
@@ -396,6 +415,9 @@ namespace GlitchyEngine.Platform.Windows
|
||||
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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user