Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove OpenGL dependencies from Core project #67

Merged
merged 12 commits into from
Sep 23, 2024
130 changes: 79 additions & 51 deletions src/Core/Application.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using System.Reflection;
using System.Text;
using KorpiEngine.AssetManagement;
using KorpiEngine.InputManagement;
using KorpiEngine.Mathematics;
using KorpiEngine.Rendering;
using KorpiEngine.SceneManagement;
using KorpiEngine.Threading;
using KorpiEngine.Tools.Logging;
using KorpiEngine.UI;
using KorpiEngine.UI.DearImGui;
using KorpiEngine.Utils;
using OpenTK.Windowing.Common;

namespace KorpiEngine;

Expand All @@ -18,13 +19,12 @@ namespace KorpiEngine;
/// </summary>
public static class Application
{
private static ImGuiController imGuiController = null!;
private static AssetProvider? assetProviderInstance;
private static SceneManager? sceneManagerInstance;
private static KorpiWindow windowInstance = null!;
private static GraphicsContext? graphicsContext;
private static AssetProvider? assetProvider;
private static SceneManager? sceneManager;
private static Type initialSceneType = null!;
private static double fixedFrameAccumulator;

[ThreadStatic]
internal static bool IsMainThread;
public static readonly IKorpiLogger Logger = LogFactory.GetLogger(typeof(Application));
Expand All @@ -42,9 +42,9 @@ public static SceneManager SceneManager
{
get
{
if (sceneManagerInstance == null)
if (sceneManager == null)
throw new InvalidOperationException("The scene manager has not been initialized yet!");
return sceneManagerInstance;
return sceneManager;
}
}

Expand All @@ -57,9 +57,9 @@ public static AssetProvider AssetProvider
{
get
{
if (assetProviderInstance == null)
if (assetProvider == null)
throw new InvalidOperationException("The asset provider has not been initialized yet!");
return assetProviderInstance;
return assetProvider;
}
}

Expand All @@ -69,8 +69,9 @@ public static AssetProvider AssetProvider
/// </summary>
/// <typeparam name="T">The type of the initial scene to load.</typeparam>
/// <param name="settings">The settings for the game window.</param>
/// <param name="assetProvider">The asset provider to use for loading assets.</param>
public static void Run<T>(WindowingSettings settings, AssetProvider assetProvider) where T : Scene
/// <param name="provider">The asset provider to use for loading assets.</param>
/// <param name="context">The graphics context to use for rendering.</param>
public static void Run<T>(WindowingSettings settings, AssetProvider provider, GraphicsContext context) where T : Scene
{
IsMainThread = true;
MemoryReleaseSystem.Initialize();
Expand All @@ -80,39 +81,49 @@ public static void Run<T>(WindowingSettings settings, AssetProvider assetProvide

// Needs to be executed before Window.OnLoad() (called right after Window.Run())
// to provide access to asset loading.
assetProviderInstance = assetProvider;
assetProviderInstance.Initialize();
assetProvider = provider;
assetProvider.Initialize();

initialSceneType = typeof(T);

windowInstance = new KorpiWindow(settings.GameWindowSettings, settings.NativeWindowSettings);
windowInstance.Load += OnLoad;
windowInstance.UpdateFrame += OnUpdateFrame;
windowInstance.RenderFrame += OnRenderFrame;
windowInstance.Unload += OnUnload;
graphicsContext = context;
graphicsContext.Run(settings, OnLoad, OnUpdate, OnRender, OnUnload);
graphicsContext = null;
}


private static void OnWindowResize(Int2 newSize)
{
Graphics.UpdateViewport(newSize.X, newSize.Y);

windowInstance.Run();
WindowInfo.Update(graphicsContext!);
}


/// <summary>
/// Quits the application.
/// </summary>
public static void Quit()
{
windowInstance.Close();
if (graphicsContext == null)
throw new InvalidOperationException("The graphics context has not been initialized yet!");

graphicsContext.Shutdown();
}


#region Loading and Unloading

private static void OnLoad()
{
SystemInfo.Initialize();
Graphics.Initialize(graphicsContext!);

// Queue window visibility after all internal resources are loaded.
windowInstance.CenterWindow();
windowInstance.IsVisible = true;
sceneManagerInstance = new SceneManager(initialSceneType);
imGuiController = new ImGuiController(windowInstance);
graphicsContext!.Window.OnResize += OnWindowResize;
graphicsContext.Window.SetCentered();
graphicsContext.Window.IsVisible = true;
sceneManager = new SceneManager(initialSceneType);

GUI.Initialize();
#if TOOLS
Expand All @@ -131,35 +142,24 @@ private static void OnUnload()
#endif
GUI.Deinitialize();

sceneManagerInstance?.InternalDispose();
sceneManagerInstance = null;
sceneManager?.InternalDispose();
sceneManager = null;
GlobalJobPool.Shutdown();
assetProviderInstance?.Shutdown();
assetProvider?.Shutdown();

ImGuiWindowManager.Shutdown();
imGuiController.Dispose();
MemoryReleaseSystem.Shutdown();
windowInstance.Dispose();

Graphics.Shutdown();
}

#endregion


#region Frame Updating and Rendering

private static void OnUpdateFrame(FrameEventArgs args)
private static void OnUpdate(double deltaTime)
{
double deltaTime = args.Time;
fixedFrameAccumulator += deltaTime;

while (fixedFrameAccumulator >= EngineConstants.FIXED_DELTA_TIME)
{
InternalFixedUpdate();
fixedFrameAccumulator -= EngineConstants.FIXED_DELTA_TIME;
}

double fixedAlpha = fixedFrameAccumulator / EngineConstants.FIXED_DELTA_TIME;

if (deltaTime > EngineConstants.MAX_DELTA_TIME)
{
Logger.Warn($"Detected large frame hitch ({1f/deltaTime:F2}fps, {deltaTime:F2}s)! Delta time was clamped to {EngineConstants.MAX_DELTA_TIME:F2} seconds.");
Expand All @@ -170,13 +170,27 @@ private static void OnUpdateFrame(FrameEventArgs args)
Logger.Warn($"Detected frame hitch ({deltaTime:F2}s)!");
}

InternalUpdate(deltaTime, fixedAlpha);
InternalPreUpdate(deltaTime);

fixedFrameAccumulator += deltaTime;

while (fixedFrameAccumulator >= EngineConstants.FIXED_DELTA_TIME)
{
InternalFixedUpdate();
fixedFrameAccumulator -= EngineConstants.FIXED_DELTA_TIME;
}

double fixedAlpha = fixedFrameAccumulator / EngineConstants.FIXED_DELTA_TIME;

InternalUpdate(fixedAlpha);
}


private static void OnRenderFrame(FrameEventArgs args)
private static void OnRender()
{
Graphics.StartFrame();
InternalRender();
Graphics.EndFrame();
}


Expand All @@ -191,17 +205,25 @@ private static void InternalFixedUpdate()
}


private static void InternalUpdate(double deltaTime, double fixedAlpha)
private static void InternalPreUpdate(double deltaTime)
{
Time.Update(deltaTime);
Input.Update(graphicsContext!.InputState);
DisplayInfo.Update(graphicsContext.DisplayState);
Cursor.Update(graphicsContext.Window.CursorState);
}


private static void InternalUpdate(double fixedAlpha)
{
Time.Update(deltaTime, fixedAlpha);
Input.Input.Update(windowInstance.KeyboardState, windowInstance.MouseState);
Time.UpdateFixedAlpha(fixedAlpha);

SceneManager.Update();

// Instantly execute jobs.
GlobalJobPool.Update();

imGuiController.Update();
graphicsContext!.ImGuiRenderer.Update();
ImGuiWindowManager.Update();

MemoryReleaseSystem.ProcessDisposeQueue();
Expand All @@ -211,7 +233,7 @@ private static void InternalUpdate(double deltaTime, double fixedAlpha)
private static void InternalRender()
{
SceneManager.Render();
imGuiController.Render();
graphicsContext!.ImGuiRenderer.Render();
}

#endregion
Expand All @@ -229,4 +251,10 @@ private static void InitializeLog4Net()
}

#endregion


internal static void SetCursorState(CursorLockState value)
{
graphicsContext!.Window.CursorState = value;
}
}
10 changes: 5 additions & 5 deletions src/Core/Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
<Platforms>AnyCPU</Platforms>
</PropertyGroup>

<ItemGroup>
<InternalsVisibleTo Include="$(AssemblyName).Tests" />
<InternalsVisibleTo Include="KorpiEngine.OpenGL" />
</ItemGroup>

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<Optimize>false</Optimize>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
Expand All @@ -34,7 +39,6 @@
<PackageReference Include="ImGui.NET" Version="1.91.0.1"/>
<PackageReference Include="log4net" Version="2.0.15"/>
<PackageReference Include="Magick.NET-Q16-AnyCPU" Version="13.7.0"/>
<PackageReference Include="OpenTK" Version="4.8.2"/>
</ItemGroup>

<ItemGroup>
Expand All @@ -43,10 +47,6 @@
</Content>
</ItemGroup>

<ItemGroup>
<Folder Include="Rendering\Lighting\" />
</ItemGroup>

<ItemGroup>
<None Update="Math\MathOps.tt">
<Generator>TextTemplatingFileGenerator</Generator>
Expand Down
35 changes: 0 additions & 35 deletions src/Core/Input/Cursor.cs

This file was deleted.

35 changes: 0 additions & 35 deletions src/Core/Input/Input.cs

This file was deleted.

27 changes: 27 additions & 0 deletions src/Core/InputManagement/Cursor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace KorpiEngine.InputManagement;

public static class Cursor
{
private static CursorLockState lockState = CursorLockState.None;

public static CursorLockState LockState
{
get => lockState;
set
{
if (LockState == value)
return;

Application.SetCursorState(value);
lockState = value;
}
}

public static bool IsHidden => LockState != CursorLockState.None;


internal static void Update(CursorLockState state)
{
LockState = state;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace KorpiEngine.Input;
namespace KorpiEngine.InputManagement;

public enum CursorLockState
{
Expand Down
Loading
Loading