From 4054a9b0c26f92512af84e3af650072217fdab0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20L=C3=BCbe=C3=9F?= Date: Sat, 9 Jan 2021 12:05:05 +0100 Subject: [PATCH] Added Camera, Renderer, ... and moved example to sandbox --- GlitchyEngine/src/Application.bf | 171 +---------------- .../Platform/DX11/Renderer/Dx11RendererAPI.bf | 27 +++ .../src/Renderer/BufferCollection.bf | 33 ++++ GlitchyEngine/src/Renderer/Camera.bf | 112 ++++++++++++ GlitchyEngine/src/Renderer/Effect.bf | 31 ++++ .../src/Renderer/OrthographicCamera.bf | 92 ++++++++++ .../src/Renderer/PerspectiveCamera.bf | 104 +++++++++++ GlitchyEngine/src/Renderer/RenderCommand.bf | 28 +++ GlitchyEngine/src/Renderer/Renderer.bf | 42 +++++ GlitchyEngine/src/Renderer/RendererAPI.bf | 22 +++ Sandbox/content/basicShader.hlsl | 2 +- Sandbox/src/SandboxApp.bf | 173 +++++++++++++++++- 12 files changed, 670 insertions(+), 167 deletions(-) create mode 100644 GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf create mode 100644 GlitchyEngine/src/Renderer/Camera.bf create mode 100644 GlitchyEngine/src/Renderer/Effect.bf create mode 100644 GlitchyEngine/src/Renderer/OrthographicCamera.bf create mode 100644 GlitchyEngine/src/Renderer/PerspectiveCamera.bf create mode 100644 GlitchyEngine/src/Renderer/RenderCommand.bf create mode 100644 GlitchyEngine/src/Renderer/Renderer.bf create mode 100644 GlitchyEngine/src/Renderer/RendererAPI.bf diff --git a/GlitchyEngine/src/Application.bf b/GlitchyEngine/src/Application.bf index 0c10bbb..6f63430 100644 --- a/GlitchyEngine/src/Application.bf +++ b/GlitchyEngine/src/Application.bf @@ -2,9 +2,6 @@ using System; using GlitchyEngine.Events; using GlitchyEngine.ImGui; using GlitchyEngine.Math; -using DirectX.D3D11; -using DirectX.Common; -using DirectX.D3DCompiler; using System.Diagnostics; using GlitchyEngine.Renderer; @@ -15,6 +12,7 @@ namespace GlitchyEngine static Application s_Instance = null; private Window _window ~ delete _; + private RendererAPI _rendererApi ~ delete _; private bool _running = true; private LayerStack _layerStack = new LayerStack() ~ delete _; @@ -37,146 +35,15 @@ namespace GlitchyEngine _window = new Window(.Default); _window.EventCallback = new => OnEvent; + _rendererApi = new RendererAPI(); + _rendererApi.Context = _window.Context; + + RenderCommand.RendererAPI = _rendererApi; + + Renderer.Init(_window.Context); + _imGuiLayer = new ImGuiLayer(); PushOverlay(_imGuiLayer); - - MakeTestTriangle(); - } - - struct VertexColor : IVertexData - { - public Vector3 Position; - public Color Color; - - public this() => this = default; - - public this(Vector3 pos, Color color) - { - Position = pos; - Color = color; - } - - //public static readonly InputElementDescription[] InputLayout ~ delete _; - - public static readonly VertexLayout VertexLayout ~ delete _; - - public static VertexLayout IVertexData.VertexLayout => VertexLayout; - - static this() - { - //VertexLayout = new VertexLayout(); - } - } - - VertexLayout _vertexLayout ~ delete _; - - GeometryBinding _geometryBinding ~ delete _; - VertexBuffer _vertexBuffer ~ delete _; - IndexBuffer _indexBuffer ~ delete _; - - GeometryBinding _quadGeometryBinding ~ delete _; - VertexBuffer _quadVertexBuffer ~ delete _; - IndexBuffer _quadIndexBuffer ~ delete _; - - RasterizerState _rasterizerState ~ delete _; - - VertexShader _vertexShader ~ delete _; - PixelShader _pixelShader ~ delete _; - Buffer _cBuffer ~ delete _; - - private Vector3 CircleCoord(float angle) - { - return .(Math.Cos(angle), Math.Sin(angle), 0); - } - - private void MakeTestTriangle() - { - _vertexShader = Shader.FromFile!(_window.Context, "content\\basicShader.hlsl", "VS"); - - // Create Input Layout - - _vertexLayout = new VertexLayout(_window.Context, new .( - VertexElement(.R32G32B32_Float, "POSITION"), - VertexElement(.R8G8B8A8_UNorm, "COLOR"), - ), _vertexShader); - - // - // Load pixel shader - // - - _pixelShader = Shader.FromFile!(_window.Context, "content\\basicShader.hlsl", "PS"); - - //Todo: _pixelShader.[Friend]_buffers = new .[1]; - - _cBuffer = new Buffer(_window.Context, .(0, .Constant, .Immutable, .None)); - _cBuffer.Data = .White; - _cBuffer.Update(); - - _pixelShader.Buffers.ReplaceBuffer("Constants", _cBuffer); - - // Create hexagon - { - _geometryBinding = new GeometryBinding(_window.Context); - _geometryBinding.SetPrimitiveTopology(.TriangleList); - _geometryBinding.SetVertexLayout(_vertexLayout); - - float pO3 = Math.PI_f / 3.0f; - VertexColor[?] vertices = .( - VertexColor(.Zero, Color(255,255,255)), - VertexColor(CircleCoord(0), Color(255, 0, 0)), - VertexColor(CircleCoord(pO3), Color(255,255, 0)), - VertexColor(CircleCoord(pO3*2), Color( 0,255, 0)), - VertexColor(CircleCoord(Math.PI_f), Color( 0,255,255)), - VertexColor(CircleCoord(-pO3*2), Color( 0, 0,255)), - VertexColor(CircleCoord(-pO3), Color(255, 0,255)), - ); - - _vertexBuffer = new VertexBuffer(Window.Context, typeof(VertexColor), (.)vertices.Count, .Immutable); - _vertexBuffer.SetData(vertices); - _geometryBinding.SetVertexBufferSlot(_vertexBuffer, 0); - - uint16[?] indices = .( - 0, 1, 2, - 0, 2, 3, - 0, 3, 4, - 0, 4, 5, - 0, 5, 6, - 0, 6, 1); - - _indexBuffer = new IndexBuffer(Window.Context, (.)indices.Count, .Immutable); - _indexBuffer.SetData(indices); - _geometryBinding.SetIndexBuffer(_indexBuffer); - } - - // Create Quad - { - _quadGeometryBinding = new GeometryBinding(_window.Context); - _quadGeometryBinding.SetPrimitiveTopology(.TriangleList); - _quadGeometryBinding.SetVertexLayout(_vertexLayout); - - VertexColor[?] vertices = .( - VertexColor(Vector3(-0.75f, 0.75f, 0), Color.Blue), - VertexColor(Vector3(-0.75f, -0.75f, 0), Color.Blue), - VertexColor(Vector3(0.75f, -0.75f, 0), Color.Blue), - VertexColor(Vector3(0.75f, 0.75f, 0), Color.Blue), - ); - - _quadVertexBuffer = new VertexBuffer(Window.Context, typeof(VertexColor), (.)vertices.Count, .Immutable); - _quadVertexBuffer.SetData(vertices); - _quadGeometryBinding.SetVertexBufferSlot(_quadVertexBuffer, 0); - - uint16[?] indices = .( - 0, 1, 2, - 2, 3, 0); - - _quadIndexBuffer = new IndexBuffer(Window.Context, (.)indices.Count, .Immutable); - _quadIndexBuffer.SetData(indices); - _quadGeometryBinding.SetIndexBuffer(_quadIndexBuffer); - } - - // Create rasterizer state - GlitchyEngine.Renderer.RasterizerStateDescription rsDesc = .(.Solid, .Back, true); - _rasterizerState = new RasterizerState(Window.Context, rsDesc); } public void OnEvent(Event e) @@ -200,28 +67,6 @@ namespace GlitchyEngine Input.NewFrame(); - _window.Context.ClearRenderTarget(null, .(0.2f, 0.2f, 0.2f)); - - // Draw test geometry - { - _window.Context.SetRenderTarget(null); - _window.Context.BindRenderTargets(); - - _window.Context.SetVertexShader(_vertexShader); - - _window.Context.SetPixelShader(_pixelShader); - - _window.Context.SetRasterizerState(_rasterizerState); - - _window.Context.SetViewport(Window.Context.SwapChain.BackbufferViewport); - - _geometryBinding.Bind(); - _window.Context.DrawIndexed(_geometryBinding.IndexCount); - - _quadGeometryBinding.Bind(); - _window.Context.DrawIndexed(_quadGeometryBinding.IndexCount); - } - for(Layer layer in _layerStack) layer.Update(_gameTime); diff --git a/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf new file mode 100644 index 0000000..b1df512 --- /dev/null +++ b/GlitchyEngine/src/Platform/DX11/Renderer/Dx11RendererAPI.bf @@ -0,0 +1,27 @@ +using GlitchyEngine.Math; + +namespace GlitchyEngine.Renderer +{ + extension RendererAPI + { + private GraphicsContext _context; + + public GraphicsContext Context + { + get => _context; + set => _context = value; + } + + public static override API Api => .D3D11; + + public override void Clear(RenderTarget renderTarget, ColorRGBA clearColor) + { + _context.ClearRenderTarget(renderTarget, clearColor); + } + + public override void DrawIndexed(GeometryBinding geometry) + { + _context.DrawIndexed(geometry.IndexCount, geometry.IndexByteOffset, 0); + } + } +} diff --git a/GlitchyEngine/src/Renderer/BufferCollection.bf b/GlitchyEngine/src/Renderer/BufferCollection.bf index 7700056..394cd61 100644 --- a/GlitchyEngine/src/Renderer/BufferCollection.bf +++ b/GlitchyEngine/src/Renderer/BufferCollection.bf @@ -105,6 +105,39 @@ namespace GlitchyEngine.Renderer } } + /** + * Replaces the buffer with the given name. + * @param name The name of the buffer to replace. + * @param buffer The new buffer. + * @param If set to true, the Collection will take ownership of the buffer; if false, the ownership will remain with the caller. + */ + public bool TryReplaceBuffer(StringView name, Buffer buffer, bool passOwnership = false) + { + if(_strToBuf.TryGetValue(name, let oldBuffer)) + { + int index = GetIndexOfBuffer(oldBuffer); + + ref BufferEntry bufferDesc = ref _buffers[index]; + + Log.EngineLogger.Assert(name == bufferDesc.Name); + + if(bufferDesc.OwnsBuffer) + delete bufferDesc.Buffer; + + bufferDesc.Buffer = buffer; + bufferDesc.OwnsBuffer = passOwnership; + + _strToBuf[bufferDesc.Name] = buffer; + _idxToBuf[bufferDesc.Index] = buffer; + + return true; + } + else + { + return false; + } + } + public void Add(int index, StringView name, Buffer buffer, bool passOwnership = false) { String nameStr = new String(name); diff --git a/GlitchyEngine/src/Renderer/Camera.bf b/GlitchyEngine/src/Renderer/Camera.bf new file mode 100644 index 0000000..e2b9006 --- /dev/null +++ b/GlitchyEngine/src/Renderer/Camera.bf @@ -0,0 +1,112 @@ +using System; +using GlitchyEngine.Math; + +namespace GlitchyEngine.Renderer +{ + public abstract class Camera + { + protected Matrix _view; + protected Matrix _transform; + protected Matrix _projection; + protected Matrix _viewProjection; + + protected float _nearPlane; + protected float _farPlane; + + protected Vector3 _position; + protected Vector3 _rotation; + + /// If true the transform matrix is outdated and needs to be recalculated. + protected bool _transformOutdated = true; + + /// If true the projection matrix is outdated and needs to be recalculated. + protected bool _projectionOutdated = true; + + public Matrix Transform => _transform; + + public Matrix View => _view; + + public Matrix Projection => _projection; + + public Matrix ViewProjection => _viewProjection; + + public float NearPlane + { + get => _nearPlane; + set + { + if(_nearPlane == value) + return; + + _nearPlane = value; + + _projectionOutdated = true; + } + } + + public float FarPlane + { + get => _farPlane; + set + { + if(_farPlane == value) + return; + + _farPlane = value; + + _projectionOutdated = true; + } + } + + public Vector3 Position + { + get => _position; + set + { + if(_position == value) + return; + + _position = value; + _transformOutdated = true; + } + } + + public Vector3 Rotation + { + get => _rotation; + set + { + if(_rotation == value) + return; + + _rotation = value; + _transformOutdated = true; + } + } + + public void Update() + { + bool changed = false; + + if(_transformOutdated) + { + UpdateTransform(); + _transformOutdated = false; + changed = true; + } + + if(_projectionOutdated) + { + UpdateProjection(); + _projectionOutdated = false; + changed = true; + } + + if(changed) + _viewProjection = _projection * _view; + } + + protected abstract void UpdateTransform(); + protected abstract void UpdateProjection(); + } +} diff --git a/GlitchyEngine/src/Renderer/Effect.bf b/GlitchyEngine/src/Renderer/Effect.bf new file mode 100644 index 0000000..4ee4e67 --- /dev/null +++ b/GlitchyEngine/src/Renderer/Effect.bf @@ -0,0 +1,31 @@ +using System; + +namespace GlitchyEngine.Renderer +{ + public class Effect + { + protected GraphicsContext _context; + internal VertexShader _vs; + internal PixelShader _ps; + + public GraphicsContext Context => _context; + + public VertexShader VertexShader + { + get => _vs; + set => _vs = value; + } + + public PixelShader PixelShader + { + get => _ps; + set => _ps = value; + } + + public void Bind(GraphicsContext context) + { + context.SetVertexShader(_vs); + context.SetPixelShader(_ps); + } + } +} diff --git a/GlitchyEngine/src/Renderer/OrthographicCamera.bf b/GlitchyEngine/src/Renderer/OrthographicCamera.bf new file mode 100644 index 0000000..28f610e --- /dev/null +++ b/GlitchyEngine/src/Renderer/OrthographicCamera.bf @@ -0,0 +1,92 @@ +using GlitchyEngine.Math; + +namespace GlitchyEngine.Renderer +{ + public class OrthographicCamera : Camera + { + protected float _bottom, _left, _right, _top; + + public float Bottom + { + get => _bottom; + set + { + if(_bottom == value) + return; + + _bottom = value; + _projectionOutdated = true; + } + } + + public float Left + { + get => _left; + set + { + if(_left == value) + return; + + _left = value; + _projectionOutdated = true; + } + } + + public float Right + { + get => _right; + set + { + if(_right == value) + return; + + _right = value; + _projectionOutdated = true; + } + } + + public float Top + { + get => _top; + set + { + if(_top == value) + return; + + _top = value; + _projectionOutdated = true; + } + } + + public float Width + { + get => _right - _left; + set + { + Left = -value / 2.0f; + Right = value / 2.0f; + } + } + + public float Height + { + get => _top - _bottom; + set + { + Bottom = -value / 2.0f; + Top = value / 2.0f; + } + } + + protected override void UpdateProjection() + { + _projection = Matrix.OrthographicProjectionOffCenter(_left, _right, _top, _bottom, _nearPlane, _farPlane); + } + + protected override void UpdateTransform() + { + _transform = Matrix.Translation(_position) * Matrix.RotationZ(_rotation.Z) * Matrix.RotationY(_rotation.Y) * Matrix.RotationX(_rotation.X); + _view = _transform.Invert(); + } + } +} diff --git a/GlitchyEngine/src/Renderer/PerspectiveCamera.bf b/GlitchyEngine/src/Renderer/PerspectiveCamera.bf new file mode 100644 index 0000000..e8e5c05 --- /dev/null +++ b/GlitchyEngine/src/Renderer/PerspectiveCamera.bf @@ -0,0 +1,104 @@ +using System; +using GlitchyEngine.Math; + +namespace GlitchyEngine.Renderer +{ + /** + * If FarPlane is float.PositiveInfinity the projection matrix will be an infinite projection (that means no far plane) + */ + public class PerspectiveCamera : Camera + { + public enum ProjectionType + { + /** + * The projection has a near and a far plane. The near plane has a depth of 0, the far plane a depth of 1. + */ + Limited, + /** + * The projection has a near and a far plane. The near plane has a depth of 1, the far plane a depth of 0. + */ + LimitedReversed, + /** + * The projection only has a near. The near plane has a depth of 0; infinite distance has a value of 1. + */ + Infinite, + /** + * The projection only has a near. The near plane has a depth of 1; infinite distance has a value of 0. + */ + InfiniteReversed + } + + protected ProjectionType _projectionType; + + protected float _fovY; + + protected float _aspect; + + /** + * Gets or Sets the projection type. + */ + public ProjectionType ProjectionType + { + get => _projectionType; + set + { + if(_projectionType == value) + return; + + _projectionType = value; + _projectionOutdated = true; + } + } + + public float FovY + { + get => _fovY; + set + { + if(_fovY == value) + return; + + _fovY = value; + _projectionOutdated = true; + } + } + + public float AspectRatio + { + get => _aspect; + set + { + if(_aspect == value) + return; + + _aspect = value; + _projectionOutdated = true; + } + } + + protected override void UpdateProjection() + { + Log.EngineLogger.Assert(_nearPlane < _farPlane, "The near plane must be smaller than the far plane."); + + switch(_projectionType) + { + case .Limited: + _projection = Matrix.PerspectiveProjection(_fovY, _aspect, _nearPlane, _farPlane); + case .LimitedReversed: + _projection = Matrix.ReversedPerspectiveProjection(_fovY, _aspect, _nearPlane, _farPlane); + case .Infinite: + _projection = Matrix.InfinitePerspectiveProjection(_fovY, _aspect, _nearPlane); // todo: epsilon + case .InfiniteReversed: + _projection = Matrix.ReversedInfinitePerspectiveProjection(_fovY, _aspect, _nearPlane); // todo: epsilon + default: + Log.EngineLogger.Assert(false, "Unknown projection type."); + } + } + + protected override void UpdateTransform() + { + _transform = Matrix.Translation(_position) * Matrix.RotationZ(_rotation.Z) * Matrix.RotationY(_rotation.Y) * Matrix.RotationX(_rotation.X); + _view = _transform.Invert(); + } + } +} diff --git a/GlitchyEngine/src/Renderer/RenderCommand.bf b/GlitchyEngine/src/Renderer/RenderCommand.bf new file mode 100644 index 0000000..331f209 --- /dev/null +++ b/GlitchyEngine/src/Renderer/RenderCommand.bf @@ -0,0 +1,28 @@ +using System; +using GlitchyEngine.Math; + +namespace GlitchyEngine.Renderer +{ + public static class RenderCommand + { + private static RendererAPI _rendererAPI; + + public static RendererAPI RendererAPI + { + get => _rendererAPI; + set => _rendererAPI = value; + } + + [Inline] + public static void Clear(RenderTarget renderTarget, ColorRGBA color) + { + _rendererAPI.Clear(renderTarget, color); + } + + [Inline] + public static void DrawIndexed(GeometryBinding geometry) + { + _rendererAPI.DrawIndexed(geometry); + } + } +} diff --git a/GlitchyEngine/src/Renderer/Renderer.bf b/GlitchyEngine/src/Renderer/Renderer.bf new file mode 100644 index 0000000..9f049b4 --- /dev/null +++ b/GlitchyEngine/src/Renderer/Renderer.bf @@ -0,0 +1,42 @@ +using GlitchyEngine.Math; + +namespace GlitchyEngine.Renderer +{ + public class Renderer + { + struct SceneConstants + { + public Matrix ViewProjection; + } + + static GraphicsContext _context; + + static Buffer _sceneConstants ~ delete _; + + public static void Init(GraphicsContext context) + { + _context = context; + _sceneConstants = new Buffer(_context, .(0, .Constant, .Dynamic, .Write)); + _sceneConstants.Update(); + } + + public static void BeginScene(Camera camera) + { + _sceneConstants.Data.ViewProjection = camera.ViewProjection; + _sceneConstants.Update(); + } + + public static void EndScene(){} + + public static void Submit(GeometryBinding geometry, Effect effect) + { + effect.Bind(_context); + + effect.PixelShader?.Buffers.TryReplaceBuffer("SceneConstants", _sceneConstants); + effect.VertexShader?.Buffers.TryReplaceBuffer("SceneConstants", _sceneConstants); + + geometry.Bind(); + RenderCommand.DrawIndexed(geometry); + } + } +} diff --git a/GlitchyEngine/src/Renderer/RendererAPI.bf b/GlitchyEngine/src/Renderer/RendererAPI.bf new file mode 100644 index 0000000..43bdf6a --- /dev/null +++ b/GlitchyEngine/src/Renderer/RendererAPI.bf @@ -0,0 +1,22 @@ +using GlitchyEngine.Math; + +namespace GlitchyEngine.Renderer +{ + public class RendererAPI + { + public enum API + { + None, + D3D11 + } + + /** + * Gets which graphics API is active. + */ + public static extern API Api { get; } + + public extern void Clear(RenderTarget renderTarget, ColorRGBA clearColor); + + public extern void DrawIndexed(GeometryBinding geometry); + } +} diff --git a/Sandbox/content/basicShader.hlsl b/Sandbox/content/basicShader.hlsl index 332338e..2a41105 100644 --- a/Sandbox/content/basicShader.hlsl +++ b/Sandbox/content/basicShader.hlsl @@ -1,4 +1,4 @@ -cbuffer Constants : register(b0) +cbuffer SceneConstants : register(b0) { float4x4 Transform = float4x4(1, 0, 0, 0, 0, 1, 0, 0, diff --git a/Sandbox/src/SandboxApp.bf b/Sandbox/src/SandboxApp.bf index d4425aa..4a2490c 100644 --- a/Sandbox/src/SandboxApp.bf +++ b/Sandbox/src/SandboxApp.bf @@ -5,18 +5,185 @@ using System.Diagnostics; using GlitchLog; using GlitchyEngine.ImGui; using ImGui; +using GlitchyEngine.Renderer; +using GlitchyEngine.Math; namespace Sandbox { class ExampleLayer : Layer { + private OrthographicCamera _camera ~ delete _; + + struct VertexColor : IVertexData + { + public Vector3 Position; + public Color Color; + + public this() => this = default; + + public this(Vector3 pos, Color color) + { + Position = pos; + Color = color; + } + + //public static readonly InputElementDescription[] InputLayout ~ delete _; + + public static readonly VertexLayout VertexLayout ~ delete _; + + public static VertexLayout IVertexData.VertexLayout => VertexLayout; + + static this() + { + //VertexLayout = new VertexLayout(); + } + } + + VertexLayout _vertexLayout ~ delete _; + + GeometryBinding _geometryBinding ~ delete _; + VertexBuffer _vertexBuffer ~ delete _; + IndexBuffer _indexBuffer ~ delete _; + + GeometryBinding _quadGeometryBinding ~ delete _; + VertexBuffer _quadVertexBuffer ~ delete _; + IndexBuffer _quadIndexBuffer ~ delete _; + + RasterizerState _rasterizerState ~ delete _; + + Effect _effect ~ delete _; + VertexShader _vertexShader ~ delete _; + PixelShader _pixelShader ~ delete _; + + Buffer _cBuffer ~ delete _; + + private Vector3 CircleCoord(float angle) + { + return .(Math.Cos(angle), Math.Sin(angle), 0); + } + [AllowAppend] - public this() : base("Example") { } + public this() : base("Example") + { + { + _effect = new Effect(); + + _vertexShader = Shader.FromFile!(Application.Get().Window.Context, "content\\basicShader.hlsl", "VS"); + _effect.VertexShader = _vertexShader; + + _pixelShader = Shader.FromFile!(Application.Get().Window.Context, "content\\basicShader.hlsl", "PS"); + _effect.PixelShader = _pixelShader; + } + + // Create Input Layout + + _vertexLayout = new VertexLayout(Application.Get().Window.Context, new .( + VertexElement(.R32G32B32_Float, "POSITION"), + VertexElement(.R8G8B8A8_UNorm, "COLOR"), + ), _vertexShader); + + _cBuffer = new Buffer(Application.Get().Window.Context, .(0, .Constant, .Immutable)); + _cBuffer.Data = .White; + _cBuffer.Update(); + + _pixelShader.Buffers.ReplaceBuffer("Constants", _cBuffer); + + // Create hexagon + { + _geometryBinding = new GeometryBinding(Application.Get().Window.Context); + _geometryBinding.SetPrimitiveTopology(.TriangleList); + _geometryBinding.SetVertexLayout(_vertexLayout); + + float pO3 = Math.PI_f / 3.0f; + VertexColor[?] vertices = .( + VertexColor(.Zero, Color(255,255,255)), + VertexColor(CircleCoord(0), Color(255, 0, 0)), + VertexColor(CircleCoord(pO3), Color(255,255, 0)), + VertexColor(CircleCoord(pO3*2), Color( 0,255, 0)), + VertexColor(CircleCoord(Math.PI_f), Color( 0,255,255)), + VertexColor(CircleCoord(-pO3*2), Color( 0, 0,255)), + VertexColor(CircleCoord(-pO3), Color(255, 0,255)), + ); + + _vertexBuffer = new VertexBuffer(Application.Get().Window.Context, typeof(VertexColor), (.)vertices.Count, .Immutable); + _vertexBuffer.SetData(vertices); + _geometryBinding.SetVertexBufferSlot(_vertexBuffer, 0); + + uint16[?] indices = .( + 0, 1, 2, + 0, 2, 3, + 0, 3, 4, + 0, 4, 5, + 0, 5, 6, + 0, 6, 1); + + _indexBuffer = new IndexBuffer(Application.Get().Window.Context, (.)indices.Count, .Immutable); + _indexBuffer.SetData(indices); + _geometryBinding.SetIndexBuffer(_indexBuffer); + } + + // Create Quad + { + _quadGeometryBinding = new GeometryBinding(Application.Get().Window.Context); + _quadGeometryBinding.SetPrimitiveTopology(.TriangleList); + _quadGeometryBinding.SetVertexLayout(_vertexLayout); + + VertexColor[?] vertices = .( + VertexColor(Vector3(-0.75f, 0.75f, 0), Color.Blue), + VertexColor(Vector3(-0.75f, -0.75f, 0), Color.Blue), + VertexColor(Vector3(0.75f, -0.75f, 0), Color.Blue), + VertexColor(Vector3(0.75f, 0.75f, 0), Color.Blue), + ); + + _quadVertexBuffer = new VertexBuffer(Application.Get().Window.Context, typeof(VertexColor), (.)vertices.Count, .Immutable); + _quadVertexBuffer.SetData(vertices); + _quadGeometryBinding.SetVertexBufferSlot(_quadVertexBuffer, 0); + + uint16[?] indices = .( + 0, 1, 2, + 2, 3, 0); + + _quadIndexBuffer = new IndexBuffer(Application.Get().Window.Context, (.)indices.Count, .Immutable); + _quadIndexBuffer.SetData(indices); + _quadGeometryBinding.SetIndexBuffer(_quadIndexBuffer); + } + + // Create rasterizer state + GlitchyEngine.Renderer.RasterizerStateDescription rsDesc = .(.Solid, .Back, true); + _rasterizerState = new RasterizerState(Application.Get().Window.Context, rsDesc); + + // Camera + _camera = new OrthographicCamera(); + _camera.NearPlane = -1; + _camera.FarPlane = 1; + } public override void Update(GameTime gameTime) { - if(Input.IsKeyPressed(.Tab)) - Log.ClientLogger.Info("Tab key is pressed!"); + _camera.Width = Application.Get().Window.Context.SwapChain.BackbufferViewport.Width / 256; + _camera.Height = Application.Get().Window.Context.SwapChain.BackbufferViewport.Height / 256; + + _camera.Update(); + + RenderCommand.Clear(null, .(0.2f, 0.2f, 0.2f)); + + // Draw test geometry + Application.Get().Window.Context.SetRenderTarget(null); + Application.Get().Window.Context.BindRenderTargets(); + + Application.Get().Window.Context.SetRasterizerState(_rasterizerState); + + Application.Get().Window.Context.SetViewport(Application.Get().Window.Context.SwapChain.BackbufferViewport); + + RenderCommand.SetViewport(Application.Get().Window.Context.SwapChain.BackbufferViewport); + + Renderer.BeginScene(_camera); + + Renderer.Submit(_geometryBinding, _effect); + Renderer.Submit(_quadGeometryBinding, _effect); + + Renderer.EndScene(); + } public override void OnEvent(Event event)