diff --git a/DaggerFramework/Source/Rendering/RaylibRenderer.cs b/DaggerFramework/Source/Rendering/RaylibRenderer.cs index 84c3d9e..a65d8f9 100644 --- a/DaggerFramework/Source/Rendering/RaylibRenderer.cs +++ b/DaggerFramework/Source/Rendering/RaylibRenderer.cs @@ -52,6 +52,17 @@ namespace DaggerFramework.Rendering Raylib.EndDrawing(); } + public override void BeginCamera2d(Vector2 offset, Vector2 target, float rotation, float zoom) + { + var camera = new Camera2D(offset, target, rotation, zoom); + Raylib.BeginMode2D(camera); + } + + public override void EndCamera2d() + { + Raylib.EndMode2D(); + } + public override void ClearBackground(Color color) { Raylib.ClearBackground(DaggerColorToRaylibColor(color)); diff --git a/DaggerFramework/Source/Rendering/Renderer.cs b/DaggerFramework/Source/Rendering/Renderer.cs index f7ba52e..149eff5 100644 --- a/DaggerFramework/Source/Rendering/Renderer.cs +++ b/DaggerFramework/Source/Rendering/Renderer.cs @@ -58,6 +58,10 @@ namespace DaggerFramework.Rendering /// Ends rendering of the frame. /// public abstract void EndFrame(); + + public abstract void BeginCamera2d(Vector2 offset, Vector2 target, float rotation, float zoom); + public abstract void EndCamera2d(); + /// /// Clears the render canvas and sets a background color. /// diff --git a/DaggerFramework/Source/Rendering/StandardRenderer.cs b/DaggerFramework/Source/Rendering/StandardRenderer.cs index 1843504..4f38141 100644 --- a/DaggerFramework/Source/Rendering/StandardRenderer.cs +++ b/DaggerFramework/Source/Rendering/StandardRenderer.cs @@ -166,6 +166,17 @@ namespace DaggerFramework.Rendering throw new NotImplementedException(); } + public override void BeginCamera2d(Vector2 offset, Vector2 target, float rotation, float zoom) + { + throw new NotImplementedException(); + } + + public override void EndCamera2d() + { + throw new NotImplementedException(); + } + + private GL _gl; private Glfw _glfw; private unsafe WindowHandle* _windowHandle; diff --git a/DaggerFramework/Source/SceneGraph/Camera2d.cs b/DaggerFramework/Source/SceneGraph/Camera2d.cs new file mode 100644 index 0000000..ac93a94 --- /dev/null +++ b/DaggerFramework/Source/SceneGraph/Camera2d.cs @@ -0,0 +1,25 @@ +using System.Numerics; + +namespace DaggerFramework.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/DaggerFramework/Source/SceneGraph/Entities/Entity.cs b/DaggerFramework/Source/SceneGraph/Entities/Entity.cs index 75c81dd..33fe0a7 100644 --- a/DaggerFramework/Source/SceneGraph/Entities/Entity.cs +++ b/DaggerFramework/Source/SceneGraph/Entities/Entity.cs @@ -1,4 +1,5 @@ using DaggerFramework.Audio; +using DaggerFramework.Rendering; namespace DaggerFramework.SceneGraph { @@ -7,6 +8,7 @@ namespace DaggerFramework.SceneGraph public EntityLayer Layer { get; set; } public InputHandler Input => Layer.Scene.Input; public AudioBackend Audio => Layer.Scene.Audio; + public Renderer Renderer => Layer.Scene.Renderer; public int Id { get; set; } public void Start() => OnStart(); diff --git a/DaggerFramework/Source/SceneGraph/EntityLayer.cs b/DaggerFramework/Source/SceneGraph/EntityLayer.cs index 05cda32..7903e6f 100644 --- a/DaggerFramework/Source/SceneGraph/EntityLayer.cs +++ b/DaggerFramework/Source/SceneGraph/EntityLayer.cs @@ -1,10 +1,13 @@ using DaggerFramework.Rendering; +using DaggerFramework.Utils; namespace DaggerFramework.SceneGraph { public class EntityLayer : Layer { public List Entities { get => _entities; } + public Camera2d CurrentCamera { get; set; } + public EntityLayer(List entities) { _entities = entities; @@ -15,11 +18,36 @@ namespace DaggerFramework.SceneGraph _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; } @@ -30,8 +58,9 @@ namespace DaggerFramework.SceneGraph protected override void OnStart() { - foreach (var entity in _entities) + for (int i = 0; i < _entities.Count; i++) { + var entity = _entities[i]; entity.Layer = this; entity.Start(); } @@ -45,14 +74,38 @@ namespace DaggerFramework.SceneGraph } } + protected override void OnBeginDraw(Renderer renderer) + { + var hasCamera = CurrentCamera != null; + if (hasCamera) + { + renderer.BeginCamera2d(CurrentCamera.Offset, CurrentCamera.Position, 0f, CurrentCamera.Zoom); + } + } + + protected override void OnEndDraw(Renderer renderer) + { + var hasCamera = CurrentCamera != null; + if (hasCamera) + { + renderer.EndCamera2d(); + } + } + + protected override void OnDraw(Renderer renderer) { - foreach (IDrawable drawable in _entities) + // TODO: can be done more efficiently, needs rendering redesign. + foreach (var entity in _entities) { - drawable.Draw(renderer); + if (entity is IDrawable drawable) + { + drawable.Draw(renderer); + } } } private List _entities; + private List _cameraEntities = new(); } } \ No newline at end of file diff --git a/DaggerFramework/Source/SceneGraph/Layer.cs b/DaggerFramework/Source/SceneGraph/Layer.cs index 6743e6b..977e378 100644 --- a/DaggerFramework/Source/SceneGraph/Layer.cs +++ b/DaggerFramework/Source/SceneGraph/Layer.cs @@ -9,7 +9,9 @@ namespace DaggerFramework.SceneGraph public InputHandler Input { get; set; } public ResourceManager ResourceManager => Scene.ResourceManager; + public void BeginDraw(Renderer renderer) => OnBeginDraw(renderer); public void Draw(Renderer renderer) => OnDraw(renderer); + public void EndDraw(Renderer renderer) => OnEndDraw(renderer); public void Start() => OnStart(); public void Update(double dt) => OnUpdate(dt); @@ -18,6 +20,8 @@ namespace DaggerFramework.SceneGraph protected virtual void OnStart() { } protected virtual void OnUpdate(double dt) { } protected virtual void OnInput(InputHandler input) { } + protected abstract void OnBeginDraw(Renderer renderer); protected abstract void OnDraw(Renderer renderer); + protected abstract void OnEndDraw(Renderer renderer); } } \ No newline at end of file diff --git a/DaggerFramework/Source/SceneGraph/Scene.cs b/DaggerFramework/Source/SceneGraph/Scene.cs index 9399b09..e853ae4 100644 --- a/DaggerFramework/Source/SceneGraph/Scene.cs +++ b/DaggerFramework/Source/SceneGraph/Scene.cs @@ -65,7 +65,9 @@ namespace DaggerFramework.SceneGraph foreach (var layer in _layers.Values) { + layer.BeginDraw(_renderer); layer.Draw(_renderer); + layer.EndDraw(_renderer); } Renderer.EndFrame(); @@ -85,7 +87,5 @@ namespace DaggerFramework.SceneGraph private AudioBackend _audioBackend; private InputHandler _input; private ResourceManager _resourceManager; - - private bool _inputDirty; } } \ No newline at end of file diff --git a/DaggerFramework/Source/Utils/ImGuiRenderLayer.cs b/DaggerFramework/Source/Utils/ImGuiRenderLayer.cs index c35af98..35d0199 100644 --- a/DaggerFramework/Source/Utils/ImGuiRenderLayer.cs +++ b/DaggerFramework/Source/Utils/ImGuiRenderLayer.cs @@ -27,6 +27,16 @@ namespace DaggerFramework.SceneGraph _controller.Update(dt, Input); } + protected override void OnBeginDraw(Renderer renderer) + { + throw new NotImplementedException(); + } + + protected override void OnEndDraw(Renderer renderer) + { + throw new NotImplementedException(); + } + private ImGuiController _controller; } diff --git a/DaggerFramework/Source/Utils/MathUtils.cs b/DaggerFramework/Source/Utils/MathUtils.cs index 002cb8a..15b777a 100644 --- a/DaggerFramework/Source/Utils/MathUtils.cs +++ b/DaggerFramework/Source/Utils/MathUtils.cs @@ -20,7 +20,7 @@ namespace DaggerFramework public static Vector2 LerpVector2(Vector2 v1, Vector2 v2, double t) { var x = Lerp(v1.X, v2.X, t); - var y = Lerp(v1.X, v2.Y, t); + var y = Lerp(v1.Y, v2.Y, t); return new Vector2(x, y); } diff --git a/TestGame/TestGame.cs b/TestGame/TestGame.cs index 8472cad..f619b7e 100644 --- a/TestGame/TestGame.cs +++ b/TestGame/TestGame.cs @@ -23,7 +23,7 @@ public class TestGame : Game Size = new Vector2(1280, 720) }, new RendererSettings() { - UseVSync = false + UseVSync = true }); _audioBackend.Initialize(); diff --git a/TestGame/TestPlayer.cs b/TestGame/TestPlayer.cs index df0186c..99c7c12 100644 --- a/TestGame/TestPlayer.cs +++ b/TestGame/TestPlayer.cs @@ -8,6 +8,14 @@ public class TestPlayer : RectangleShape2d { base.OnStart(); Color = Color.Cyan; + _logger.Echo("OnStart"); + + _camera = new Camera2d() + { + Current = true, + }; + + Layer.AddEntity(_camera); } protected override void OnUpdate(double dt) @@ -19,7 +27,11 @@ public class TestPlayer : RectangleShape2d var velocity = Input.GetInputDirection("left", "right", "up", "down") * _speed; Position += velocity * (float)dt; + + _camera.Position = MathUtils.LerpVector2(_camera.Position, Position, dt * 5f); } + private Logger _logger = new(nameof(TestPlayer)); private float _speed = 200f; + private Camera2d _camera; } \ No newline at end of file