diff --git a/TestGame/Circle2d.cs b/TestGame/Circle2d.cs deleted file mode 100644 index 9a06e7d..0000000 --- a/TestGame/Circle2d.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Voile.Rendering; -using Voile.SceneGraph; - -namespace Voile; - -public class Circle2d : Drawable2d -{ - public override void OnDraw(RenderSystem renderer) - { - renderer.DrawCircle(32f, Color.AliceBlue); - } -} \ No newline at end of file diff --git a/TestGame/TestGame.cs b/TestGame/TestGame.cs index 7a33a1d..d49439e 100644 --- a/TestGame/TestGame.cs +++ b/TestGame/TestGame.cs @@ -4,6 +4,7 @@ using Voile.Utils; using Voile.Input; using Voile.Systems.Particles; using System.Numerics; +using System.Diagnostics.CodeAnalysis; public class TestGame : Game { @@ -12,6 +13,7 @@ public class TestGame : Game public override void Initialize() { InitializeDefault(); + _particleSystem = new ParticleSystem(); ResourceManager.AddResourceLoaderAssociation(new ParticleEmitterSettingsResourceLoader()); @@ -33,13 +35,13 @@ public class TestGame : Game if (!ResourceManager.TryLoad("test_emitter.toml", out _emitterSettings)) { - + throw new Exception("Failed to load emitter settings!"); } } protected override void Ready() { - _emitterId = _particleSystem!.CreateEmitter(Renderer.WindowSize / 2, _emitterSettings); + _emitterId = _particleSystem.CreateEmitter(Renderer.WindowSize / 2, _emitterSettings); } protected override void Run() @@ -87,8 +89,8 @@ public class TestGame : Game Renderer.EndBlended(); } - private ParticleSystem? _particleSystem; + [NotNull] private ParticleSystem _particleSystem; private int _emitterId; - private ResourceRef? _emitterSettings; + private ResourceRef _emitterSettings; private Logger _logger = new(nameof(TestGame)); } \ No newline at end of file diff --git a/TestGame/TestGame.csproj b/TestGame/TestGame.csproj index 0718771..d2bdf28 100644 --- a/TestGame/TestGame.csproj +++ b/TestGame/TestGame.csproj @@ -4,7 +4,7 @@ Exe net7.0 enable - enable + disable true win-x64;linux-x64 diff --git a/TestGame/TestPlayer.cs b/TestGame/TestPlayer.cs deleted file mode 100644 index 6866d25..0000000 --- a/TestGame/TestPlayer.cs +++ /dev/null @@ -1,44 +0,0 @@ -using Voile; -using Voile.Extensions; -using Voile.SceneGraph; -using Voile.Utils; - -public class TestPlayer : RectangleShape2d -{ - public float SprintSpeed { get; set; } = 400f; - protected override void OnStart() - { - base.OnStart(); - Color = Color.Cyan; - - _camera = new Camera2d() - { - Current = true, - }; - - if (Layer is not null) - { - Layer.AddEntity(_camera); - } - } - - protected override void OnUpdate(double dt) - { - base.OnUpdate(dt); - - var sprinting = Input.IsActionDown("sprint"); - _speed = sprinting ? SprintSpeed : 200f; - - var velocity = Input.GetInputDirection("left", "right", "up", "down") * _speed; - Position += velocity * (float)dt; - - if (_camera is not null) - { - _camera.Position = _camera.Position.Lerp(Position, dt * 5f); - } - } - - private Logger _logger = new(nameof(TestPlayer)); - private float _speed = 200f; - private Camera2d? _camera; -} \ No newline at end of file diff --git a/TestGame/UiLayer.cs b/TestGame/UiLayer.cs deleted file mode 100644 index 6a6d69e..0000000 --- a/TestGame/UiLayer.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System.Numerics; -using Voile; -using Voile.Rendering; -using Voile.SceneGraph; -using Voile.UI; -using Voile.Utils; - -public class UiLayer : Layer -{ - protected override void OnStart() - { - base.OnStart(); - - GetResources(); - CreateUiElements(); - } - - protected override void OnUpdate(double dt) - { - base.OnUpdate(dt); - if (Scene is null) return; - _screenContainer.UpdateRect(Vector2.Zero, Scene.Renderer.WindowSize); - } - - protected override void OnBeginDraw(RenderSystem renderer) - { - - } - - protected override void OnDraw(RenderSystem renderer) - { - _screenContainer.Render(renderer); - } - - protected override void OnEndDraw(RenderSystem renderer) - { - - } - - private void CreateUiElements() - { - if (Scene is null) return; - - _screenContainer.UpdateRect(Vector2.Zero, Scene.Renderer.WindowSize); - - var style = new PanelStyle() - { - BackgroundColor = new Color(0.2f, 0.2f, 0.2f, 1.0f) - }; - - _panel = new MarginPanel(style) - { - ExpandRatio = new Vector2(0.5f, 1f), - AbsoluteMargin = Vector2.One * 16f - }; - _screenContainer.AddChild(_panel); - - var exampleText = new TextLabel() - { - Font = _defaultFont!, - FontSize = 20, - Text = "This Panel will occupy 50% of the screen.\nThis text in particular is inside a panel with an absolute margin of 16px.\nHow cool is that?" - }; - - var contentPanel = new MarginPanel(new PanelStyle() - { - BackgroundColor = new Color(0.25f, 0.25f, 0.25f, 1.0f) - }) - { - AbsoluteMargin = Vector2.One * 32f - }; - - _panel.AddChild(contentPanel); - - var verticalPanel = new MarginPanel(new PanelStyle() - { - BackgroundColor = new Color(0.1f, 0.1f, 0.1f, 1.0f), - }) - { - AbsoluteMargin = Vector2.One * 8f, - }; - - contentPanel.AddChild(verticalPanel); - verticalPanel.AddChild(exampleText); - } - - private void GetResources() - { - ResourceManager.TryGetResource("inter_regular", out _defaultFont); - } - - - private Font? _defaultFont; - private Container _screenContainer = new(); - private Panel? _panel; - - private Logger _logger = new(nameof(UiLayer)); -} \ No newline at end of file diff --git a/TestGame/World.cs b/TestGame/World.cs deleted file mode 100644 index 1074be4..0000000 --- a/TestGame/World.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Numerics; -using Voile; -using Voile.Rendering; -using Voile.SceneGraph; - -public class World : Drawable2d -{ - protected override void OnStart() - { - base.OnStart(); - - _randomPositions = new Vector2[_rectangleAmount]; - for (int i = 0; i < _rectangleAmount - 1; i++) - { - _randomPositions[i] = MathUtils.RandomVector2(Position, Vector2.One * 2048f); - } - } - public override void OnDraw(RenderSystem renderer) - { - for (int i = 0; i < _rectangleAmount; i++) - { - renderer.SetTransform(_randomPositions[i], PivotOffset, 0); - renderer.DrawRectangle(Vector2.One * 16f, _rectangleColor); - } - } - - private Color _rectangleColor = new Color(0.25f, 0.25f, 0.25f, 1.0f); - private int _rectangleAmount = 6000; - private Vector2[] _randomPositions; -} \ No newline at end of file diff --git a/Voile/Source/Game.cs b/Voile/Source/Game.cs index 0d6012a..505d3a2 100644 --- a/Voile/Source/Game.cs +++ b/Voile/Source/Game.cs @@ -67,6 +67,21 @@ namespace Voile /// public void Start() { + if (Renderer is null) + { + throw new NullReferenceException("No renderer provided."); + } + + if (Input is null) + { + throw new NullReferenceException("No input system provided."); + } + + if (ResourceManager is null) + { + throw new NullReferenceException("No ResourceManager provided."); + } + Initialize(); LoadResources(); Ready(); diff --git a/Voile/Source/Rendering/StandardRenderSystem.cs b/Voile/Source/Rendering/StandardRenderSystem.cs index 3ee0111..b0555f8 100644 --- a/Voile/Source/Rendering/StandardRenderSystem.cs +++ b/Voile/Source/Rendering/StandardRenderSystem.cs @@ -15,7 +15,7 @@ namespace Voile.Rendering public class StandardRenderSystem : RenderSystem { /// - public override Vector2 WindowSize { get; set; } + public override Vector2 WindowSize { get => _windowSize; set { _windowSize = value; } } /// public override bool ShouldRun => !_window?.IsClosing ?? false; @@ -189,7 +189,7 @@ namespace Voile.Rendering private unsafe void CreateApi() { - _wgpu = WebGPU.GetApi(); + _wgpu = WebGPU.GetApi() ?? throw new Exception("Failed to initialize WebGPU API."); } private unsafe void CreateInstance() @@ -205,6 +205,11 @@ namespace Voile.Rendering private unsafe void CreateAdapter() { + if (_wgpu is null) + { + throw new Exception("WebGPU API is not initialized!"); + } + RequestAdapterOptions adapterOptions = new() { CompatibleSurface = _surface, @@ -224,13 +229,13 @@ namespace Voile.Rendering _wgpu.AdapterGetProperties(_adapter, &adapterProperties); - string deviceName = Marshal.PtrToStringAnsi((IntPtr)adapterProperties.Name); + string deviceName = Marshal.PtrToStringAnsi((IntPtr)adapterProperties.Name) ?? string.Empty; _logger.Info($"Retrieved WebGPU Adapter ({deviceName})"); } else { - string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr); + string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr) ?? string.Empty; _logger.Error($"Error while retrieving WebGPU Adapter: {msg}"); } }); @@ -240,6 +245,11 @@ namespace Voile.Rendering private unsafe void CreateDevice() { + if (_wgpu is null) + { + throw new Exception("WebGPU API is not initialized!"); + } + DeviceDescriptor deviceDescriptor = new(); PfnRequestDeviceCallback callback = PfnRequestDeviceCallback.From( @@ -252,7 +262,7 @@ namespace Voile.Rendering } else { - string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr); + string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr) ?? string.Empty; _logger.Error($"Error while retrieving WebGPU Device: {msg}"); } }); @@ -262,6 +272,11 @@ namespace Voile.Rendering private unsafe void ConfigureSurface() { + if (_wgpu is null) + { + throw new Exception("WebGPU API is not initialized!"); + } + SurfaceConfiguration configuration = new SurfaceConfiguration { Device = _device, @@ -272,14 +287,19 @@ namespace Voile.Rendering Usage = TextureUsage.RenderAttachment }; - _wgpu!.SurfaceConfigure(_surface, configuration); + _wgpu.SurfaceConfigure(_surface, configuration); } private unsafe void ConfigureDebugCallback() { + if (_wgpu is null) + { + throw new Exception("WebGPU API is not initialized!"); + } + PfnErrorCallback callback = PfnErrorCallback.From((type, msgPtr, userDataPtr) => { - string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr); + string msg = Marshal.PtrToStringAnsi((IntPtr)msgPtr) ?? string.Empty; _logger.Error($"WebGPU Error: {msg}"); }); @@ -289,6 +309,11 @@ namespace Voile.Rendering private unsafe void WgpuBeginFrame() { + if (_wgpu is null) + { + throw new Exception("WebGPU API is not initialized!"); + } + _queue = _wgpu.DeviceGetQueue(_device); _commandEncoder = _wgpu.DeviceCreateCommandEncoder(_device, null); @@ -309,6 +334,11 @@ namespace Voile.Rendering private unsafe void WgpuEndFrame() { + if (_wgpu is null) + { + throw new Exception("WebGPU API is not initialized!"); + } + _wgpu.RenderPassEncoderEnd(_renderPassEncoder); var commandBuffer = _wgpu.CommandEncoderFinish(_commandEncoder, null); _wgpu.CommandEncoderRelease(_commandEncoder); @@ -325,7 +355,7 @@ namespace Voile.Rendering private unsafe void ShutdownUnsafe() { - _wgpu.DeviceDestroy(_device); + _wgpu!.DeviceDestroy(_device); _wgpu.InstanceRelease(_instance); _wgpu.SurfaceRelease(_surface); _wgpu.AdapterRelease(_adapter); @@ -365,7 +395,7 @@ namespace Voile.Rendering } - private Vector2 _windowSize; + private Vector2 _windowSize = Vector2.Zero; private IWindow? _window; private Color _clearColor = Color.Black; diff --git a/Voile/Source/SceneGraph/Camera2d.cs b/Voile/Source/SceneGraph/Camera2d.cs deleted file mode 100644 index f8091d1..0000000 --- a/Voile/Source/SceneGraph/Camera2d.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.Numerics; - -namespace Voile.SceneGraph; - -public class Camera2d : Entity2d -{ - public Vector2 Offset { get; set; } - public float Zoom { get; set; } = 1f; - public bool Current - { - get => _current; set - { - _current = value; - Layer?.UpdateCurrentCamera(); - } - } - - protected override void OnStart() - { - base.OnStart(); - Offset = Renderer.WindowSize / 2; - } - - private bool _current; -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Entities/CircleShape2d.cs b/Voile/Source/SceneGraph/Entities/CircleShape2d.cs deleted file mode 100644 index dee3731..0000000 --- a/Voile/Source/SceneGraph/Entities/CircleShape2d.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Voile.Rendering; - -namespace Voile.SceneGraph -{ - public class CircleShape2d : Drawable2d - { - public float Radius { get => _radius; set => _radius = value; } - public Color Color { get => _color; set => _color = value; } - - public override void OnDraw(RenderSystem renderer) - { - renderer.DrawCircle(_radius, _color); - } - - private float _radius = 16; - private Color _color = Color.White; - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Entities/Drawable2d.cs b/Voile/Source/SceneGraph/Entities/Drawable2d.cs deleted file mode 100644 index b1bb6ff..0000000 --- a/Voile/Source/SceneGraph/Entities/Drawable2d.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System.Numerics; -using Voile.Rendering; - -namespace Voile.SceneGraph -{ - public abstract class Drawable2d : Entity2d, IDrawable - { - public Vector2 PivotOffset { get; set; } - public void Draw(RenderSystem renderer) - { - renderer.SetTransform(Position, PivotOffset, Rotation); - OnDraw(renderer); - } - - public abstract void OnDraw(RenderSystem renderer); - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Entities/Entity.cs b/Voile/Source/SceneGraph/Entities/Entity.cs deleted file mode 100644 index bb5fd02..0000000 --- a/Voile/Source/SceneGraph/Entities/Entity.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Text.Json.Serialization; -using Voile.Audio; -using Voile.Input; -using Voile.Rendering; - -namespace Voile.SceneGraph -{ - public class Entity - { - [JsonIgnore] public EntityLayer? Layer { get; set; } - [JsonIgnore] public InputSystem Input => Layer!.Scene.Input; - [JsonIgnore] public AudioSystem Audio => Layer!.Scene.Audio; - [JsonIgnore] public RenderSystem Renderer => Layer!.Scene.Renderer; - public int Id { get; set; } - - public void Start() => OnStart(); - public void Update(double dt) => OnUpdate(dt); - public void ReceiveInput(InputSystem input) => OnInput(input); - - protected virtual void OnStart() { } - protected virtual void OnDestroy() { } - protected virtual void OnUpdate(double dt) { } - protected virtual void OnInput(InputSystem input) { } - - public void Destroy() - { - OnDestroy(); - Layer?.DestroyEntity(Id); - } - } - - [JsonSourceGenerationOptions(WriteIndented = true)] - [JsonSerializable(typeof(Entity))] - internal partial class EntitySourceGenerationContext : JsonSerializerContext - { - - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Entities/Entity2d.cs b/Voile/Source/SceneGraph/Entities/Entity2d.cs deleted file mode 100644 index 6a0d58b..0000000 --- a/Voile/Source/SceneGraph/Entities/Entity2d.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Numerics; - -namespace Voile.SceneGraph -{ - public class Entity2d : Entity - { - public Vector2 Position { get; set; } - public float Rotation { get; set; } - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Entities/IDrawable.cs b/Voile/Source/SceneGraph/Entities/IDrawable.cs deleted file mode 100644 index 2c92de0..0000000 --- a/Voile/Source/SceneGraph/Entities/IDrawable.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Voile.Rendering; - -namespace Voile.SceneGraph -{ - public interface IDrawable - { - public void Draw(RenderSystem renderer); - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Entities/RectangleShape2d.cs b/Voile/Source/SceneGraph/Entities/RectangleShape2d.cs deleted file mode 100644 index 249d243..0000000 --- a/Voile/Source/SceneGraph/Entities/RectangleShape2d.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Numerics; -using Voile.Rendering; - -namespace Voile.SceneGraph; - -public class RectangleShape2d : Drawable2d -{ - public Vector2 Size { get; set; } = Vector2.One * 32; - public Color Color { get; set; } = Color.White; - public override void OnDraw(RenderSystem renderer) - { - PivotOffset = Size / 2; - renderer.DrawRectangle(Size, Color); - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Entities/Sprite2d.cs b/Voile/Source/SceneGraph/Entities/Sprite2d.cs deleted file mode 100644 index 6c73c57..0000000 --- a/Voile/Source/SceneGraph/Entities/Sprite2d.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Drawing; - -using Voile.Rendering; - -namespace Voile.SceneGraph -{ - public class Sprite2d : Drawable2d - { - public Texture2d Texture { get => _texture ?? Texture2d.Empty; set => _texture = value; } - - protected override void OnStart() - { - var renderer = Layer.Scene.Renderer; - } - - public override void OnDraw(RenderSystem renderer) - { - renderer.DrawTexture(_texture!, Color.White); - } - - private Texture2d? _texture; - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Entities/Text2d.cs b/Voile/Source/SceneGraph/Entities/Text2d.cs deleted file mode 100644 index aaa8fab..0000000 --- a/Voile/Source/SceneGraph/Entities/Text2d.cs +++ /dev/null @@ -1,42 +0,0 @@ -using Voile.Rendering; -using System.Drawing; - -namespace Voile.SceneGraph -{ - public class Text2d : Drawable2d - { - public string Text { get => _text; set => _text = value; } - public Color FontColor { get => _fontColor; set => _fontColor = value; } - public Font Font - { - get => _font; set - { - _isDirty = true; - _font = value; - } - } - - public Text2d(Font font) - { - _font = font; - } - - public override void OnDraw(RenderSystem renderer) - { - if (_font == null) - { - renderer.DrawDebugText(_text, 20, _fontColor); - } - else - { - renderer.DrawText(_font, _text, _fontColor); - } - } - - private string _text = string.Empty; - private Color _fontColor = Color.White; - private Font _font; - private int _fontHandle; - private bool _isDirty; - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/EntityLayer.cs b/Voile/Source/SceneGraph/EntityLayer.cs deleted file mode 100644 index 2563149..0000000 --- a/Voile/Source/SceneGraph/EntityLayer.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System.Text.Json.Serialization; -using Voile.Rendering; -using Voile.Utils; - -namespace Voile.SceneGraph -{ - public class EntityLayer : Layer - { - public List Entities { get; set; } - public Camera2d? CurrentCamera { get; set; } - - public EntityLayer(List entities) - { - Entities = entities; - } - - public EntityLayer() - { - Entities = new List(); - } - - public void UpdateCurrentCamera() - { - if (_cameraEntities.Count == 1) - { - CurrentCamera = _cameraEntities[0]; - return; - } - else - { - foreach (var camera in _cameraEntities) - { - if (camera.Current) CurrentCamera = camera; - } - } - } - - public bool AddEntity(Entity entity) - { - entity.Id = Entities.Count; - entity.Layer = this; - - if (entity is Camera2d camera2d) - { - _cameraEntities.Add(camera2d); - UpdateCurrentCamera(); - } - - Entities.Add(entity); - - - return true; - } - - public void DestroyEntity(int at) - { - Entities.RemoveAt(at); - } - - protected override void OnStart() - { - for (int i = 0; i < Entities.Count; i++) - { - var entity = Entities[i]; - entity.Layer = this; - entity.Start(); - } - } - - protected override void OnUpdate(double dt) - { - foreach (var entity in Entities) - { - entity.Update(dt); - } - } - - protected override void OnBeginDraw(RenderSystem renderer) - { - if (CurrentCamera is not null) - { - renderer.BeginCamera2d(CurrentCamera.Offset, CurrentCamera.Position, 0f, CurrentCamera.Zoom); - } - } - - protected override void OnEndDraw(RenderSystem renderer) - { - if (CurrentCamera is not null) - { - renderer.EndCamera2d(); - } - } - - - protected override void OnDraw(RenderSystem renderer) - { - // TODO: can be done more efficiently, needs rendering redesign. - foreach (var entity in Entities) - { - if (entity is IDrawable drawable) - { - drawable.Draw(renderer); - } - } - } - private List _cameraEntities = new(); - } - - [JsonSourceGenerationOptions(WriteIndented = true)] - [JsonSerializable(typeof(EntityLayer))] - [JsonSerializable(typeof(Entity))] - [JsonSerializable(typeof(List))] - internal partial class EntityLayerContext : JsonSerializerContext - { - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/IMainLoop.cs b/Voile/Source/SceneGraph/IMainLoop.cs deleted file mode 100644 index dbbe77d..0000000 --- a/Voile/Source/SceneGraph/IMainLoop.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Voile.SceneGraph -{ - public interface IMainLoop - { - void Init(); - void Start(); - void Update(); - double DeltaTime { get; } - bool ShouldRun { get; } - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Layer.cs b/Voile/Source/SceneGraph/Layer.cs deleted file mode 100644 index fc4ae07..0000000 --- a/Voile/Source/SceneGraph/Layer.cs +++ /dev/null @@ -1,29 +0,0 @@ -using Voile.Resources; -using Voile.Rendering; -using System.Text.Json.Serialization; -using Voile.Input; - -namespace Voile.SceneGraph -{ - public abstract class Layer : IDrawable - { - [JsonIgnore] public Scene? Scene { get; set; } - [JsonIgnore] public InputSystem? Input { get; set; } - [JsonIgnore] public ResourceManager ResourceManager => Scene!.ResourceManager; - - public void BeginDraw(RenderSystem renderer) => OnBeginDraw(renderer); - public void Draw(RenderSystem renderer) => OnDraw(renderer); - public void EndDraw(RenderSystem renderer) => OnEndDraw(renderer); - - public void Start() => OnStart(); - public void Update(double dt) => OnUpdate(dt); - public void ReceiveInput(InputSystem input) => OnInput(input); - - protected virtual void OnStart() { } - protected virtual void OnUpdate(double dt) { } - protected virtual void OnInput(InputSystem input) { } - protected abstract void OnBeginDraw(RenderSystem renderer); - protected abstract void OnDraw(RenderSystem renderer); - protected abstract void OnEndDraw(RenderSystem renderer); - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Resources/SerializedScene.cs b/Voile/Source/SceneGraph/Resources/SerializedScene.cs deleted file mode 100644 index 4ef3834..0000000 --- a/Voile/Source/SceneGraph/Resources/SerializedScene.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text.Json.Serialization; - -namespace Voile.SceneGraph -{ - public class SerializedScene : Resource - { - public Dictionary Layers { get; set; } - - public byte[]? Buffer { get; set; } - public long BufferSize { get; set; } - - public SerializedScene(string path, byte[] buffer) : base(path) - { - Buffer = buffer; - } - } - - [JsonSourceGenerationOptions(WriteIndented = true)] - [JsonSerializable(typeof(SerializedScene))] - [JsonSerializable(typeof(Dictionary))] - [JsonSerializable(typeof(Entity2d))] - [JsonSerializable(typeof(Layer))] - [JsonSerializable(typeof(EntityLayer))] - internal partial class SerializedSceneContext : JsonSerializerContext - { - - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Resources/SerializedSceneSaver.cs b/Voile/Source/SceneGraph/Resources/SerializedSceneSaver.cs deleted file mode 100644 index ff047e6..0000000 --- a/Voile/Source/SceneGraph/Resources/SerializedSceneSaver.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Voile.Resources; -using Voile.Utils; - -namespace Voile.SceneGraph -{ - public class SerializedSceneSaver : IResourceSaver - { - public bool TrySave(string path, in SerializedScene resource) - { - if (resource.Buffer is null) - { - _logger.Error($"Tried to save a resource at \"{path}\" with a null buffer!"); - return false; - } - - File.WriteAllBytes(path, resource.Buffer); - - return true; - } - - private Logger _logger = new(nameof(SerializedSceneSaver)); - } -} \ No newline at end of file diff --git a/Voile/Source/SceneGraph/Scene.cs b/Voile/Source/SceneGraph/Scene.cs deleted file mode 100644 index 81090b3..0000000 --- a/Voile/Source/SceneGraph/Scene.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System.Text.Json; -using Voile.Audio; -using Voile.Input; -using Voile.Rendering; -using Voile.Resources; - - -namespace Voile.SceneGraph -{ - public class Scene : IMainLoop - { - public RenderSystem Renderer { get => _renderer; set => _renderer = value; } - public InputSystem? Input { get => _input; set => _input = value; } - public AudioSystem? Audio => _audioBackend; - public ResourceManager ResourceManager => _resourceManager; - - public double DeltaTime => _renderer.FrameTime; - public bool ShouldRun => Renderer.ShouldRun; - - public Scene(SceneSettings settings) - { - _renderer = settings.Renderer; - _input = settings.InputHandler; - _audioBackend = settings.AudioBackend; - _resourceManager = settings.ResourceManager; - } - - public static Scene FromSerialized(SerializedScene serializedScene, SceneSettings settings) - { - var scene = new Scene(settings); - scene.WithLayers(serializedScene.Layers); - - return scene; - } - - public bool TrySerialize(out SerializedScene serializedScene) - { - serializedScene = new SerializedScene(string.Empty, new byte[] { }) - { - Layers = _layers - }; - - - serializedScene.Buffer = JsonSerializer.SerializeToUtf8Bytes(serializedScene, new JsonSerializerOptions - { - TypeInfoResolver = SerializedSceneContext.Default - }); - serializedScene.BufferSize = serializedScene.Buffer.LongLength; - - return true; - } - - public void WithLayers(Dictionary layers) - { - _layers = layers; - } - - public void Init() => SetupRenderer(); - public void Start() - { - foreach (var layer in _layers.Values) - { - if (_input is not null) - { - layer.Input = _input; - } - - layer.Start(); - } - } - - public void Update() - { - foreach (var layer in _layers) - { - layer.Value.Update(DeltaTime); - } - - Audio?.Update(DeltaTime); - } - - public void AddLayer(string name, Layer layer) - { - layer.Scene = this; - _layers.Add(name, layer); - } - - public void BeginDraw() - { - Renderer.BeginFrame(); - Renderer.ClearBackground(Color.Black); - - foreach (var layer in _layers.Values) - { - layer.BeginDraw(_renderer); - layer.Draw(_renderer); - } - - Renderer.ResetTransform(); - } - - public void EndDraw() - { - foreach (var layer in _layers.Values) - { - layer.EndDraw(_renderer); - } - - Renderer.EndFrame(); - } - - private void SetupRenderer() - { - Renderer.Initialize(new RendererSettings { Msaa = Msaa.Msaa4x, UseVSync = true }); - } - - private Dictionary _layers = new(); - private RenderSystem _renderer; - private AudioSystem? _audioBackend; - private InputSystem? _input; - private ResourceManager _resourceManager; - } - - public struct SceneSettings - { - public RenderSystem Renderer { get; set; } - public AudioSystem AudioBackend { get; set; } - public InputSystem InputHandler { get; set; } - public ResourceManager ResourceManager { get; set; } - } -} \ No newline at end of file diff --git a/Voile/Source/Utils/ImGuiRenderLayer.cs b/Voile/Source/Utils/ImGuiRenderLayer.cs deleted file mode 100644 index 979d128..0000000 --- a/Voile/Source/Utils/ImGuiRenderLayer.cs +++ /dev/null @@ -1,332 +0,0 @@ -using System.Numerics; -using ImGuiNET; -using Raylib_cs; -using Voile.Input; -using Voile.Rendering; -using KeyboardKey = Voile.Input.KeyboardKey; -using MouseButton = Voile.Input.MouseButton; - -namespace Voile.SceneGraph -{ - public class ImGuiRenderLayer : Layer - { - protected override void OnDraw(RenderSystem renderer) - { - Layout(); - _controller.Draw(renderer); - } - - protected virtual void Layout() { } - - protected override void OnStart() - { - _controller = new ImGuiController(); - _controller.Load(Scene.Renderer.WindowSize); - } - - protected override void OnUpdate(double dt) - { - // _controller.Update(dt, Input); - } - - protected override void OnBeginDraw(RenderSystem renderer) - { - throw new NotImplementedException(); - } - - protected override void OnEndDraw(RenderSystem renderer) - { - throw new NotImplementedException(); - } - - private ImGuiController _controller; - } - - public class ImGuiController : IDisposable, IDrawable - { - public ImGuiController() - { - _context = ImGui.CreateContext(); - ImGui.SetCurrentContext(_context); - } - public void Dispose() - { - ImGui.DestroyContext(); - } - - public void Load(Vector2 size) - { - ImGuiIOPtr io = ImGui.GetIO(); - io.Fonts.AddFontDefault(); - - Resize(size); - LoadFontTexture(); - SetupInput(); - ImGui.NewFrame(); - } - - unsafe void LoadFontTexture() - { - ImGuiIOPtr io = ImGui.GetIO(); - io.Fonts.GetTexDataAsRGBA32(out byte* pixels, out int width, out int height); - - // TODO: use engine API instead of Raylib. - Image image = new Image - { - data = pixels, - width = width, - height = height, - mipmaps = 1, - format = PixelFormat.PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, - }; - _fontTexture = Raylib.LoadTextureFromImage(image); - - io.Fonts.SetTexID(new IntPtr(_fontTexture.id)); - io.Fonts.ClearTexData(); - } - - private void SetupInput() - { - ImGuiIOPtr io = ImGui.GetIO(); - - // Setup config flags - io.ConfigFlags |= ImGuiConfigFlags.NavEnableKeyboard; - - // Setup back-end capabilities flags - io.BackendFlags |= ImGuiBackendFlags.HasMouseCursors; - io.BackendFlags |= ImGuiBackendFlags.HasSetMousePos; - - // Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array. - io.KeyMap[(int)ImGuiKey.Tab] = (int)KeyboardKey.Tab; - io.KeyMap[(int)ImGuiKey.LeftArrow] = (int)KeyboardKey.Left; - io.KeyMap[(int)ImGuiKey.RightArrow] = (int)KeyboardKey.Right; - io.KeyMap[(int)ImGuiKey.UpArrow] = (int)KeyboardKey.Up; - io.KeyMap[(int)ImGuiKey.DownArrow] = (int)KeyboardKey.Down; - io.KeyMap[(int)ImGuiKey.PageUp] = (int)KeyboardKey.PageUp; - io.KeyMap[(int)ImGuiKey.PageDown] = (int)KeyboardKey.PageDown; - io.KeyMap[(int)ImGuiKey.Home] = (int)KeyboardKey.Home; - io.KeyMap[(int)ImGuiKey.End] = (int)KeyboardKey.End; - io.KeyMap[(int)ImGuiKey.Insert] = (int)KeyboardKey.Insert; - io.KeyMap[(int)ImGuiKey.Delete] = (int)KeyboardKey.Delete; - io.KeyMap[(int)ImGuiKey.Backspace] = (int)KeyboardKey.Backspace; - io.KeyMap[(int)ImGuiKey.Space] = (int)KeyboardKey.Spacebar; - io.KeyMap[(int)ImGuiKey.Enter] = (int)KeyboardKey.Enter; - io.KeyMap[(int)ImGuiKey.Escape] = (int)KeyboardKey.Escape; - io.KeyMap[(int)ImGuiKey.A] = (int)KeyboardKey.A; - io.KeyMap[(int)ImGuiKey.C] = (int)KeyboardKey.C; - io.KeyMap[(int)ImGuiKey.V] = (int)KeyboardKey.V; - io.KeyMap[(int)ImGuiKey.X] = (int)KeyboardKey.X; - io.KeyMap[(int)ImGuiKey.Y] = (int)KeyboardKey.Y; - io.KeyMap[(int)ImGuiKey.Z] = (int)KeyboardKey.Z; - } - - public void Resize(Vector2 size) - { - ImGuiIOPtr io = ImGui.GetIO(); - io.DisplaySize = size / _scaleFactor; - } - - public void Update(double dt, InputSystem input) - { - ImGuiIOPtr io = ImGui.GetIO(); - - io.DisplayFramebufferScale = Vector2.One; - io.DeltaTime = (float)dt; - - UpdateKeyboard(input); - UpdateMouse(input); - - ImGui.NewFrame(); - } - - private void UpdateKeyboard(InputSystem input) - { - ImGuiIOPtr io = ImGui.GetIO(); - - // Modifiers are not reliable across systems - io.KeyCtrl = io.KeysDown[(int)KeyboardKey.LeftControl] || io.KeysDown[(int)KeyboardKey.RightControl]; - io.KeyShift = io.KeysDown[(int)KeyboardKey.LeftShift] || io.KeysDown[(int)KeyboardKey.RightShift]; - io.KeyAlt = io.KeysDown[(int)KeyboardKey.LeftAlt] || io.KeysDown[(int)KeyboardKey.RightAlt]; - io.KeySuper = io.KeysDown[(int)KeyboardKey.LeftSuper] || io.KeysDown[(int)KeyboardKey.RightSuper]; - - // Key states - for (int i = (int)KeyboardKey.Spacebar; i < (int)KeyboardKey.KBMenu + 1; i++) - { - io.KeysDown[i] = input.IsKeyboardKeyDown((KeyboardKey)i); - } - - // Key input - int keyPressed = input.GetCharPressed(); - if (keyPressed != 0) - { - io.AddInputCharacter((uint)keyPressed); - } - } - - private void UpdateMouse(InputSystem input) - { - ImGuiIOPtr io = ImGui.GetIO(); - - // Store button states - for (int i = 0; i < io.MouseDown.Count; i++) - { - io.MouseDown[i] = input.IsMouseButtonDown((MouseButton)i); - } - - // Mouse scroll - io.MouseWheel += input.GetMouseWheelMovement(); - - // Mouse position - Vector2 mousePosition = io.MousePos; - // TODO: - // bool focused = Raylib.IsWindowFocused(); - - if (io.WantSetMousePos) - { - input.SetMousePosition(mousePosition); - } - else - { - io.MousePos = input.GetMousePosition(); - } - - // Mouse cursor state - if ((io.ConfigFlags & ImGuiConfigFlags.NoMouseCursorChange) == 0 || input.IsCursorHidden()) - { - ImGuiMouseCursor cursor = ImGui.GetMouseCursor(); - if (cursor == ImGuiMouseCursor.None || io.MouseDrawCursor) - { - input.HideCursor(); - } - else - { - input.ShowCursor(); - } - } - } - - private void Render() - { - ImGui.Render(); - } - - private void RenderCommandLists(ImDrawDataPtr data) - { - // Scale coordinates for retina displays (screen coordinates != framebuffer coordinates) - int fbWidth = (int)(data.DisplaySize.X * data.FramebufferScale.X); - int fbHeight = (int)(data.DisplaySize.Y * data.FramebufferScale.Y); - - // Avoid rendering if display is minimized or if the command list is empty - if (fbWidth <= 0 || fbHeight <= 0 || data.CmdListsCount == 0) - { - return; - } - - Rlgl.rlDrawRenderBatchActive(); - Rlgl.rlDisableBackfaceCulling(); - Rlgl.rlEnableScissorTest(); - - data.ScaleClipRects(ImGui.GetIO().DisplayFramebufferScale); - - for (int n = 0; n < data.CmdListsCount; n++) - { - int idxOffset = 0; - ImDrawListPtr cmdList = data.CmdListsRange[n]; - - // Vertex buffer and index buffer generated by DearImGui - ImPtrVector vtxBuffer = cmdList.VtxBuffer; - ImVector idxBuffer = cmdList.IdxBuffer; - - for (int cmdi = 0; cmdi < cmdList.CmdBuffer.Size; cmdi++) - { - ImDrawCmdPtr pcmd = cmdList.CmdBuffer[cmdi]; - - // Scissor rect - Vector2 pos = data.DisplayPos; - int rectX = (int)((pcmd.ClipRect.X - pos.X) * data.FramebufferScale.X); - int rectY = (int)((pcmd.ClipRect.Y - pos.Y) * data.FramebufferScale.Y); - int rectW = (int)((pcmd.ClipRect.Z - rectX) * data.FramebufferScale.Y); - int rectH = (int)((pcmd.ClipRect.W - rectY) * data.FramebufferScale.Y); - Rlgl.rlScissor(rectX, Raylib.GetScreenHeight() - (rectY + rectH), rectW, rectH); - - if (pcmd.UserCallback != IntPtr.Zero) - { - // pcmd.UserCallback(cmdList, pcmd); - idxOffset += (int)pcmd.ElemCount; - } - else - { - DrawTriangles(pcmd.ElemCount, idxOffset, (int)pcmd.VtxOffset, idxBuffer, vtxBuffer, pcmd.TextureId); - idxOffset += (int)pcmd.ElemCount; - Rlgl.rlDrawRenderBatchActive(); - } - } - } - - Rlgl.rlSetTexture(0); - Rlgl.rlDisableScissorTest(); - Rlgl.rlEnableBackfaceCulling(); - } - - private Color GetColor(uint hexValue) - { - Color color = new Color(); - - color.R = (byte)(hexValue & 0xFF) / 255f; - color.G = (byte)((hexValue >> 8) & 0xFF) / 255f; - color.B = (byte)((hexValue >> 16) & 0xFF) / 255f; - color.A = (byte)((hexValue >> 24) & 0xFF) / 255f; - - return color; - } - - void DrawTriangleVertex(ImDrawVertPtr idxVert) - { - Color c = GetColor(idxVert.col); - Rlgl.rlColor4ub((byte)Math.Round(c.R * 255f), (byte)Math.Round(c.G * 255f), (byte)Math.Round(c.B * 255f), (byte)Math.Round(c.A * 255f)); - Rlgl.rlTexCoord2f(idxVert.uv.X, idxVert.uv.Y); - Rlgl.rlVertex2f(idxVert.pos.X, idxVert.pos.Y); - } - - // Draw the imgui triangle data - private void DrawTriangles(uint count, int idxOffset, int vtxOffset, ImVector idxBuffer, ImPtrVector idxVert, IntPtr textureId) - { - ushort index = 0; - ImDrawVertPtr vertex; - - if (Rlgl.rlCheckRenderBatchLimit((int)count * 3)) - { - Rlgl.rlDrawRenderBatchActive(); - } - - Rlgl.rlBegin(DrawMode.TRIANGLES); - Rlgl.rlSetTexture((uint)textureId); - - for (int i = 0; i <= (count - 3); i += 3) - { - index = idxBuffer[idxOffset + i]; - vertex = idxVert[vtxOffset + index]; - DrawTriangleVertex(vertex); - - index = idxBuffer[idxOffset + i + 1]; - vertex = idxVert[vtxOffset + index]; - DrawTriangleVertex(vertex); - - index = idxBuffer[idxOffset + i + 2]; - vertex = idxVert[vtxOffset + index]; - DrawTriangleVertex(vertex); - } - Rlgl.rlEnd(); - } - - public void Draw(RenderSystem renderer) - { - ImGui.Render(); - RenderCommandLists(ImGui.GetDrawData()); - } - - private IntPtr _context; - private Texture2D _fontTexture; - private Vector2 _scaleFactor = Vector2.One; - } -} \ No newline at end of file