diff --git a/FinalEngine.Editor.Common/FinalEngine.Editor.Common.csproj b/FinalEngine.Editor.Common/FinalEngine.Editor.Common.csproj
index 1cbc5447..9721447b 100644
--- a/FinalEngine.Editor.Common/FinalEngine.Editor.Common.csproj
+++ b/FinalEngine.Editor.Common/FinalEngine.Editor.Common.csproj
@@ -30,4 +30,8 @@
+
+
+
+
diff --git a/FinalEngine.Editor.Common/GlobalSuppressions.cs b/FinalEngine.Editor.Common/GlobalSuppressions.cs
new file mode 100644
index 00000000..f52f45a5
--- /dev/null
+++ b/FinalEngine.Editor.Common/GlobalSuppressions.cs
@@ -0,0 +1,8 @@
+//
+// Copyright (c) Software Antics. All rights reserved.
+//
+
+using System.Diagnostics.CodeAnalysis;
+
+[assembly: SuppressMessage("Performance", "CA1848:Use the LoggerMessage delegates", Justification = "KISS")]
+[assembly: SuppressMessage("Usage", "CA2254:Template should be a static expression", Justification = "KISS")]
diff --git a/FinalEngine.Editor.Common/Services/Scenes/ISceneRenderer.cs b/FinalEngine.Editor.Common/Services/Scenes/ISceneRenderer.cs
new file mode 100644
index 00000000..5b7c2947
--- /dev/null
+++ b/FinalEngine.Editor.Common/Services/Scenes/ISceneRenderer.cs
@@ -0,0 +1,16 @@
+//
+// Copyright (c) Software Antics. All rights reserved.
+//
+
+namespace FinalEngine.Editor.Common.Services.Scenes;
+
+///
+/// Defines an interface that renders a scene.
+///
+public interface ISceneRenderer
+{
+ ///
+ /// Renders the scene.
+ ///
+ void Render();
+}
diff --git a/FinalEngine.Editor.Common/Services/Scenes/SceneRenderer.cs b/FinalEngine.Editor.Common/Services/Scenes/SceneRenderer.cs
new file mode 100644
index 00000000..65563976
--- /dev/null
+++ b/FinalEngine.Editor.Common/Services/Scenes/SceneRenderer.cs
@@ -0,0 +1,41 @@
+//
+// Copyright (c) Software Antics. All rights reserved.
+//
+
+namespace FinalEngine.Editor.Common.Services.Scenes;
+
+using System;
+using System.Drawing;
+using FinalEngine.Rendering;
+
+///
+/// Provides a standard implementation of an .
+///
+///
+public sealed class SceneRenderer : ISceneRenderer
+{
+ ///
+ /// The render device.
+ ///
+ private readonly IRenderDevice renderDevice;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The render device.
+ ///
+ ///
+ /// The specified parameter cannot be null.
+ ///
+ public SceneRenderer(IRenderDevice renderDevice)
+ {
+ this.renderDevice = renderDevice ?? throw new ArgumentNullException(nameof(renderDevice));
+ }
+
+ ///
+ public void Render()
+ {
+ this.renderDevice.Clear(Color.FromArgb(255, 30, 30, 30));
+ }
+}
diff --git a/FinalEngine.Editor.Desktop/App.xaml.cs b/FinalEngine.Editor.Desktop/App.xaml.cs
index d609e2ad..9a8f31ae 100644
--- a/FinalEngine.Editor.Desktop/App.xaml.cs
+++ b/FinalEngine.Editor.Desktop/App.xaml.cs
@@ -7,10 +7,10 @@ namespace FinalEngine.Editor.Desktop;
using System.Diagnostics;
using System.IO.Abstractions;
using System.Windows;
-using CommunityToolkit.Mvvm.Messaging;
using FinalEngine.Editor.Common.Extensions;
using FinalEngine.Editor.Common.Services.Application;
using FinalEngine.Editor.Common.Services.Environment;
+using FinalEngine.Editor.Common.Services.Scenes;
using FinalEngine.Editor.Desktop.Services.Actions;
using FinalEngine.Editor.Desktop.Services.Factories.Layout;
using FinalEngine.Editor.Desktop.Views;
@@ -25,6 +25,8 @@ namespace FinalEngine.Editor.Desktop;
using FinalEngine.Editor.ViewModels.Interactions;
using FinalEngine.Editor.ViewModels.Services.Actions;
using FinalEngine.Editor.ViewModels.Services.Factories.Layout;
+using FinalEngine.Rendering;
+using FinalEngine.Rendering.OpenGL;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
@@ -102,11 +104,13 @@ private static void ConfigureServices(HostBuilderContext context, IServiceCollec
builder.AddConsole().SetMinimumLevel(Debugger.IsAttached ? LogLevel.Debug : LogLevel.Information);
});
+ services.AddSingleton();
+
services.AddSingleton();
- services.AddSingleton(WeakReferenceMessenger.Default);
services.AddSingleton();
services.AddSingleton();
+ services.AddSingleton();
services.AddFactory();
services.AddFactory();
diff --git a/FinalEngine.Editor.Desktop/FinalEngine.Editor.Desktop.csproj b/FinalEngine.Editor.Desktop/FinalEngine.Editor.Desktop.csproj
index ed1fdbd5..d8c412a1 100644
--- a/FinalEngine.Editor.Desktop/FinalEngine.Editor.Desktop.csproj
+++ b/FinalEngine.Editor.Desktop/FinalEngine.Editor.Desktop.csproj
@@ -28,6 +28,7 @@
+
all
@@ -43,6 +44,7 @@
+
diff --git a/FinalEngine.Editor.Desktop/Views/Scenes/SceneView.xaml b/FinalEngine.Editor.Desktop/Views/Scenes/SceneView.xaml
index 2ec8bdcd..15be9a02 100644
--- a/FinalEngine.Editor.Desktop/Views/Scenes/SceneView.xaml
+++ b/FinalEngine.Editor.Desktop/Views/Scenes/SceneView.xaml
@@ -3,9 +3,23 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
+ xmlns:eb="clr-namespace:EventBinder;assembly=EventBinder"
xmlns:vm="clr-namespace:FinalEngine.Editor.ViewModels.Docking.Panes.Scenes;assembly=FinalEngine.Editor.ViewModels"
+ xmlns:glwpf="clr-namespace:OpenTK.Wpf;assembly=GLWpfControl"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=vm:SceneViewPaneViewModel}">
+
+
+
+
+
diff --git a/FinalEngine.Editor.Desktop/Views/Scenes/SceneView.xaml.cs b/FinalEngine.Editor.Desktop/Views/Scenes/SceneView.xaml.cs
index 62f25d52..2f994263 100644
--- a/FinalEngine.Editor.Desktop/Views/Scenes/SceneView.xaml.cs
+++ b/FinalEngine.Editor.Desktop/Views/Scenes/SceneView.xaml.cs
@@ -17,5 +17,6 @@ public partial class SceneView : UserControl
public SceneView()
{
this.InitializeComponent();
+ this.glWpfControl.Start();
}
}
diff --git a/FinalEngine.Editor.ViewModels/Docking/Panes/Scenes/ISceneViewPaneViewModel.cs b/FinalEngine.Editor.ViewModels/Docking/Panes/Scenes/ISceneViewPaneViewModel.cs
index 47c9c38c..8d6b22d8 100644
--- a/FinalEngine.Editor.ViewModels/Docking/Panes/Scenes/ISceneViewPaneViewModel.cs
+++ b/FinalEngine.Editor.ViewModels/Docking/Panes/Scenes/ISceneViewPaneViewModel.cs
@@ -4,10 +4,22 @@
namespace FinalEngine.Editor.ViewModels.Docking.Panes.Scenes;
+using System.Windows.Input;
+
///
/// Defines an interface that represents a model of the scene view pane.
///
///
public interface ISceneViewPaneViewModel : IPaneViewModel
{
+ ///
+ /// Gets the render command.
+ ///
+ ///
+ /// The render command.
+ ///
+ ///
+ /// The is used to render the currently active scene.
+ ///
+ ICommand RenderCommand { get; }
}
diff --git a/FinalEngine.Editor.ViewModels/Docking/Panes/Scenes/SceneViewPaneViewModel.cs b/FinalEngine.Editor.ViewModels/Docking/Panes/Scenes/SceneViewPaneViewModel.cs
index 45a82426..bf0bf34b 100644
--- a/FinalEngine.Editor.ViewModels/Docking/Panes/Scenes/SceneViewPaneViewModel.cs
+++ b/FinalEngine.Editor.ViewModels/Docking/Panes/Scenes/SceneViewPaneViewModel.cs
@@ -5,6 +5,9 @@
namespace FinalEngine.Editor.ViewModels.Docking.Panes.Scenes;
using System;
+using System.Windows.Input;
+using CommunityToolkit.Mvvm.Input;
+using FinalEngine.Editor.Common.Services.Scenes;
using Microsoft.Extensions.Logging;
///
@@ -14,22 +17,53 @@ namespace FinalEngine.Editor.ViewModels.Docking.Panes.Scenes;
///
public sealed class SceneViewPaneViewModel : PaneViewModelBase, ISceneViewPaneViewModel
{
+ ///
+ /// The scene renderer, used to render the current scene.
+ ///
+ private readonly ISceneRenderer sceneRenderer;
+
+ ///
+ /// The render command, used to render the current scene.
+ ///
+ private ICommand? renderCommand;
+
///
/// Initializes a new instance of the class.
///
///
/// The logger.
///
- public SceneViewPaneViewModel(ILogger logger)
+ ///
+ /// The scene renderer used to render the currently active scene.
+ ///
+ public SceneViewPaneViewModel(
+ ILogger logger,
+ ISceneRenderer sceneRenderer)
{
if (logger == null)
{
throw new ArgumentNullException(nameof(logger));
}
+ this.sceneRenderer = sceneRenderer ?? throw new ArgumentNullException(nameof(sceneRenderer));
+
this.Title = "Scene View";
this.ContentID = "SceneView";
logger.LogInformation($"Initializing {this.Title}...");
}
+
+ ///
+ public ICommand RenderCommand
+ {
+ get { return this.renderCommand ??= new RelayCommand(this.Render); }
+ }
+
+ ///
+ /// Renders the currently active scene.
+ ///
+ private void Render()
+ {
+ this.sceneRenderer.Render();
+ }
}
diff --git a/FinalEngine.Examples.Game/Program.cs b/FinalEngine.Examples.Game/Program.cs
index 75866043..edb70ee1 100644
--- a/FinalEngine.Examples.Game/Program.cs
+++ b/FinalEngine.Examples.Game/Program.cs
@@ -73,7 +73,7 @@ internal static void Main()
var gameTime = new GameTime(120.0d);
resourceManager.RegisterLoader(new SoundResourceLoader(fileSystem));
- resourceManager.RegisterLoader(new ShaderResourceLoader(renderDevice.Factory, fileSystem));
+ resourceManager.RegisterLoader(new ShaderResourceLoader(fileSystem, renderDevice.Factory));
resourceManager.RegisterLoader(new Texture2DResourceLoader(fileSystem, renderDevice.Factory));
displayManager.ChangeResolution(DisplayResolution.HighDefinition);
diff --git a/FinalEngine.Extensions.Resources/Loaders/Shaders/ShaderResourceLoader.cs b/FinalEngine.Extensions.Resources/Loaders/Shaders/ShaderResourceLoader.cs
index ab534973..a06059af 100644
--- a/FinalEngine.Extensions.Resources/Loaders/Shaders/ShaderResourceLoader.cs
+++ b/FinalEngine.Extensions.Resources/Loaders/Shaders/ShaderResourceLoader.cs
@@ -29,16 +29,16 @@ public sealed class ShaderResourceLoader : ResourceLoaderBase
///
/// Initializes a new instance of the class.
///
- ///
- /// The GPU resource factory, used to load shaders into memory.
- ///
///
/// The file system, used to load shader source code into memory.
///
+ ///
+ /// The GPU resource factory, used to load shaders into memory.
+ ///
///
/// The specified or parameter cannot be null.
///
- public ShaderResourceLoader(IGPUResourceFactory factory, IFileSystem fileSystem)
+ public ShaderResourceLoader(IFileSystem fileSystem, IGPUResourceFactory factory)
{
this.factory = factory ?? throw new ArgumentNullException(nameof(factory));
this.fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
diff --git a/FinalEngine.Tests/Editor/Common/Services/Rendering/SceneRendererTests.cs b/FinalEngine.Tests/Editor/Common/Services/Rendering/SceneRendererTests.cs
new file mode 100644
index 00000000..d028228b
--- /dev/null
+++ b/FinalEngine.Tests/Editor/Common/Services/Rendering/SceneRendererTests.cs
@@ -0,0 +1,47 @@
+//
+// Copyright (c) Software Antics. All rights reserved.
+//
+
+namespace FinalEngine.Tests.Editor.Common.Services.Rendering;
+
+using System;
+using System.Drawing;
+using FinalEngine.Editor.Common.Services.Scenes;
+using FinalEngine.Rendering;
+using Moq;
+using NUnit.Framework;
+
+[TestFixture]
+public sealed class SceneRendererTests
+{
+ private Mock renderDevice;
+
+ private SceneRenderer sceneRenderer;
+
+ [Test]
+ public void ConstructorShouldThrowArgumentNullExceptionWhenRenderDeviceIsNull()
+ {
+ // Act and assert
+ Assert.Throws(() =>
+ {
+ new SceneRenderer(null);
+ });
+ }
+
+ [Test]
+ public void RenderShouldInvokeRenderDeviceClearWhenInvoked()
+ {
+ // Act
+ this.sceneRenderer.Render();
+
+ // Assert
+ this.renderDevice.Verify(x => x.Clear(Color.FromArgb(255, 30, 30, 30), 1, 0), Times.Once);
+ }
+
+ [SetUp]
+ public void Setup()
+ {
+ this.renderDevice = new Mock();
+ this.sceneRenderer = new SceneRenderer(this.renderDevice.Object);
+ }
+}
diff --git a/FinalEngine.Tests/Editor/ViewModels/Docking/Panes/Scenes/SceneViewPaneViewModelTests.cs b/FinalEngine.Tests/Editor/ViewModels/Docking/Panes/Scenes/SceneViewPaneViewModelTests.cs
index 00ac3bbd..43089bb0 100644
--- a/FinalEngine.Tests/Editor/ViewModels/Docking/Panes/Scenes/SceneViewPaneViewModelTests.cs
+++ b/FinalEngine.Tests/Editor/ViewModels/Docking/Panes/Scenes/SceneViewPaneViewModelTests.cs
@@ -5,6 +5,7 @@
namespace FinalEngine.Tests.Editor.ViewModels.Docking.Panes.Scenes;
using System;
+using FinalEngine.Editor.Common.Services.Scenes;
using FinalEngine.Editor.ViewModels.Docking.Panes.Scenes;
using Microsoft.Extensions.Logging;
using Moq;
@@ -15,6 +16,8 @@ public sealed class SceneViewPaneViewModelTests
{
private Mock> logger;
+ private Mock sceneRenderer;
+
private SceneViewPaneViewModel viewModel;
[Test]
@@ -48,14 +51,34 @@ public void ConstructorShouldThrowArgumentNullExceptionWhenLoggerIsNull()
{
Assert.Throws(() =>
{
- new SceneViewPaneViewModel(null);
+ new SceneViewPaneViewModel(null, this.sceneRenderer.Object);
+ });
+ }
+
+ [Test]
+ public void ConstructorShouldThrowArgumentNullExceptionWhenSceneRendererIsNull()
+ {
+ Assert.Throws(() =>
+ {
+ new SceneViewPaneViewModel(this.logger.Object, null);
});
}
+ [Test]
+ public void RenderCommandExecuteShouldInvokeSceneRendererRenderWhenInvoked()
+ {
+ // Act
+ this.viewModel.RenderCommand.Execute(null);
+
+ // Assert
+ this.sceneRenderer.Verify(x => x.Render(), Times.Once);
+ }
+
[SetUp]
public void Setup()
{
this.logger = new Mock>();
- this.viewModel = new SceneViewPaneViewModel(this.logger.Object);
+ this.sceneRenderer = new Mock();
+ this.viewModel = new SceneViewPaneViewModel(this.logger.Object, this.sceneRenderer.Object);
}
}
diff --git a/FinalEngine.Tests/Extensions/Resources/Loaders/Shaders/ShaderResourceLoaderTests.cs b/FinalEngine.Tests/Extensions/Resources/Loaders/Shaders/ShaderResourceLoaderTests.cs
index f6477730..220fd257 100644
--- a/FinalEngine.Tests/Extensions/Resources/Loaders/Shaders/ShaderResourceLoaderTests.cs
+++ b/FinalEngine.Tests/Extensions/Resources/Loaders/Shaders/ShaderResourceLoaderTests.cs
@@ -30,7 +30,7 @@ public void ConstructorShouldThrowArgumentNullExceptionWhenFactoryIsNull()
// Act and assert
Assert.Throws(() =>
{
- new ShaderResourceLoader(null, this.fileSystem);
+ new ShaderResourceLoader(this.fileSystem, null);
});
}
@@ -40,7 +40,7 @@ public void ConstructorShouldThrowArgumentNullExceptionWhenFileSystemIsNull()
// Act and assert
Assert.Throws(() =>
{
- new ShaderResourceLoader(this.factory.Object, null);
+ new ShaderResourceLoader(null, this.factory.Object);
});
}
@@ -149,6 +149,6 @@ public void Setup()
this.factory.Setup(x => x.CreateShader(It.IsAny(), It.IsAny())).Returns(this.shader.Object);
- this.loader = new ShaderResourceLoader(this.factory.Object, this.fileSystem);
+ this.loader = new ShaderResourceLoader(this.fileSystem, this.factory.Object);
}
}
diff --git a/SharedAssemblyInfo.cs b/SharedAssemblyInfo.cs
index 98e8aae4..c67831b0 100644
--- a/SharedAssemblyInfo.cs
+++ b/SharedAssemblyInfo.cs
@@ -9,8 +9,8 @@
[assembly: AssemblyCopyright("© 2023 Software Antics")]
[assembly: AssemblyTrademark("Software Antics™")]
[assembly: AssemblyCulture("")]
-[assembly: AssemblyVersion("2023.3.1924.0")]
-[assembly: AssemblyFileVersion("2023.3.1924.0")]
+[assembly: AssemblyVersion("2023.3.2334.0")]
+[assembly: AssemblyFileVersion("2023.3.2333.0")]
#if DEBUG
[assembly: AssemblyConfiguration("Debug")]
#else