From bb0ab53c0648c46b6ab301328e2b20713e5c0037 Mon Sep 17 00:00:00 2001 From: copygirl Date: Fri, 4 Nov 2022 21:44:32 +0100 Subject: [PATCH] Split Render system into 3 --- src/gaemstone.Client/Systems/Renderer.cs | 131 ++++++++++++----------- 1 file changed, 69 insertions(+), 62 deletions(-) diff --git a/src/gaemstone.Client/Systems/Renderer.cs b/src/gaemstone.Client/Systems/Renderer.cs index 9571a5e..3ccbbb8 100644 --- a/src/gaemstone.Client/Systems/Renderer.cs +++ b/src/gaemstone.Client/Systems/Renderer.cs @@ -15,7 +15,10 @@ using static gaemstone.Components.TransformComponents; namespace gaemstone.Client.Systems; [Module] -[DependsOn(typeof(Windowing))] +[DependsOn(typeof(gaemstone.Components.TransformComponents))] +[DependsOn(typeof(gaemstone.Client.Components.CameraComponents))] +[DependsOn(typeof(gaemstone.Client.Components.RenderingComponents))] +[DependsOn(typeof(gaemstone.Client.Systems.Windowing))] public class Renderer : IModuleInitializer { @@ -51,77 +54,81 @@ public class Renderer _modelMatrixUniform = GL.GetUniformLocation(_program, "modelMatrix"); } - [System(typeof(SystemPhase.OnStore))] - public void Render(Universe universe, GameWindow window, Canvas canvas) + [System(typeof(SystemPhase.PreStore))] + public void Clear(Canvas canvas) { var GL = canvas.GL; GL.UseProgram(_program); GL.Viewport(default, canvas.Size); GL.ClearColor(new Vector4D(0, 0, 0, 255)); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + } - Filter.RunOnce(universe, (in GlobalTransform cameraTransform, - in Camera camera, CameraViewport? viewport) => { - var color = viewport?.ClearColor ?? new(0x4B, 0x00, 0x82, 255); - var bounds = viewport?.Viewport ?? new(default, canvas.Size); - - GL.Enable(EnableCap.ScissorTest); - GL.Viewport(bounds); GL.Scissor(bounds.Origin.X, bounds.Origin.Y, (uint)bounds.Size.X, (uint)bounds.Size.Y); - GL.ClearColor(color); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); - GL.Disable(EnableCap.ScissorTest); - - // Get the camera's transform matrix and invert it. - Matrix4X4.Invert(cameraTransform, out var invertedTransform); - - // Create the camera's projection matrix. - var cameraProjection = camera.IsOrthographic - ? Matrix4X4.CreateOrthographic( - bounds.Size.X, -bounds.Size.Y, - camera.NearPlane, camera.FarPlane) - : Matrix4X4.CreatePerspectiveFieldOfView( - camera.FieldOfView * MathF.PI / 180, // Degrees => Radians - (float)bounds.Size.X / bounds.Size.Y, // Aspect Ratio - camera.NearPlane, camera.FarPlane); - - // Set the uniform to the combined transform and projection. - var cameraMatrix = invertedTransform * cameraProjection; - GL.UniformMatrix4(_cameraMatrixUniform, 1, false, in cameraMatrix.Row1.X); - - _renderEntityRule ??= new(universe, new(@" - GlobalTransform, - (Mesh, $mesh), MeshHandle($mesh), - ?(Texture, $tex), ?TextureHandle($tex) - ")); - foreach (var iter in _renderEntityRule) { - var transforms = iter.Field(1); - var meshes = iter.Field(3); - // var texPairs = iter.MaybeField(4); - var textures = iter.MaybeField(5); - - for (var i = 0; i < iter.Count; i++) { - var rTransform = transforms[i]; - var mesh = meshes[i]; - // var hasTexture = (texPairs.Length > 0); - var texture = textures.MaybeGet(i); - - // If entity has Texture, bind it now. - if (texture.HasValue) GL.BindTexture(texture.Value.Target, texture.Value.Handle); - - // Draw the mesh. - GL.UniformMatrix4(_modelMatrixUniform, 1, false, in rTransform.Value.Row1.X); - GL.BindVertexArray(mesh.Handle); - if (!mesh.IsIndexed) GL.DrawArrays(PrimitiveType.Triangles, 0, (uint)mesh.Count); - else unsafe { GL.DrawElements(PrimitiveType.Triangles, (uint)mesh.Count, DrawElementsType.UnsignedShort, null); } - - // If entity has Texture, unbind it after it has been rendered. - if (texture.HasValue) GL.BindTexture(texture.Value.Target, 0); - } - } - }); + [System(typeof(SystemPhase.OnStore))] + public void Render(Universe universe, [Game] Canvas canvas, + in GlobalTransform cameraTransform, in Camera camera, CameraViewport? viewport) + { + var color = viewport?.ClearColor ?? new(0x4B, 0x00, 0x82, 255); + var bounds = viewport?.Viewport ?? new(default, canvas.Size); - window.Handle.SwapBuffers(); + var GL = canvas.GL; + GL.Enable(EnableCap.ScissorTest); + GL.Viewport(bounds); GL.Scissor(bounds.Origin.X, bounds.Origin.Y, (uint)bounds.Size.X, (uint)bounds.Size.Y); + GL.ClearColor(color); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); + GL.Disable(EnableCap.ScissorTest); + + // Create the camera's projection matrix. + var cameraProjection = camera.IsOrthographic + ? Matrix4X4.CreateOrthographic( + bounds.Size.X, -bounds.Size.Y, + camera.NearPlane, camera.FarPlane) + : Matrix4X4.CreatePerspectiveFieldOfView( + camera.FieldOfView * MathF.PI / 180, // Degrees => Radians + (float)bounds.Size.X / bounds.Size.Y, // Aspect Ratio + camera.NearPlane, camera.FarPlane); + + // Get the camera's transform matrix and invert it. + Matrix4X4.Invert(cameraTransform, out var invertedTransform); + // Set the uniform to the combined transform and projection. + var cameraMatrix = invertedTransform * cameraProjection; + GL.UniformMatrix4(_cameraMatrixUniform, 1, false, in cameraMatrix.Row1.X); + + _renderEntityRule ??= new(universe, new(@" + GlobalTransform, + (Mesh, $mesh), MeshHandle($mesh), + ?(Texture, $tex), ?TextureHandle($tex) + ")); + foreach (var iter in _renderEntityRule) { + var transforms = iter.Field(1); + var meshes = iter.Field(3); + // var texPairs = iter.MaybeField(4); + var textures = iter.MaybeField(5); + + for (var i = 0; i < iter.Count; i++) { + var rTransform = transforms[i]; + var mesh = meshes[i]; + // var hasTexture = (texPairs.Length > 0); + var texture = textures.MaybeGet(i); + + // If entity has Texture, bind it now. + if (texture.HasValue) GL.BindTexture(texture.Value.Target, texture.Value.Handle); + + // Draw the mesh. + GL.UniformMatrix4(_modelMatrixUniform, 1, false, in rTransform.Value.Row1.X); + GL.BindVertexArray(mesh.Handle); + if (!mesh.IsIndexed) GL.DrawArrays(PrimitiveType.Triangles, 0, (uint)mesh.Count); + else unsafe { GL.DrawElements(PrimitiveType.Triangles, (uint)mesh.Count, DrawElementsType.UnsignedShort, null); } + + // If entity has Texture, unbind it after it has been rendered. + if (texture.HasValue) GL.BindTexture(texture.Value.Target, 0); + } + } } + [System(typeof(SystemPhase.PostFrame))] + public static void SwapBuffers(GameWindow window) + => window.Handle.SwapBuffers(); + [DebuggerStepThrough] private static void DebugCallback(GLEnum source, GLEnum _type, int id, GLEnum _severity, int length, nint _message, nint userParam)