Skip to content

Commit

Permalink
Merge pull request #5 from Tornado-Technology/camera-system
Browse files Browse the repository at this point in the history
Camera system WIP
  • Loading branch information
Tornado-Technology committed Jul 11, 2024
2 parents 78578a9 + 713daf4 commit be88aab
Show file tree
Hide file tree
Showing 36 changed files with 1,247 additions and 368 deletions.
4 changes: 3 additions & 1 deletion .idea/.idea.Hypercube/.idea/indexLayout.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Hypercube.Client/Dependencies.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Hypercube.Client.Graphics;
using Hypercube.Client.Graphics.Rendering;
using Hypercube.Client.Graphics.Texturing;
using Hypercube.Client.Graphics.Viewports;
using Hypercube.Client.Input.Handler;
using Hypercube.Client.Input.Manager;
using Hypercube.Client.Runtimes;
Expand Down Expand Up @@ -38,6 +39,9 @@ public static void Register(DependenciesContainer rootContainer)
// Texturing
rootContainer.Register<ITextureManager, TextureManager>();

// Camera
rootContainer.Register<ICameraManager, CameraManager>();

// Rendering
rootContainer.Register<IRenderer, Renderer>();

Expand Down
21 changes: 16 additions & 5 deletions Hypercube.Client/Graphics/Rendering/Renderer.Render.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
using Hypercube.Client.Graphics.Viewports;
using Hypercube.Shared.Math;
using Hypercube.Shared.Math.Box;
using Hypercube.Shared.Math.Matrix;
using Hypercube.Shared.Math.Vector;
using Hypercube.Shared.Runtimes.Loop.Event;
using OpenToolkit.Graphics.OpenGL4;

Expand Down Expand Up @@ -40,6 +42,8 @@ private void OnLoad()
_baseTexture = _textureManager.CreateHandler("/icon.png");
_baseTexture.Bind();

_cameraManager.SetMainCamera(_cameraManager.CreateCamera2D(MainWindow.Size));

_vbo = new BufferObject(BufferTarget.ArrayBuffer);
_ebo = new BufferObject(BufferTarget.ElementArrayBuffer);
_vao = new ArrayObject();
Expand All @@ -64,9 +68,10 @@ private void OnLoad()
private void OnFrameUpdate(UpdateFrameEvent args)
{
#if DEBUG
_windowManager.WindowSetTitle(MainWindow, $"FPS: {_timing.Fps} | RealTime: {_timing.RealTime}");
_windowManager.WindowSetTitle(MainWindow, $"FPS: {_timing.Fps} | RealTime: {_timing.RealTime} | cPos: {_cameraManager.MainCamera?.Position ?? null} | cRot: {_cameraManager.MainCamera?.Rotation ?? null}");
#endif
_windowManager.PollEvents();
_cameraManager.UpdateInput(_cameraManager.MainCamera, args.DeltaSeconds);
}

private void OnFrameRender(RenderFrameEvent args)
Expand All @@ -83,14 +88,20 @@ private void OnFrameRender(RenderFrameEvent args)
var colorG = new Color(0f, sin, 0f);
var colorB = new Color(0f, 0f, sin);

DrawTexture(_baseTexture, new Box2(-1.0f, 1.0f, 0.0f, 0.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), Color.White);
DrawTexture(_baseTexture, new Box2(0.0f, 1.0f, 1.0f, 0.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorR);
DrawTexture(_baseTexture, new Box2(-1.0f, 0.0f, 0.0f, -1.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorG);
DrawTexture(_baseTexture, new Box2(0.0f, 0.0f, 1.0f, -1.0f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorB);
DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitY * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), Color.White);
DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitX * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorR);
DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(-Vector2.UnitX * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorG);
DrawTexture(_baseTexture, _baseTexture.Texture.QuadCrateTranslated(Vector2.UnitY * 60f), new Box2(0.0f, 1.0f, 1.0f, 0.0f), colorB);

BatchUpdate();

var model = Matrix4X4.CreateTranslation(Vector2.Zero) * Matrix4X4.CreateRotationZ(0) * Matrix4X4.CreateScale(Vector2.One);
var view = Matrix4X4.CreateTranslation(0.0f, 0.0f, -3.0f);

_baseShader.Use();
_baseShader.SetUniform("model", model);
_baseShader.SetUniform("view", view);
_baseShader.SetUniform("projection", _cameraManager.Projection);

_vao.Bind();
GL.DrawElements(BeginMode.Triangles, (int) _batchIndexIndex, DrawElementsType.UnsignedInt, 0);
Expand Down
5 changes: 3 additions & 2 deletions Hypercube.Client/Graphics/Rendering/Renderer.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.Frozen;
using Hypercube.Client.Graphics.Event;
using System.Collections.Frozen;
using Hypercube.Client.Graphics.OpenGL;
using Hypercube.Client.Graphics.Texturing;
using Hypercube.Client.Graphics.Viewports;
using Hypercube.Client.Graphics.Windows;
using Hypercube.Client.Graphics.Windows.Manager;
using Hypercube.Shared.Dependency;
Expand All @@ -22,6 +22,7 @@ public sealed partial class Renderer : IRenderer, IPostInject
[Dependency] private readonly IEventBus _eventBus = default!;
[Dependency] private readonly ITextureManager _textureManager = default!;
[Dependency] private readonly ITiming _timing = default!;
[Dependency] private readonly ICameraManager _cameraManager = default!;
[Dependency] private readonly IResourceManager _resourceManager = default!;

private readonly ILogger _logger = LoggingManager.GetLogger("renderer");
Expand Down
7 changes: 6 additions & 1 deletion Hypercube.Client/Graphics/Shading/IShader.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
namespace Hypercube.Client.Graphics.Shading;
using Hypercube.Shared.Math.Matrix;

namespace Hypercube.Client.Graphics.Shading;

public interface IShader
{
void Use();
int GetUniformLocation(string name);
void SetUniform(string name, int value);
void SetUniform(string name, Matrix4X4 value, bool transpose = false);
void SetUniform(int index, Matrix4X4 value, bool transpose = false);
}
23 changes: 20 additions & 3 deletions Hypercube.Client/Graphics/Shading/Shader.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
using Hypercube.Shared.Math.Vector;
using Hypercube.Shared.Math.Matrix;
using Hypercube.Shared.Math.Vector;
using Hypercube.Shared.Resources;
using Hypercube.Shared.Resources.Manager;
using OpenToolkit.Graphics.OpenGL4;
using Vector2 = Hypercube.Shared.Math.Vector.Vector2;

namespace Hypercube.Client.Graphics.Shading;

Expand Down Expand Up @@ -57,12 +57,17 @@ public void Use()
GL.UseProgram(_handle);
}

public int GetUniformLocation(string name)
{
return GL.GetUniformLocation(_handle, name);
}

public void SetUniform(string name, int value)
{
GL.UseProgram(_handle);
GL.Uniform1(_uniformLocations[name], value);
}

public void SetUniform(string name, Vector2Int value)
{
GL.UseProgram(_handle);
Expand All @@ -80,6 +85,18 @@ public void SetUniform(string name, Vector2 value)
GL.UseProgram(_handle);
GL.Uniform2(_uniformLocations[name], value.X, value.Y);
}

public void SetUniform(string name, Matrix4X4 value, bool transpose = false)
{
SetUniform(GL.GetUniformLocation(_handle, name), value, transpose);
}

public void SetUniform(int index, Matrix4X4 value, bool transpose = false)
{
var matrix = transpose ? Matrix4X4.Transpose(value) : new Matrix4X4(value);
GL.UseProgram(_handle);
GL.UniformMatrix4(index, 1, false, matrix.ToArray());
}

private int CreateShader(string source, ShaderType type)
{
Expand Down
2 changes: 1 addition & 1 deletion Hypercube.Client/Graphics/Vertex.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public readonly struct Vertex
private static readonly Color DefaultColor = Color.White;

public readonly Vector3 Position;
public readonly Vector2 UVCoords;
public readonly Color Color;
public readonly Vector2 UVCoords;

public Vertex(Vector3 position, Vector2 uvCoords, Color color)
{
Expand Down
57 changes: 42 additions & 15 deletions Hypercube.Client/Graphics/Viewports/Camera2D.cs
Original file line number Diff line number Diff line change
@@ -1,37 +1,64 @@
using Hypercube.Shared.Math.Box;
using Hypercube.Shared.Math.Matrix;
using Hypercube.Shared.Math.Matrix;
using Hypercube.Shared.Math.Vector;

namespace Hypercube.Client.Graphics.Viewports;

public class Camera2D : ICamera
{
public float ZFar { get; private set; }
public float ZNear { get; private set; }
public Vector2 Position { get; private set; }
public float Zoom { get; private set; }
public Vector3 Position { get; private set; }
public Vector3 Rotation { get; private set; }
public Vector3 Scale { get; private set; } = Vector3.One;

private readonly float _zFar;
private readonly float _zNear;
private Vector2Int Size { get; set; }

public Matrix4X4 Projection;

private Vector2 HalfSize => Size / 2f;
public Matrix4X4 Projection { get; private set; }

public void SetPosition(Vector2 position)
public Camera2D(Vector2Int size, Vector2 position, float zNear, float zFar)
{
Size = size;
Position = new Vector3(position);
_zNear = zNear;
_zFar = zFar;

UpdateProjection();
}

public void SetSize(Vector2Int size)
{
Size = size;
UpdateProjection();
}

public void SetPosition(Vector3 position)
{
Position = position;
UpdateProjection();
}

public void SetZoom(float zoom)
public void SetRotation(Vector3 rotation)
{
Rotation = Rotation.WithZ(rotation.Z);
UpdateProjection();
}

public void SetScale(Vector3 scale)
{
Zoom = zoom;
Scale = scale;
UpdateProjection();
}

private void UpdateProjection()
{
var size = new Box2();
var projection = Matrix4X4.CreateOrthographic(Size, _zNear, _zFar);

var projection = Matrix4X4.CreateOrthographic(size, ZNear, ZFar);
var scale = Matrix4X4.CreateScale(Zoom);

Projection = projection * scale;
var translate = Matrix4X4.CreateTranslation(Position);
var rotation = Matrix4X4.CreateRotationZ(Rotation.Z);
var scale = Matrix4X4.CreateScale(Scale);

Projection = projection * translate * rotation * scale;
}
}
69 changes: 60 additions & 9 deletions Hypercube.Client/Graphics/Viewports/CameraManager.cs
Original file line number Diff line number Diff line change
@@ -1,20 +1,71 @@
using Hypercube.Shared.Dependency;
using Hypercube.Shared.EventBus;
using Hypercube.Shared.Runtimes.Loop.Event;
using Hypercube.Client.Input;
using Hypercube.Client.Input.Handler;
using Hypercube.Shared.Dependency;
using Hypercube.Shared.Math.Matrix;
using Hypercube.Shared.Math.Vector;

namespace Hypercube.Client.Graphics.Viewports;

public class CameraManager : ICameraManager, IPostInject
public class CameraManager : ICameraManager
{
[Dependency] private readonly IEventBus _eventBus = default!;
[Dependency] private readonly IInputHandler _inputHandler = default!;

public void PostInject()
public ICamera? MainCamera { get; private set; }
public Matrix4X4 Projection => MainCamera?.Projection ?? Matrix4X4.Identity;

public void UpdateInput(ICamera? camera, float delta)
{
_eventBus.Subscribe<UpdateFrameEvent>(OnUpdate);
if (camera is null)
return;

// Debug camera controls
var position = camera.Position;
var rotation = camera.Rotation;
var scale = camera.Scale;

var speed = 20f;

if (_inputHandler.IsKeyDown(Key.W))
position -= Vector3.UnitY * speed * delta;

if (_inputHandler.IsKeyDown(Key.S))
position += Vector3.UnitY * speed * delta;

if (_inputHandler.IsKeyDown(Key.A))
position += Vector3.UnitX * speed * delta;

if (_inputHandler.IsKeyDown(Key.D))
position -= Vector3.UnitX * speed * delta;

if (_inputHandler.IsKeyDown(Key.Q))
rotation -= Vector3.UnitZ * delta;

if (_inputHandler.IsKeyDown(Key.E))
rotation += Vector3.UnitZ * delta;

if (_inputHandler.IsKeyDown(Key.T))
scale -= Vector3.One * delta;

if (_inputHandler.IsKeyDown(Key.Y))
scale += Vector3.One * delta;

camera.SetPosition(position);
camera.SetRotation(rotation);
camera.SetScale(scale);
}

private void OnUpdate(UpdateFrameEvent args)
public void SetMainCamera(ICamera camera)
{

MainCamera = camera;
}

public ICamera CreateCamera2D(Vector2Int size)
{
return CreateCamera2D(size, Vector2.Zero);
}

public ICamera CreateCamera2D(Vector2Int size, Vector2 position, float zNear = 0.1f, float zFar = 100f)
{
return new Camera2D(size, position, zNear, zFar);
}
}
13 changes: 12 additions & 1 deletion Hypercube.Client/Graphics/Viewports/ICamera.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
namespace Hypercube.Client.Graphics.Viewports;
using Hypercube.Shared.Math.Matrix;
using Hypercube.Shared.Math.Vector;

namespace Hypercube.Client.Graphics.Viewports;

public interface ICamera
{
Matrix4X4 Projection { get; }

Vector3 Position { get; }
Vector3 Rotation { get; }
Vector3 Scale { get; }

void SetPosition(Vector3 position);
void SetRotation(Vector3 rotation);
void SetScale(Vector3 scale);
}
11 changes: 9 additions & 2 deletions Hypercube.Client/Graphics/Viewports/ICameraManager.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
namespace Hypercube.Client.Graphics.Viewports;
using Hypercube.Shared.Math.Matrix;
using Hypercube.Shared.Math.Vector;

namespace Hypercube.Client.Graphics.Viewports;

public interface ICameraManager
{

ICamera? MainCamera { get; }
Matrix4X4 Projection { get; }
void SetMainCamera(ICamera camera);
ICamera CreateCamera2D(Vector2Int size);
void UpdateInput(ICamera? camera, float delta);
}
Loading

0 comments on commit be88aab

Please sign in to comment.