From 8827bfbb786559f4daf778f28e86f9d039c171d3 Mon Sep 17 00:00:00 2001 From: Harrison Date: Thu, 25 Jun 2020 00:05:44 -0500 Subject: [PATCH] Added linear interpolation between updates to mesh batch. Cleaned up code. --- src/SlatedGameToolkit.Framework/GameEngine.cs | 5 +++- .../Graphics/Render/Camera.cs | 22 +++++++++++++-- .../Graphics/Render/Camera2D.cs | 13 ++++++++- .../Graphics/Render/IMoveable.cs | 22 +++++++++++++++ .../Graphics/Render/MeshBatch.cs | 28 +++++++++++++++++-- .../StateSystem/StateManager.cs | 4 +-- .../StateSystem/States/IState.cs | 4 +-- .../Commands/GraphicalPlaygroundCommand.cs | 1 + .../Utilities/Playground/MainState.cs | 12 ++++---- 9 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 src/SlatedGameToolkit.Framework/Graphics/Render/IMoveable.cs diff --git a/src/SlatedGameToolkit.Framework/GameEngine.cs b/src/SlatedGameToolkit.Framework/GameEngine.cs index b0dd139..d2b113a 100644 --- a/src/SlatedGameToolkit.Framework/GameEngine.cs +++ b/src/SlatedGameToolkit.Framework/GameEngine.cs @@ -164,7 +164,10 @@ namespace SlatedGameToolkit.Framework { //Updates. manager.update(updateDeltaTime.TotalSeconds <= 0 ? timePassedFromLastUpdate.TotalSeconds : updateDeltaTime.TotalSeconds); timePassedFromLastUpdate -= updateDeltaTime; - if (updateDeltaTime.TotalSeconds <= 0) break; + if (updateDeltaTime.TotalSeconds <= 0) { + timePassedFromLastUpdate = TimeSpan.Zero; + break; + } } timePassedFromLastRender += difference; diff --git a/src/SlatedGameToolkit.Framework/Graphics/Render/Camera.cs b/src/SlatedGameToolkit.Framework/Graphics/Render/Camera.cs index aae59f1..17df797 100644 --- a/src/SlatedGameToolkit.Framework/Graphics/Render/Camera.cs +++ b/src/SlatedGameToolkit.Framework/Graphics/Render/Camera.cs @@ -4,15 +4,27 @@ using SlatedGameToolkit.Framework.Utilities; namespace SlatedGameToolkit.Framework.Graphics.Render { - public class Camera { - private bool viewUpdated = true, projectionUpdated = true, orthographic; - public virtual Vector3 Up { get; set; } = Vector3.UnitY; + public class Camera : IMoveable { + private bool viewUpdated = true, projectionUpdated = true, orthographic = false; + private Vector3 position, lookAt; private float nearField = 0.01f, farField = 100f; private float width, height; private Matrix4x4 lookAtMatrix = Matrix4x4.Identity; private Matrix4x4 view = Matrix4x4.Identity, projection; + + /// + /// Position updates the camera without changing camera orientation if true. + /// Otherwise, camera will always attempt to look in the direction of the point given by the LookAt vector. + /// + /// Whether or not to change orientation while moving camera position. + public bool LockedOrientation { get; set; } = false; + /// + /// The up direction of the camera. + /// + /// A vector representing the up direction of the camera. + public Vector3 Up { get; set; } = Vector3.UnitY; public event EventHandler projectionUpdateEvent; public bool Orthographic { @@ -31,7 +43,9 @@ namespace SlatedGameToolkit.Framework.Graphics.Render return position; } set { + Vector3 orientation = CameraFront; this.position = value; + if (LockedOrientation) CameraFront = orientation; viewUpdated = true; } } @@ -120,6 +134,8 @@ namespace SlatedGameToolkit.Framework.Graphics.Render } } + public Vector3 MoveTo { get; set; } + public Camera(float width, float height) { if (width <= 0) throw new ArgumentException("Width can't be less than or equal to 0."); if (height <= 0) throw new ArgumentException("Height can't be less than or equal to 0."); diff --git a/src/SlatedGameToolkit.Framework/Graphics/Render/Camera2D.cs b/src/SlatedGameToolkit.Framework/Graphics/Render/Camera2D.cs index 83ac06a..8359206 100644 --- a/src/SlatedGameToolkit.Framework/Graphics/Render/Camera2D.cs +++ b/src/SlatedGameToolkit.Framework/Graphics/Render/Camera2D.cs @@ -10,12 +10,23 @@ namespace SlatedGameToolkit.Framework.Graphics.Render set { base.Position = new Vector3(value, base.Position.Z); - base.CameraFront = -Vector3.UnitZ; + } + } + + public new Vector2 MoveTo { + get { + return new Vector2(base.MoveTo.X, base.MoveTo.Y); + } + + set { + base.MoveTo = new Vector3(value, base.MoveTo.Z); } } public Camera2D(int width, int height) : base(width, height) { this.Orthographic = true; + this.LockedOrientation = true; + this.CameraFront = -Vector3.UnitZ; } } } \ No newline at end of file diff --git a/src/SlatedGameToolkit.Framework/Graphics/Render/IMoveable.cs b/src/SlatedGameToolkit.Framework/Graphics/Render/IMoveable.cs new file mode 100644 index 0000000..6e926f8 --- /dev/null +++ b/src/SlatedGameToolkit.Framework/Graphics/Render/IMoveable.cs @@ -0,0 +1,22 @@ +using System.Numerics; + +namespace SlatedGameToolkit.Framework.Graphics.Render +{ + public interface IMoveable + { + /// + /// A vector describing the position this object should move to. + /// This is then used to smooth the movement to the intermediate renders. + /// + /// + /// A vector describing the new position of the object by the end of the update. + Vector3 MoveTo { get; set; } + + + /// + /// The current position of the entity. + /// + /// A vector describing the current objects position. + Vector3 Position { get; set; } + } +} \ No newline at end of file diff --git a/src/SlatedGameToolkit.Framework/Graphics/Render/MeshBatch.cs b/src/SlatedGameToolkit.Framework/Graphics/Render/MeshBatch.cs index 2541d6f..774becb 100644 --- a/src/SlatedGameToolkit.Framework/Graphics/Render/MeshBatch.cs +++ b/src/SlatedGameToolkit.Framework/Graphics/Render/MeshBatch.cs @@ -11,13 +11,14 @@ using SlatedGameToolkit.Framework.Utilities; namespace SlatedGameToolkit.Framework.Graphics.Render { public class MeshBatch : IDisposable { - public GLContext GLContext {get; private set; } private const int VERTEX_LENGTH = 9; + private bool disposed; + private float batchDelta; + public GLContext GLContext {get; private set; } private int projALoc, viewALoc, modelALoc, texturedALoc; private Camera camera; private RenderProgram renderProgram; private ITexture texture; - private bool disposed; private VertexArrayBuffers vertexBuffers; public bool Batching { get; private set; } @@ -59,10 +60,17 @@ namespace SlatedGameToolkit.Framework.Graphics.Render GLContext.UniformMatrix4fv(projALoc, 1, false, camera.ProjectionMatrix.ToColumnMajorArray()); } - public virtual void Begin(Matrix4x4 modelsMatrix) { + /// + /// Begins a mesh batch for rendering. + /// + /// The models matrix. + /// The time elapsed since the last update. + public virtual void Begin(Matrix4x4 modelsMatrix, double delta) { if (Batching) throw new InvalidOperationException("This batch is already started."); this.Batching = true; this.modelsMatrix = modelsMatrix; + + this.batchDelta = (float)delta; } /// @@ -70,6 +78,14 @@ namespace SlatedGameToolkit.Framework.Graphics.Render /// /// Draws the given mesh. public virtual void Draw(IMesh mesh) { + IMoveable moveable = mesh as IMoveable; + if (moveable != null) { + if (GameEngine.UpdatesPerSecond <= 0) { + camera.Position = camera.MoveTo; + } else { + camera.Position = camera.Position + (camera.MoveTo - camera.Position) * batchDelta; + } + } if (mesh.Texture?.Handle != this.texture?.Handle) { Flush(); this.texture = mesh.Texture; @@ -121,6 +137,12 @@ namespace SlatedGameToolkit.Framework.Graphics.Render protected virtual void Flush() { texture?.Use(); renderProgram.Use(); + if (GameEngine.UpdatesPerSecond <= 0) { + camera.Position = camera.MoveTo; + } else { + camera.Position = camera.Position + (camera.MoveTo - camera.Position) * batchDelta; + } + vertexBuffers.BufferVertices(data, true); vertexBuffers.BufferIndices(indices, true); GLContext.UniformMatrix4fv(modelALoc, 1, false, modelsMatrix.ToColumnMajorArray()); diff --git a/src/SlatedGameToolkit.Framework/StateSystem/StateManager.cs b/src/SlatedGameToolkit.Framework/StateSystem/StateManager.cs index cd4605e..62a93f6 100644 --- a/src/SlatedGameToolkit.Framework/StateSystem/StateManager.cs +++ b/src/SlatedGameToolkit.Framework/StateSystem/StateManager.cs @@ -37,14 +37,14 @@ namespace SlatedGameToolkit.Framework.StateSystem addState(initialState); } - internal void update(double delta) { + internal void update(double timeStep) { if (nextState != null) { if (currentState.Deactivate() & nextState.Activate()) { currentState = nextState; nextState = null; } } - currentState.Update(delta); + currentState.Update(timeStep); } internal void render(double delta) { diff --git a/src/SlatedGameToolkit.Framework/StateSystem/States/IState.cs b/src/SlatedGameToolkit.Framework/StateSystem/States/IState.cs index 15719d4..90d24c7 100644 --- a/src/SlatedGameToolkit.Framework/StateSystem/States/IState.cs +++ b/src/SlatedGameToolkit.Framework/StateSystem/States/IState.cs @@ -29,8 +29,8 @@ namespace SlatedGameToolkit.Framework.StateSystem.States /// Called in intervals dependent on game loop chosen for every update cycle. /// Only called on if this state is the active state, indicated on the last status method called on this implementation (acitvate, and deactivate). /// - /// The time in seconds that has passed since the last update. - void Update(double delta); + /// The change in time between the updates in seconds. If fixed, this amounts to the portion of time between the set update rate. If unlocked, represents the actual amount of time passed since the last update. + void Update(double timeStep); /// /// Called in intervals dependent on game loop chose for every render cycle. diff --git a/src/SlatedGameToolkit.Tools/Commands/GraphicalPlaygroundCommand.cs b/src/SlatedGameToolkit.Tools/Commands/GraphicalPlaygroundCommand.cs index 83bb3d8..cec534d 100644 --- a/src/SlatedGameToolkit.Tools/Commands/GraphicalPlaygroundCommand.cs +++ b/src/SlatedGameToolkit.Tools/Commands/GraphicalPlaygroundCommand.cs @@ -19,6 +19,7 @@ namespace SlatedGameToolkit.Tools.Commands interactable.Tell("Engine is already running!"); return true; } + GameEngine.Ignite(new MainState()); return true; } else if (args[0].Equals("stop")) { diff --git a/src/SlatedGameToolkit.Tools/Utilities/Playground/MainState.cs b/src/SlatedGameToolkit.Tools/Utilities/Playground/MainState.cs index 5fcd573..9248ad2 100644 --- a/src/SlatedGameToolkit.Tools/Utilities/Playground/MainState.cs +++ b/src/SlatedGameToolkit.Tools/Utilities/Playground/MainState.cs @@ -77,26 +77,26 @@ namespace SlatedGameToolkit.Tools.Utilities.Playground public void Render(double delta) { - renderer.Begin(Matrix4x4.Identity); + renderer.Begin(Matrix4x4.Identity, delta); renderer.Draw(logo); renderer.Draw(textureTester); renderer.Draw(untextured); renderer.End(); } - public void Update(double delta) + public void Update(double timeStep) { if (Keyboard.IsKeyPressed(SDL.SDL_Keycode.SDLK_DOWN)) { - camera.Position += new Vector2(0, (float)(-0.5f * delta)); + camera.MoveTo += new Vector2(0, (-0.25f)) * (float) timeStep; } if (Keyboard.IsKeyPressed(SDL.SDL_Keycode.SDLK_UP)) { - camera.Position += new Vector2(0, (float)(0.5f * delta)); + camera.MoveTo += new Vector2(0, (0.25f)) * (float) timeStep; } if (Keyboard.IsKeyPressed(SDL.SDL_Keycode.SDLK_LEFT)) { - camera.Position += new Vector2((float)(-0.5f * delta), 0); + camera.MoveTo += new Vector2((-0.25f) * (float) timeStep, 0); } if (Keyboard.IsKeyPressed(SDL.SDL_Keycode.SDLK_RIGHT)) { - camera.Position += new Vector2((float)(0.5f * delta), 0); + camera.MoveTo += new Vector2((0.25f) * (float) timeStep, 0); } } }