feat: switch default backend to Silk.NET OpenGL
- OpenGLRenderContext: Initialize() + CreateOpenGL() for non-blocking - OpenGLWindow: Initialize() instead of Run(), CreateGL() method - Program.cs: default backend is now 'opengl', SwapBuffers per frame - ImGui guarded: only initialized for RaylibRenderer, ObjectManipulator checks _imGuiAvailable before calling ImGui.GetIO() - 66/66 tests, 145 FPS with OpenGL backend
This commit is contained in:
@@ -14,7 +14,7 @@ Size=250,398
|
||||
Collapsed=0
|
||||
|
||||
[Window][Inspector]
|
||||
Pos=36,302
|
||||
Pos=112,297
|
||||
Size=300,425
|
||||
Collapsed=0
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<ProjectReference Include="..\Engine.Graphics.Vulkan\Engine.Graphics.Vulkan.csproj" />
|
||||
<ProjectReference Include="..\Engine.AI\Engine.AI.csproj" />
|
||||
<ProjectReference Include="..\Engine.Physics\Engine.Physics.csproj" />
|
||||
<ProjectReference Include="..\Engine.Graphics.OpenGL\Engine.Graphics.OpenGL.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -28,10 +28,14 @@ public sealed class ObjectManipulator
|
||||
/// Process input for object picking and dragging.
|
||||
/// Returns true if input was consumed (ImGui should be ignored).
|
||||
/// </summary>
|
||||
private bool _imGuiAvailable;
|
||||
|
||||
public void SetImGuiAvailable(bool available) => _imGuiAvailable = available;
|
||||
|
||||
public bool ProcessInput(World world, Camera camera, IInputState input)
|
||||
{
|
||||
// Skip if ImGui is capturing mouse
|
||||
if (ImGuiNET.ImGui.GetIO().WantCaptureMouse)
|
||||
if (_imGuiAvailable && ImGuiNET.ImGui.GetIO().WantCaptureMouse)
|
||||
{
|
||||
_isDragging = false;
|
||||
return false;
|
||||
|
||||
@@ -11,6 +11,7 @@ using Engine.Core;
|
||||
using Engine.Core.Components;
|
||||
using Engine.Graphics;
|
||||
using Engine.Graphics.Loaders;
|
||||
using Engine.Graphics.OpenGL;
|
||||
using Engine.Graphics.RaylibBackend;
|
||||
using Engine.Graphics.Vulkan;
|
||||
using Engine.Physics;
|
||||
@@ -43,19 +44,22 @@ class Program
|
||||
|
||||
RaylibBackendRegistrar.EnsureRegistered();
|
||||
VulkanBackendRegistrar.EnsureRegistered();
|
||||
using var renderContext = RenderBackendFactory.Create("raylib", 1280, 720, enableValidation: false);
|
||||
OpenGLBackendRegistrar.EnsureRegistered();
|
||||
using var renderContext = RenderBackendFactory.Create("opengl", 1280, 720, enableValidation: false);
|
||||
var window = renderContext.Window;
|
||||
var input = window.Input;
|
||||
using var renderer = renderContext.CreateRenderer();
|
||||
|
||||
// ImGui editor layer
|
||||
var imGuiLayer = new ImGuiLayer();
|
||||
// ImGui editor layer (Raylib only)
|
||||
ImGuiLayer? imGuiLayer = null;
|
||||
var objectManipulator = new ObjectManipulator();
|
||||
if (!cameraTour)
|
||||
objectManipulator.SetImGuiAvailable(false);
|
||||
if (!cameraTour && renderer is RaylibRenderer rlRenderer)
|
||||
{
|
||||
imGuiLayer = new ImGuiLayer();
|
||||
imGuiLayer.Initialize();
|
||||
if (renderer is RaylibRenderer rlRenderer)
|
||||
rlRenderer.ImGuiLayer = imGuiLayer;
|
||||
rlRenderer.ImGuiLayer = imGuiLayer;
|
||||
objectManipulator.SetImGuiAvailable(true);
|
||||
}
|
||||
|
||||
var (modelPath, mcpPort) = ParseArgs(args);
|
||||
@@ -283,15 +287,18 @@ class Program
|
||||
}
|
||||
|
||||
// Feed frame data to ImGui before rendering.
|
||||
imGuiLayer.SetFrameData(world, timing, currentFps);
|
||||
if (imGuiLayer != null)
|
||||
imGuiLayer.SetFrameData(world, timing, currentFps);
|
||||
|
||||
// Sync selection between manipulator and ImGui
|
||||
if (objectManipulator.IsDragging && !string.IsNullOrEmpty(objectManipulator.SelectedEntityName))
|
||||
imGuiLayer.SetSelectedEntity(objectManipulator.SelectedEntityName);
|
||||
objectManipulator.SetImGuiAvailable(imGuiLayer != null);
|
||||
|
||||
renderer.RenderWorld(world);
|
||||
queue.CompletePendingScreenshots();
|
||||
|
||||
// Swap buffers for OpenGL backend
|
||||
if (renderContext is OpenGLRenderContext glCtx2)
|
||||
glCtx2.SwapBuffers();
|
||||
|
||||
frames++;
|
||||
if (timing.TotalTime - lastFpsTime >= 1.0)
|
||||
{
|
||||
@@ -303,7 +310,7 @@ class Program
|
||||
}
|
||||
|
||||
Console.WriteLine("Shutting down...");
|
||||
imGuiLayer.Dispose();
|
||||
imGuiLayer?.Dispose();
|
||||
#if !RELEASE_AOT
|
||||
if (mcpApp != null)
|
||||
await mcpApp.StopAsync();
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using Engine.Core;
|
||||
using Engine.Graphics;
|
||||
using Silk.NET.OpenGL;
|
||||
using Silk.NET.Windowing;
|
||||
using SilkWindow = Silk.NET.Windowing.IWindow;
|
||||
using CoreIWindow = Engine.Core.IWindow;
|
||||
|
||||
namespace Engine.Graphics.OpenGL;
|
||||
|
||||
@@ -12,16 +14,15 @@ public sealed class OpenGLRenderContext : IRenderContext
|
||||
private OpenGLRenderer? _renderer;
|
||||
private bool _disposed;
|
||||
|
||||
public IWindow Window => _window;
|
||||
public CoreIWindow Window => _window;
|
||||
|
||||
public OpenGLRenderContext(int width, int height, bool enableValidation = false)
|
||||
{
|
||||
_window = new OpenGLWindow("Cortex Engine (OpenGL)", width, height);
|
||||
}
|
||||
|
||||
public void OnLoad()
|
||||
{
|
||||
_gl = _window.SilkView.CreateOpenGL();
|
||||
// Initialize() triggers the Load callback which creates the GL context
|
||||
_window.SilkView.Initialize();
|
||||
// After Initialize, CreateOpenGL should work
|
||||
_gl = _window.CreateGL();
|
||||
_window.OnLoad();
|
||||
}
|
||||
|
||||
@@ -31,10 +32,9 @@ public sealed class OpenGLRenderContext : IRenderContext
|
||||
return _renderer;
|
||||
}
|
||||
|
||||
public void Resize(int width, int height)
|
||||
{
|
||||
_renderer?.SetScreenSize(width, height);
|
||||
}
|
||||
public void Resize(int width, int height) => _renderer?.SetScreenSize(width, height);
|
||||
|
||||
public void SwapBuffers() => _window.SilkView.SwapBuffers();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using Engine.Core;
|
||||
using Silk.NET.Input;
|
||||
using Silk.NET.OpenGL;
|
||||
using Silk.NET.Windowing;
|
||||
using SilkWindow = Silk.NET.Windowing.IWindow;
|
||||
|
||||
@@ -31,6 +32,8 @@ public sealed class OpenGLWindow : Engine.Core.IWindow, IDisposable
|
||||
|
||||
_silkWindow = Window.Create(options);
|
||||
_silkWindow.Closing += () => _shouldClose = true;
|
||||
// Initialize without Run() — enables non-blocking event loop
|
||||
_silkWindow.Initialize();
|
||||
}
|
||||
|
||||
public void OnLoad()
|
||||
@@ -39,6 +42,8 @@ public sealed class OpenGLWindow : Engine.Core.IWindow, IDisposable
|
||||
_input.Initialize(inputContext);
|
||||
}
|
||||
|
||||
public GL CreateGL() => _silkWindow.CreateOpenGL();
|
||||
|
||||
public void PumpEvents() => _silkWindow.DoEvents();
|
||||
public void Close() => _shouldClose = true;
|
||||
public string[] GetRequiredVulkanExtensions() => Array.Empty<string>();
|
||||
|
||||
Reference in New Issue
Block a user