diff --git a/GlitchyEngine/src/Renderer/CameraComponent.bf b/GlitchyEngine/src/Renderer/CameraComponent.bf new file mode 100644 index 0000000..2a9f379 --- /dev/null +++ b/GlitchyEngine/src/Renderer/CameraComponent.bf @@ -0,0 +1,98 @@ +using GlitchyEngine.Math; + +namespace GlitchyEngine.Renderer +{ + public struct CameraComponent + { + public enum Projection + { + /** + * A perspective projection with near and far plane. + */ + Perspective, + /** + * A perspective projection with near and far plane, + * except that the closer a pixel is to the far plane the smaller its depth-value gets. + */ + PerspectiveReversed, + /** + * A perspective projection with a near plane and a far plane at infinite distance. + */ + PerspectiveInfinite, + /** + * A perspective projection with a near plane and a far plane at infinite distance, + * except that the closer a pixel is to the far plane the smaller its depth-value gets. + */ + PerspectiveReversedInfinite, + /** + * An orthographic projection. + */ + Orthographic + } + + float _nearPlane; + float _farPlane; + Projection _projectionType; + float _fovY; + float _aspect; + + public float NearPlane + { + get => _nearPlane; + set mut => _nearPlane = value; + } + + public float FarPlane + { + get => _farPlane; + set mut => _farPlane = value; + } + + public Projection ProjectionType + { + get => _projectionType; + set mut => _projectionType = value; + } + + public float FovY + { + get => _fovY; + set mut => _fovY = value; + } + + public float FovX + { + get => _fovY * _aspect; + set mut => _fovY = value / _aspect; + } + + public float Aspect + { + get => _aspect; + set mut => _aspect = value; + } + + public Matrix Projection => CalculateProjection(); + + public Matrix CalculateProjection() + { + Log.EngineLogger.Assert(_nearPlane < _farPlane, "The near plane must be smaller than the far plane."); + + switch(_projectionType) + { + case .Perspective: + return Matrix.PerspectiveProjection(_fovY, _aspect, _nearPlane, _farPlane); + case .PerspectiveReversed: + return Matrix.ReversedPerspectiveProjection(_fovY, _aspect, _nearPlane, _farPlane); + case .PerspectiveInfinite: + return Matrix.InfinitePerspectiveProjection(_fovY, _aspect, _nearPlane); + case .PerspectiveReversedInfinite: + return Matrix.ReversedInfinitePerspectiveProjection(_fovY, _aspect, _nearPlane); + default: + Log.EngineLogger.Assert(false, "Unknown projection type."); + } + + return .Identity; + } + } +} diff --git a/GlitchyEngine/src/Renderer/MeshComponent.bf b/GlitchyEngine/src/Renderer/MeshComponent.bf new file mode 100644 index 0000000..adca007 --- /dev/null +++ b/GlitchyEngine/src/Renderer/MeshComponent.bf @@ -0,0 +1,7 @@ +namespace GlitchyEngine.Renderer +{ + public struct MeshComponent + { + public GeometryBinding Mesh; + } +} diff --git a/GlitchyEngine/src/Renderer/Renderer.bf b/GlitchyEngine/src/Renderer/Renderer.bf index 11cf6cc..2734908 100644 --- a/GlitchyEngine/src/Renderer/Renderer.bf +++ b/GlitchyEngine/src/Renderer/Renderer.bf @@ -1,4 +1,5 @@ using GlitchyEngine.Math; +using GlitchyEngine.World; namespace GlitchyEngine.Renderer { @@ -36,6 +37,18 @@ namespace GlitchyEngine.Renderer RenderCommand.Init(); } + public static void BeginScene(EcsWorld world, Entity cameraEntity) + { + var camera = world.GetComponent(cameraEntity); + var transform = world.GetComponent(cameraEntity); + + var trans = transform.Transform; + var view = trans.Invert(); + var proj = camera.Projection; + + _sceneConstants.ViewProjection = proj * view; + } + public static void BeginScene(Camera camera) { _sceneConstants.ViewProjection = camera.ViewProjection; diff --git a/GlitchyEngine/src/World/TransformComponent.bf b/GlitchyEngine/src/World/TransformComponent.bf index 0ba7758..97ca31e 100644 --- a/GlitchyEngine/src/World/TransformComponent.bf +++ b/GlitchyEngine/src/World/TransformComponent.bf @@ -4,16 +4,67 @@ namespace GlitchyEngine.World { public struct TransformComponent { - static int _id; + Vector3 _position = .Zero; + Vector3 _rotation = .Zero; + Vector3 _scale = .One; - public static int ID {get => _id; set => _id = value; } - - internal Matrix _transform; + Matrix _transform; + bool _dirty; public Matrix Transform { - get => _transform; + get mut + { + return _transform; + } set mut => _transform = value; } + public Vector3 Position + { + get => _position; + set mut + { + if(_position == value) + return; + + _position = value; + _dirty = true; + } + } + + public Vector3 Rotation + { + get => _rotation; + set mut + { + if(_rotation == value) + return; + + _rotation = value; + _dirty = true; + } + } + + public Vector3 Scale + { + get => _scale; + set mut + { + if(_scale == value) + return; + + _scale = value; + _dirty = true; + } + } + + public void Update() mut + { + if(!_dirty) + return; + _transform = .Translation(_position) * .RotationX(_rotation.X) * + .RotationY(_rotation.Y) * .RotationZ(_rotation.Z) * .Scaling(_scale); + _dirty = false; + } } } diff --git a/GlitchyEngine/vendor/directx b/GlitchyEngine/vendor/directx index a56056a..7fc4733 160000 --- a/GlitchyEngine/vendor/directx +++ b/GlitchyEngine/vendor/directx @@ -1 +1 @@ -Subproject commit a56056a441494f646cd930fe2d8ec41751539cd8 +Subproject commit 7fc473343221fbd90624542ca31974203e0b9ea6 diff --git a/Sandbox/src/SandboxApp.bf b/Sandbox/src/SandboxApp.bf index 3d33cba..f46368e 100644 --- a/Sandbox/src/SandboxApp.bf +++ b/Sandbox/src/SandboxApp.bf @@ -7,13 +7,12 @@ using GlitchyEngine.ImGui; using ImGui; using GlitchyEngine.Renderer; using GlitchyEngine.Math; +using GlitchyEngine.World; namespace Sandbox { class ExampleLayer : Layer { - private OrthographicCamera _camera ~ delete _; // PerspectiveCamera - [Ordered] struct VertexColorTexture : IVertexData { @@ -69,6 +68,8 @@ namespace Sandbox EffectLibrary _effectLibrary ~ delete _; + EcsWorld _world = new EcsWorld() ~ delete _; + private Vector3 CircleCoord(float angle) { return .(Math.Cos(angle), Math.Sin(angle), 0); @@ -159,18 +160,6 @@ namespace Sandbox GlitchyEngine.Renderer.RasterizerStateDescription rsDesc = .(.Solid, .Back, true); _rasterizerState = new RasterizerState(_context, rsDesc); - // Camera - _camera = new OrthographicCamera(); - _camera.NearPlane = -1; - _camera.FarPlane = 1; - /* - _camera = new PerspectiveCamera(); - _camera.NearPlane = 0.1f; - _camera.FarPlane = 10.0f; - _camera.FovY = Math.PI_f / 4; - _camera.Position = .(0, -1, -5); - */ - _texture = new Texture2D(_context, "content/Textures/Checkerboard.dds"); _ge_logo = new Texture2D(_context, "content/Textures/GE_Logo.dds"); @@ -189,10 +178,45 @@ namespace Sandbox blendDesc.RenderTarget[0] = .(true, .SourceAlpha, .InvertedSourceAlpha, .Add, .SourceAlpha, .InvertedSourceAlpha, .Add, .All); _alphaBlendState = new BlendState(_context, blendDesc); _opaqueBlendState = new BlendState(_context, .Default); + + InitEcs(); + } + + Entity _cameraEntity; + + void InitEcs() + { + _world.Register(); + _world.Register(); + _world.Register(); + + // Create camera entity + _cameraEntity = _world.NewEntity(); + var cameraTransform = _world.AssignComponent(_cameraEntity); + var camera = _world.AssignComponent(_cameraEntity); + *cameraTransform = TransformComponent(); + camera.NearPlane = 0.1f; + camera.FarPlane = 10.0f; + camera.FovY = Math.PI_f / 4; + cameraTransform.Position = .(0, -1, -5); + + for(int x < 20) + for(int y < 20) + { + Entity entity = _world.NewEntity(); + + var transform = _world.AssignComponent(entity); + transform.Transform = Matrix.Translation(x * 0.2f, y * 0.2f, 0) * Matrix.Scaling(0.1f); + + var mesh = _world.AssignComponent(entity); + mesh.Mesh = _quadGeometryBinding; + } } public override void Update(GameTime gameTime) { + var cameraTransform = _world.GetComponent(_cameraEntity); + if(Application.Get().Window.IsActive) { Vector2 movement = .(); @@ -220,16 +244,13 @@ namespace Sandbox movement *= (float)(gameTime.FrameTime.TotalSeconds); - _camera.Position += .(movement, 0); + cameraTransform.Position += .(movement, 0); + cameraTransform.Update(); } - _camera.Width = _context.SwapChain.BackbufferViewport.Width / 256; - _camera.Height = _context.SwapChain.BackbufferViewport.Height / 256; - - //_camera.AspectRatio = Application.Get().Window.Context.SwapChain.BackbufferViewport.Width / - // Application.Get().Window.Context.SwapChain.BackbufferViewport.Height; - - _camera.Update(); + var camera = _world.GetComponent(_cameraEntity); + camera.Aspect = Application.Get().Window.Context.SwapChain.BackbufferViewport.Width / + Application.Get().Window.Context.SwapChain.BackbufferViewport.Height; RenderCommand.Clear(null, .(0.2f, 0.2f, 0.2f)); @@ -241,23 +262,33 @@ namespace Sandbox _context.SetViewport(_context.SwapChain.BackbufferViewport); - Renderer.BeginScene(_camera); + Renderer.BeginScene(_world, _cameraEntity); _opaqueBlendState.Bind(); var basicEffect = _effectLibrary.Get("basicShader"); var textureEffect = _effectLibrary.Get("textureShader"); - for(int x < 20) - for(int y < 20) + for(var entity in _world.Enumerate(typeof(TransformComponent))) { - if((x + y) % 2 == 0) + var transform = _world.GetComponent(entity); + transform.Update(); + } + + int i = 0; + for(var entity in _world.Enumerate(typeof(TransformComponent), typeof(MeshComponent))) + { + i++; + + if(i % 2 == 0) basicEffect.Variables["BaseColor"].SetData(_squareColor0); else basicEffect.Variables["BaseColor"].SetData(_squareColor1); - Matrix transform = Matrix.Translation(x * 0.2f, y * 0.2f, 0) * Matrix.Scaling(0.1f); - Renderer.Submit(_quadGeometryBinding, basicEffect, transform); + var transform = _world.GetComponent(entity); + var mesh = _world.GetComponent(entity); + + Renderer.Submit(mesh.Mesh, basicEffect, transform.Transform); } basicEffect.Variables["BaseColor"].SetData(_squareColor1);