Split Render system into 3

wip/source-generators
copygirl 2 years ago
parent 8177ea24ef
commit bb0ab53c06
  1. 131
      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<float>(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<float>(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<GlobalTransform>(1);
var meshes = iter.Field<MeshHandle>(3);
// var texPairs = iter.MaybeField<Identifier>(4);
var textures = iter.MaybeField<TextureHandle>(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<float>(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<GlobalTransform>(1);
var meshes = iter.Field<MeshHandle>(3);
// var texPairs = iter.MaybeField<Identifier>(4);
var textures = iter.MaybeField<TextureHandle>(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)

Loading…
Cancel
Save