diff --git a/Core/Entities/UIElement.cs b/Core/Entities/UIElement.cs
index 2ba6372..1664569 100644
--- a/Core/Entities/UIElement.cs
+++ b/Core/Entities/UIElement.cs
@@ -4,6 +4,7 @@
using SharpEngine.Core.Shaders;
using Silk.NET.OpenGL;
+using System;
using System.Threading.Tasks;
namespace SharpEngine.Core.Entities;
@@ -20,7 +21,7 @@ public class UIElement : SceneNode
public UIElement(string name)
{
Name = name;
- Mesh = MeshService.Instance.LoadMesh("plane", Primitives.Plane.Mesh);
+ // Mesh = MeshService.Instance.LoadMesh("plane", Primitives.Plane.Mesh);
}
private readonly UIShader _uIShader = new();
@@ -33,7 +34,7 @@ public UIElement(string name)
// TODO: Use actual mesh
/// Gets or sets the mesh of the UI element.
- public Mesh Mesh { get; set; } = new();
+ public Mesh Mesh { get; set; } // = new();
private readonly float[] _vertices =
[
@@ -56,20 +57,25 @@ public UIElement(string name)
public void Initialize()
{
_vertexArrayObject = Window.GL.GenVertexArray();
- Window.GL.BindVertexArray(_vertexArrayObject);
+ Bind();
InitializeBuffers();
}
+ public void Bind()
+ {
+ Window.GL.BindVertexArray(_vertexArrayObject);
+ }
+
private void InitializeBuffers()
{
var vertexBufferObject = Window.GL.GenBuffer();
Window.GL.BindBuffer(GLEnum.ArrayBuffer, vertexBufferObject);
- Window.GL.BufferData(GLEnum.ArrayBuffer, (uint)_vertices.Length * sizeof(float), _vertices, GLEnum.StaticDraw);
+ Window.GL.BufferData(GLEnum.ArrayBuffer, _vertices, GLEnum.StaticDraw);
var elementBufferObject = Window.GL.GenBuffer();
Window.GL.BindBuffer(GLEnum.ElementArrayBuffer, elementBufferObject);
- Window.GL.BufferData(GLEnum.ElementArrayBuffer, (uint)_indices.Length * sizeof(uint), _indices, GLEnum.StaticDraw);
+ Window.GL.BufferData(GLEnum.ElementArrayBuffer, _indices, GLEnum.StaticDraw);
}
///
@@ -81,8 +87,7 @@ public override Task Render()
_uIShader.Shader.SetMatrix4(ShaderAttributes.Model, Transform.ModelMatrix);
- uint a = 0;
- Window.GL.DrawElements(PrimitiveType.Triangles, (uint)_indices.Length, DrawElementsType.UnsignedInt, ref a);
+ Window.GL.DrawElements(PrimitiveType.Triangles, (uint)_indices.Length, DrawElementsType.UnsignedInt, []);
return Task.CompletedTask;
}
diff --git a/Core/Renderers/Renderer.cs b/Core/Renderers/Renderer.cs
index 9532509..ae52bed 100644
--- a/Core/Renderers/Renderer.cs
+++ b/Core/Renderers/Renderer.cs
@@ -41,6 +41,7 @@ public Renderer(CameraView camera, ISettings settings, Scene scene) : base(setti
_camera = camera;
_scene = scene;
+ // TODO: These should be refactored out. The minimum build shouldn't need to use these.
_lightingShader = new LightingShader();
_lampShader = new LampShader();
}
diff --git a/Core/Renderers/UIRenderer.cs b/Core/Renderers/UIRenderer.cs
index 11e2165..47a6e4c 100644
--- a/Core/Renderers/UIRenderer.cs
+++ b/Core/Renderers/UIRenderer.cs
@@ -41,7 +41,7 @@ public override void Initialize()
_uiShader.Shader.Use();
- //_scene.UIElements.Add(new UIElement("uiElement"));
+ _scene.UIElements.Add(new UIElement("uiElement"));
_scene.Iterate(_scene.UIElements, elem => elem.Initialize());
@@ -56,14 +56,22 @@ private void InitializeVertexArrays()
///
public override Task Render()
{
+ return Task.CompletedTask;
+
try
{
Window.GL.Disable(EnableCap.DepthTest);
Window.GL.DepthFunc(DepthFunction.Less);
+ foreach (var item in _scene.UIElements)
+ {
+ item.Bind();
+ }
+
_uiShader.Shader.Use();
var uiElementRenderTasks = _scene.IterateAsync(_scene.UIElements, elem => elem.Render());
+
return Task.WhenAll(uiElementRenderTasks);
}
catch (Exception ex)
diff --git a/Core/Shaders/LampShader.cs b/Core/Shaders/LampShader.cs
index ced37b6..aa63ddb 100644
--- a/Core/Shaders/LampShader.cs
+++ b/Core/Shaders/LampShader.cs
@@ -1,4 +1,4 @@
-using SharpEngine.Core.Entities.Properties;
+using SharpEngine.Core.Entities.Properties;
using SharpEngine.Core.Extensions;
using Silk.NET.OpenGL;
@@ -22,9 +22,12 @@ public override bool SetAttributes()
if (!base.SetAttributes())
return false;
- var positionLocation = (uint)Shader!.GetAttribLocation(ShaderAttributes.Pos);
- Window.GL.EnableVertexAttribArray(positionLocation);
- Window.GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, VertexData.Stride, 0);
+ if (!Shader!.TryGetAttribLocation(ShaderAttributes.Pos, out int positionLocation))
+ return false;
+
+ var positionLocationUint = (uint)positionLocation;
+ Window.GL.EnableVertexAttribArray(positionLocationUint);
+ Window.GL.VertexAttribPointer(positionLocationUint, 3, VertexAttribPointerType.Float, false, VertexData.Stride, 0);
return true;
}
diff --git a/Core/Shaders/LightingShader.cs b/Core/Shaders/LightingShader.cs
index 340a003..8ddd2af 100644
--- a/Core/Shaders/LightingShader.cs
+++ b/Core/Shaders/LightingShader.cs
@@ -1,6 +1,7 @@
-using SharpEngine.Core.Entities.Properties;
+using SharpEngine.Core.Entities.Properties;
using SharpEngine.Core.Extensions;
using Silk.NET.OpenGL;
+using System;
namespace SharpEngine.Core.Shaders;
@@ -22,17 +23,26 @@ public override bool SetAttributes()
if (!base.SetAttributes())
return false;
- var positionLocation = (uint)Shader!.GetAttribLocation(ShaderAttributes.Pos);
- Window.GL.EnableVertexAttribArray(positionLocation);
- Window.GL.VertexAttribPointer(positionLocation, VertexData.VerticesSize, VertexAttribPointerType.Float, false, VertexData.Stride, 0);
-
- var normalLocation = (uint)Shader.GetAttribLocation(ShaderAttributes.Normal);
- Window.GL.EnableVertexAttribArray(normalLocation);
- Window.GL.VertexAttribPointer(normalLocation, VertexData.NormalsSize, VertexAttribPointerType.Float, false, VertexData.Stride, VertexData.NormalsOffset);
+ if (!Shader!.TryGetAttribLocation(ShaderAttributes.Pos, out int positionLocation))
+ return false;
- var texCoordLocation = (uint)Shader.GetAttribLocation(ShaderAttributes.TexCoords);
- Window.GL.EnableVertexAttribArray(texCoordLocation);
- Window.GL.VertexAttribPointer(texCoordLocation, VertexData.TexCoordsSize, VertexAttribPointerType.Float, false, VertexData.Stride, VertexData.TexCoordsOffset);
+ var positionLocationUint = (uint)positionLocation;
+ Window.GL.EnableVertexAttribArray(positionLocationUint);
+ Window.GL.VertexAttribPointer(positionLocationUint, VertexData.VerticesSize, VertexAttribPointerType.Float, false, VertexData.Stride, 0);
+
+ if (!Shader!.TryGetAttribLocation(ShaderAttributes.Normal, out int normalLocation))
+ return false;
+
+ var normalLocationUint = (uint)normalLocation;
+ Window.GL.EnableVertexAttribArray(normalLocationUint);
+ Window.GL.VertexAttribPointer(normalLocationUint, VertexData.NormalsSize, VertexAttribPointerType.Float, false, VertexData.Stride, VertexData.NormalsOffset);
+
+ if (!Shader!.TryGetAttribLocation(ShaderAttributes.TexCoords, out int texCoordLocation))
+ return false;
+
+ var texCoordLocationUint = (uint)texCoordLocation;
+ Window.GL.EnableVertexAttribArray(texCoordLocationUint);
+ Window.GL.VertexAttribPointer(texCoordLocationUint, VertexData.TexCoordsSize, VertexAttribPointerType.Float, false, VertexData.Stride, VertexData.TexCoordsOffset);
return true;
}
diff --git a/Core/Shaders/Shader.cs b/Core/Shaders/Shader.cs
index 4c7b94a..0ae4049 100644
--- a/Core/Shaders/Shader.cs
+++ b/Core/Shaders/Shader.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.IO;
using System.Collections.Generic;
@@ -31,7 +31,7 @@ public class Shader
///
/// The vertex shader full path.
/// The fragment shader full path.
- /// The identfier name of the shader.
+ /// The identifier name of the shader.
public Shader(string vertPath, string fragPath, string name)
{
Name = name;
@@ -44,10 +44,16 @@ public Shader(string vertPath, string fragPath, string name)
// Load and compile shader
if (!LoadShader(ShaderType.VertexShader, vertPath, out uint vertexShader))
+ {
+ Console.WriteLine("Unable to load vertex shader.");
return;
+ }
if (!LoadShader(ShaderType.FragmentShader, fragPath, out uint fragmentShader))
+ {
+ Console.WriteLine("Unable to load fragment shader.");
return;
+ }
// These two shaders must then be merged into a shader program, which can then be used by OpenGL.
// To do this, create a program...
@@ -59,7 +65,11 @@ public Shader(string vertPath, string fragPath, string name)
Window.GL.AttachShader(Handle, fragmentShader);
// And then link them together.
- LinkProgram(Handle);
+ if (!LinkProgram(Handle))
+ {
+ Console.WriteLine("Unable to link shader program.");
+ return;
+ }
// When the shader program is linked, it no longer needs the individual shaders attached to it; the compiled code is copied into the shader program.
// Detach them, and then delete them.
@@ -91,7 +101,12 @@ private static bool LoadShader(ShaderType shaderType, string shaderPath, out uin
// GL.CreateShader will create an empty shader (obviously). The ShaderType enum denotes which type of shader will be created.
shader = Window.GL.CreateShader(shaderType);
Window.GL.ShaderSource(shader, shaderSource);
- CompileShader(shader);
+
+ if (!CompileShader(shader))
+ {
+ Console.WriteLine($"Unable to load {shaderType} shader from '{shaderPath}'.");
+ return false;
+ }
return true;
}
@@ -102,7 +117,7 @@ private void GetUniformLocations()
Window.GL.GetProgram(Handle, GLEnum.ActiveUniforms, out var numberOfUniforms);
// Next, allocate the dictionary to hold the locations.
- _uniformLocations = new Dictionary();
+ _uniformLocations = [];
// Loop over all the uniforms,
for (uint i = 0; i < numberOfUniforms; i++)
@@ -129,31 +144,39 @@ private static string ProcessIncludes(string shaderCode, string directory)
});
}
- private static void CompileShader(uint shader)
+ private static bool CompileShader(uint shader)
{
// Try to compile the shader
Window.GL.CompileShader(shader);
// Check for compilation errors
- Window.GL.GetShader(shader, GLEnum.CompileStatus, out var code);
- if (code != (int)GLEnum.True)
+ Window.GL.GetShader(shader, GLEnum.CompileStatus, out var statusCode);
+ if (statusCode != (int)GLEnum.True)
{
// We can use `GL.GetShaderInfoLog(shader)` to get information about the error.
var infoLog = Window.GL.GetShaderInfoLog(shader);
- throw new InvalidOperationException($"Error occurred whilst compiling Shader({shader}).\n\n{infoLog}");
+ Console.WriteLine($"Error occurred whilst compiling Shader({shader}).\n\n{infoLog}");
+
+ return false;
}
+
+ return true;
}
- private static void LinkProgram(uint program)
+ private static bool LinkProgram(uint program)
{
Window.GL.LinkProgram(program);
-
- Window.GL.GetProgram(program, GLEnum.LinkStatus, out var code);
- if (code != (int)GLEnum.True)
+ Window.GL.GetProgram(program, GLEnum.LinkStatus, out var statusCode);
+
+ if (statusCode != (int)GLEnum.True)
{
string infoLog = Window.GL.GetProgramInfoLog(program);
- throw new InvalidOperationException($"Error occurred whilst linking Program({program}): {infoLog}");
+ Console.WriteLine($"Error occurred whilst linking Program({program}): {infoLog}");
+
+ return false;
}
+
+ return true;
}
///
@@ -166,14 +189,18 @@ public void Use()
/// Checks if the shader attribute exists within the current shader.
///
/// The name of the attribute that's being looked for.
- /// If the attribute exists, the location of the attribute in the shader; otherwise -1.
- public int GetAttribLocation(string attribName)
+ /// Outputs the location of the attribute in the shader if found; otherwise -1.
+ /// If the attribute exists, ; otherwise, .
+ public bool TryGetAttribLocation(string attribName, out int location)
{
- int location = Window.GL.GetAttribLocation(Handle, attribName);
- if (location == -1)
+ location = Window.GL.GetAttribLocation(Handle, attribName);
+ if (location == ShaderAttributes.AttributeLocationNotFound)
+ {
Console.WriteLine($"Attribute '{attribName}' not found in shader program.");
+ return false;
+ }
- return location;
+ return true;
}
// Uniform setters
diff --git a/Core/Shaders/UIShader.cs b/Core/Shaders/UIShader.cs
index 9e049a1..126b2fe 100644
--- a/Core/Shaders/UIShader.cs
+++ b/Core/Shaders/UIShader.cs
@@ -14,10 +14,9 @@ public UIShader()
public override bool SetAttributes()
{
if (!base.SetAttributes())
- return false;
+ return false;
- var vertexLocation = Shader!.GetAttribLocation(ShaderAttributes.Pos);
- if (vertexLocation == ShaderAttributes.AttributeLocationNotFound)
+ if (!Shader!.TryGetAttribLocation(ShaderAttributes.Pos, out int vertexLocation))
return false;
uint vertexLocationUInt = (uint)vertexLocation;
diff --git a/Core/SharpEngine.Core.csproj b/Core/SharpEngine.Core.csproj
index e93fd8f..1489ce2 100644
--- a/Core/SharpEngine.Core.csproj
+++ b/Core/SharpEngine.Core.csproj
@@ -3,10 +3,6 @@
Everything needed to build games using a purely C# game engine.
-
AnyCPU;x64;x86
$(GenerateNuGetPackages)
https://github.com/Av3boy/SharpEngine
@@ -15,8 +11,7 @@
$(AssemblyName).NET
- Debug;Release;LauncherNonWindows
-
+ Debug;Release;LauncherNonWindows
diff --git a/Core/SilkWindow.cs b/Core/SilkWindow.cs
index 23989da..cbb0cb8 100644
--- a/Core/SilkWindow.cs
+++ b/Core/SilkWindow.cs
@@ -1,20 +1,24 @@
-using SharpEngine.Core.Enums;
-using Silk.NET.Core;
+using Silk.NET.Core;
using Silk.NET.Core.Contexts;
using Silk.NET.Input;
using Silk.NET.Maths;
using Silk.NET.Windowing;
+using MouseButton = Silk.NET.Input.MouseButton;
+
using StbImageSharp;
+
using System;
using System.IO;
using System.Numerics;
-using MouseButton = Silk.NET.Input.MouseButton;
namespace SharpEngine.Core;
///
-/// Represents a class abstraction for the interface.
+/// Represents an abstraction for the interface.
///
+///
+/// For window initialization, see .
+///
public abstract class SilkWindow : IWindow
{
///
@@ -154,6 +158,9 @@ public string Title
///
public event Action? Render;
+ /// Raised after the scene has been rendered.
+ public event Action? OnAfterRender;
+
/// An event executed when the window has loaded.
public event Action? OnLoaded;
@@ -173,12 +180,25 @@ public IWindow CurrentWindow
}
///
+ // [Obsolete("Use the 'Create' implementation instead.")]
public IWindow CreateWindow(WindowOptions opts)
{
+ if (CurrentWindow is not null)
+ throw new InvalidOperationException("Window already created for this instance.");
+
CurrentWindow = Silk.NET.Windowing.Window.Create(opts);
return CurrentWindow;
}
+ public static T Create(WindowOptions opts) where T : SilkWindow, new()
+ {
+ var instance = new T();
+ var winndow = instance.CreateWindow(opts);
+
+ instance.CurrentWindow = winndow;
+ return instance;
+ }
+
///
protected virtual void Dispose(bool disposing) { }
@@ -260,7 +280,7 @@ public virtual void OnLoad()
/// Handles operations needed to be executed after the renderers are finished.
///
/// Time since the last frame.
- protected virtual void AfterRender(double deltaTime) { }
+ protected virtual void AfterRender(double deltaTime) => OnAfterRender?.Invoke(deltaTime);
///
/// Handles operations needed to be executed before the renderers are executed.
diff --git a/Core/Textures/TextureService.cs b/Core/Textures/TextureService.cs
index ae0e056..89b4bcf 100644
--- a/Core/Textures/TextureService.cs
+++ b/Core/Textures/TextureService.cs
@@ -1,4 +1,4 @@
-using StbImageSharp;
+using StbImageSharp;
using System.IO;
using System.Collections.Generic;
diff --git a/Core/Window.cs b/Core/Window.cs
index 29e9936..af4cd49 100644
--- a/Core/Window.cs
+++ b/Core/Window.cs
@@ -1,4 +1,4 @@
-using SharpEngine.Core.Entities.Properties.Meshes;
+using SharpEngine.Core.Entities.Properties.Meshes;
using SharpEngine.Core.Entities.Views;
using SharpEngine.Core.Entities.Views.Settings;
using SharpEngine.Core.Enums;
@@ -7,23 +7,20 @@
using SharpEngine.Core.Renderers;
using SharpEngine.Core.Scenes;
using SharpEngine.Core.Shaders;
-using Silk.NET.Core;
-using Silk.NET.GLFW;
+using Shader = SharpEngine.Core.Shaders.Shader;
+
using Silk.NET.Input;
using Silk.NET.Maths;
using Silk.NET.OpenGL;
using Silk.NET.OpenGL.Extensions.ImGui;
using Silk.NET.Windowing;
-using StbImageSharp;
+using MouseButton = Silk.NET.Input.MouseButton;
+
using System;
using System.Collections.Generic;
-using System.IO;
using System.Linq;
using System.Numerics;
-using System.Runtime.InteropServices;
using System.Threading.Tasks;
-using MouseButton = Silk.NET.Input.MouseButton;
-using Shader = SharpEngine.Core.Shaders.Shader;
namespace SharpEngine.Core;
@@ -32,7 +29,7 @@ namespace SharpEngine.Core;
///
public class Window : SilkWindow
{
- private readonly ISettings _settings;
+ private readonly IViewSettings _settings;
private readonly CameraView _camera;
private bool _initialized;
@@ -69,6 +66,7 @@ public class Window : SilkWindow
/// The OpenGL context for this window.
public static GL GetGL() => GL;
private static void SetGL(GL gl) => GL = gl;
+ public Window() { }
///
/// Initializes a new instance of .
@@ -81,8 +79,7 @@ public Window(CameraView camera, Scene scene, IViewSettings settings)
Scene = scene;
_settings = settings;
_camera = camera;
-
- Initialize(settings.WindowOptions);
+ Initialize();
}
///
@@ -94,14 +91,16 @@ public Window(Scene scene, IViewSettings settings)
{
Scene = scene;
_settings = settings;
- _camera = new(Vector3.One, new DefaultViewSettings());
-
- Initialize(settings.WindowOptions);
+ _camera = new(Vector3.One, settings);
+ Initialize();
}
- private void Initialize(WindowOptions options)
+ private bool _windowInitialized;
+
+ // public void Initialize() where T : SilkWindow, new()
+ private void Initialize()
{
- CurrentWindow = CreateWindow(options);
+ CurrentWindow = CreateWindow(_settings.WindowOptions);
CurrentWindow.Update += OnUpdateFrame;
CurrentWindow.Render += RenderFrame;
CurrentWindow.Resize += OnResize;
@@ -112,6 +111,9 @@ private void Initialize(WindowOptions options)
///
public override void Run(Action onFrame)
{
+ if (!_windowInitialized)
+ throw new Exception("Window not been initialized for this instance. Try calling 'window.Initialize()' first.");
+
try
{
base.Run(onFrame);
diff --git a/Editor/EditorWindow.cs b/Editor/EditorWindow.cs
index 92fe757..f5bc365 100644
--- a/Editor/EditorWindow.cs
+++ b/Editor/EditorWindow.cs
@@ -24,6 +24,8 @@ public class EditorWindow : Window
private ContextMenuWindow? _contextMenuWindow;
private ActionsMenuWindow? _actionsMenuWindow;
+ public EditorWindow() { }
+
///
/// Initializes an editor window with a specified scene and view settings.
///
@@ -40,48 +42,55 @@ public override void OnLoad()
{
base.OnLoad();
- // Test only: remove later.
- var cube = PrimitiveFactory.Create(PrimitiveType.Cube, new Vector3(3, 1, 1));
- cube.Name = "test";
-
- Scene.Root.Children.Add(cube);
-
- // Get all types that inherit from ImGuiWindowBase
- var windowTypes = Assembly.GetExecutingAssembly()
- .GetTypes()
- .Where(t => t.IsSubclassOf(typeof(ImGuiWindowBase)) && !t.IsAbstract)
- .ToArray();
-
- // Initialize all ImGuiWindowBase implementations
- for (int i = 0; i < windowTypes.Length; i++)
+ try
{
- try
- {
- var type = windowTypes[i];
- var window = Activator.CreateInstance(type) ??
- throw new InvalidOperationException($"Error initializing window: {type}");
+ // Test only: remove later.
+ var cube = PrimitiveFactory.Create(PrimitiveType.Cube, new Vector3(3, 1, 1));
+ cube.Name = "test";
- var windowBase = (ImGuiWindowBase)window;
- windowBase.SetScene(Scene);
- windowBase.SetProject(_project);
+ Scene.Root.Children.Add(cube);
- _windows.Add(windowBase);
- }
- catch (Exception e)
+ // Get all types that inherit from ImGuiWindowBase
+ var windowTypes = Assembly.GetExecutingAssembly()
+ .GetTypes()
+ .Where(t => t.IsSubclassOf(typeof(ImGuiWindowBase)) && !t.IsAbstract)
+ .ToArray();
+
+ // Initialize all ImGuiWindowBase implementations
+ for (int i = 0; i < windowTypes.Length; i++)
{
- Debug.LogInformation(e.Message, e);
+ try
+ {
+ var type = windowTypes[i];
+ var window = Activator.CreateInstance(type) ??
+ throw new InvalidOperationException($"Error initializing window: {type}");
+
+ var windowBase = (ImGuiWindowBase)window;
+ windowBase.SetScene(Scene);
+ windowBase.SetProject(_project);
+
+ _windows.Add(windowBase);
+ }
+ catch (Exception e)
+ {
+ Debug.LogInformation(e.Message, e);
+ }
}
- }
- _contextMenuWindow = (ContextMenuWindow?)_windows.FirstOrDefault(w => w.GetType() == typeof(ContextMenuWindow));
- if (_contextMenuWindow is null)
- Debug.LogInformation("ContextMenuWindow not found.");
+ _contextMenuWindow = (ContextMenuWindow?)_windows.FirstOrDefault(w => w.GetType() == typeof(ContextMenuWindow));
+ if (_contextMenuWindow is null)
+ Debug.LogInformation("ContextMenuWindow not found.");
- _actionsMenuWindow = (ActionsMenuWindow?)_windows.FirstOrDefault(w => w.GetType() == typeof(ActionsMenuWindow));
- if (_actionsMenuWindow is null)
- Debug.LogInformation("ActionsMenuWindow not found.");
- else
- _actionsMenuWindow.OnSceneLoaded += SetScene;
+ _actionsMenuWindow = (ActionsMenuWindow?)_windows.FirstOrDefault(w => w.GetType() == typeof(ActionsMenuWindow));
+ if (_actionsMenuWindow is null)
+ Debug.LogInformation("ActionsMenuWindow not found.");
+ else
+ _actionsMenuWindow.OnSceneLoaded += SetScene;
+ }
+ catch (Exception e)
+ {
+ Debug.LogInformation(e.Message, e);
+ }
}
///
diff --git a/Editor/Windows/ImGuiWindowBase.cs b/Editor/Windows/ImGuiWindowBase.cs
index d1579bb..c48c182 100644
--- a/Editor/Windows/ImGuiWindowBase.cs
+++ b/Editor/Windows/ImGuiWindowBase.cs
@@ -1,7 +1,13 @@
using ImGuiNET;
using Launcher.UI;
+using SharpEngine.Core.Entities.Views.Settings;
using SharpEngine.Core.Scenes;
+using Silk.NET.Input;
+using Silk.NET.Maths;
+using Silk.NET.OpenGL;
+using Silk.NET.OpenGL.Extensions.ImGui;
using Silk.NET.Windowing;
+using System.Threading;
namespace SharpEngine.Editor.Windows
{
@@ -56,14 +62,8 @@ public void RenderWindow()
// Check docking state
bool isDocked = ImGui.IsWindowDocked();
- if (_previousDockingStates.TryGetValue(Name, out bool wasDocked))
- {
- if (wasDocked && !isDocked)
- {
- // Window was undocked
- OnWindowUndocked();
- }
- }
+ if (_previousDockingStates.TryGetValue(Name, out bool wasDocked) && wasDocked && !isDocked)
+ OnWindowUndocked();
// Update previous docking state
_previousDockingStates[Name] = isDocked;
@@ -82,20 +82,30 @@ protected virtual void OnWindowUndocked()
private void CreateSilkWindow()
{
- // TODO: Use the Core window.
- var window = Window.Create(WindowOptions.Default with
+ try
{
- Title = Name
- });
+ var thread = new Thread(() =>
+ {
- window.Load += () =>
- {
- // TODO: Initialize the ImGui context like we do in the Core window.
- };
+ var window = new Core.Window(new(), new DefaultViewSettings());
- window.Render += delta => Render();
+ window.Closing += () => _previousDockingStates[Name] = false;
+ window.OnAfterRender += deltaTime =>
+ {
+ ImGui.Begin(Name, ImGuiWindowFlags);
+ Render();
+ ImGui.End();
+ };
- window.Run();
+ window.Run();
+ });
+
+ thread.Start();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine($"Failed to create window: {ex.Message}");
+ }
}
///
diff --git a/Examples/MultipleWindows/MultipleWindows.csproj b/Examples/MultipleWindows/MultipleWindows.csproj
new file mode 100644
index 0000000..f87a3eb
--- /dev/null
+++ b/Examples/MultipleWindows/MultipleWindows.csproj
@@ -0,0 +1,17 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+
diff --git a/Examples/MultipleWindows/Program.cs b/Examples/MultipleWindows/Program.cs
new file mode 100644
index 0000000..73a0908
--- /dev/null
+++ b/Examples/MultipleWindows/Program.cs
@@ -0,0 +1,45 @@
+using Silk.NET.Core.Native;
+using Silk.NET.GLFW;
+using Silk.NET.OpenGL;
+using Silk.NET.Windowing;
+
+internal class Program
+{
+ static void Main()
+ {
+ var options1 = WindowOptions.Default with { Title = "Window 1", WindowClass = "MyWindowClass1" };
+ var options2 = WindowOptions.Default with { Title = "Window 2", WindowClass = "MyWindowClass2" };
+
+ var window1 = Window.Create(options1);
+ var window2 = Window.Create(options2);
+
+ StartWindow(window1);
+ StartWindow(window2);
+ }
+
+ static void StartWindow(IWindow window)
+ {
+ var thread = new Thread(() =>
+ {
+ window.Load += () =>
+ {
+ Console.WriteLine($"Hello from window: " + window.Title);
+
+ var gl = GL.GetApi(window);
+
+ unsafe
+ {
+ var versionPtr = gl.GetString(StringName.Version);
+ string? version = SilkMarshal.PtrToString((nint)versionPtr);
+ Console.WriteLine($"OpenGL version: {version}");
+ }
+
+ };
+
+ window.Run();
+ });
+
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+ }
+}
diff --git a/SharpEngine.sln b/SharpEngine.sln
index 71f591f..8989e1a 100644
--- a/SharpEngine.sln
+++ b/SharpEngine.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
-VisualStudioVersion = 17.14.35906.104 d17.14
+VisualStudioVersion = 17.14.35906.104
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpEngine.Core", "Core\SharpEngine.Core.csproj", "{9A1984BA-6D84-374A-8BF0-A26A6493FEA9}"
EndProject
@@ -24,6 +24,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
README.md = README.md
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MultipleWindows", "Examples\MultipleWindows\MultipleWindows.csproj", "{0AF16D15-5BD2-4FED-9C6A-227DE6A56C5E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -70,6 +72,12 @@ Global
{1BEC06D8-094D-8BC2-288E-E2C4C13F3D2E}.LauncherNonWindows|Any CPU.Build.0 = Debug|Any CPU
{1BEC06D8-094D-8BC2-288E-E2C4C13F3D2E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1BEC06D8-094D-8BC2-288E-E2C4C13F3D2E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0AF16D15-5BD2-4FED-9C6A-227DE6A56C5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0AF16D15-5BD2-4FED-9C6A-227DE6A56C5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0AF16D15-5BD2-4FED-9C6A-227DE6A56C5E}.LauncherNonWindows|Any CPU.ActiveCfg = Release|Any CPU
+ {0AF16D15-5BD2-4FED-9C6A-227DE6A56C5E}.LauncherNonWindows|Any CPU.Build.0 = Release|Any CPU
+ {0AF16D15-5BD2-4FED-9C6A-227DE6A56C5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0AF16D15-5BD2-4FED-9C6A-227DE6A56C5E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -77,5 +85,6 @@ Global
GlobalSection(NestedProjects) = preSolution
{E8A75C3B-1D82-8B30-C854-AD35FB123CDC} = {B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}
{1BEC06D8-094D-8BC2-288E-E2C4C13F3D2E} = {B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}
+ {0AF16D15-5BD2-4FED-9C6A-227DE6A56C5E} = {B36A84DF-456D-A817-6EDD-3EC3E7F6E11F}
EndGlobalSection
EndGlobal