diff --git a/src/Immersion/Program.cs b/src/Immersion/Program.cs index ad25244..4d94830 100644 --- a/src/Immersion/Program.cs +++ b/src/Immersion/Program.cs @@ -2,7 +2,6 @@ using System.Diagnostics; using System.Threading; using gaemstone.Bloxel; -using gaemstone.Client; using gaemstone.ECS; using gaemstone.Flecs; using gaemstone.Utility; @@ -43,6 +42,7 @@ universe.Modules.Register(); universe.Modules.Register(); universe.Modules.Register(); +universe.Modules.Register(); universe.Modules.Register(); game.Set(new RawInput()); @@ -55,8 +55,8 @@ universe.New("MainCamera") .Set(new CameraController { MouseSensitivity = 12.0F }) .Build(); -var heartMesh = MeshManager.Load(universe, "/Immersion/Resources/heart.glb"); -var swordMesh = MeshManager.Load(universe, "/Immersion/Resources/sword.glb"); +var heartMesh = universe.New("/Immersion/Resources/heart.glb").Add().Build(); +var swordMesh = universe.New("/Immersion/Resources/sword.glb").Add().Build(); var entities = universe.New("Entities").Build(); var rnd = new Random(); @@ -67,7 +67,7 @@ for (var z = -12; z <= 12; z++) { var (type, mesh) = rnd.Pick(("Heart", heartMesh), ("Sword", swordMesh)); entities.NewChild() .Set((GlobalTransform)(rotation * position)) - .Set(mesh) + .Add(mesh) .Build(); } diff --git a/src/gaemstone.Bloxel/Client/Systems/ChunkMeshGenerator.cs b/src/gaemstone.Bloxel/Client/Systems/ChunkMeshGenerator.cs index b6b5bae..0f075c9 100644 --- a/src/gaemstone.Bloxel/Client/Systems/ChunkMeshGenerator.cs +++ b/src/gaemstone.Bloxel/Client/Systems/ChunkMeshGenerator.cs @@ -1,10 +1,11 @@ using System; -using gaemstone.Client; +using gaemstone.Client.Systems; using gaemstone.ECS; using Silk.NET.Maths; using static gaemstone.Bloxel.Components.CoreComponents; -using static gaemstone.Bloxel.Systems.BasicWorldGenerator; using static gaemstone.Client.Components.RenderingComponents; +using static gaemstone.Client.Components.ResourceComponents; +using static gaemstone.Client.Systems.Windowing; namespace gaemstone.Bloxel.Client.Systems; @@ -31,13 +32,12 @@ public class ChunkMeshGenerator private Vector3D[] _normals = new Vector3D[StartingCapacity]; private Vector2D[] _uvs = new Vector2D[StartingCapacity]; - [System] + [System(Expression = "[in] Chunk, ChunkStoreBlocks, HasBasicWorldGeneration, !(Mesh, *)")] public void GenerateChunkMeshes(Universe universe, EntityRef entity, - in Chunk chunk, ChunkStoreBlocks blocks, - HasBasicWorldGeneration _1, [Not] MeshHandle _2) + in Chunk chunk, ChunkStoreBlocks blocks) { - var maybeMesh = Generate(universe, chunk.Position, blocks); - if (maybeMesh is MeshHandle mesh) entity.Set(mesh); + if (Generate(universe, chunk.Position, blocks) is MeshHandle handle) + entity.Add(entity.NewChild("Mesh").Set(handle).Build()); else entity.Delete(); } @@ -97,8 +97,10 @@ public class ChunkMeshGenerator } } + // TODO: Should dynamically generating meshes require getting GL this way? + var GL = universe.LookupOrThrow().Get().GL; return (indexCount > 0) - ? MeshManager.Create(universe, + ? MeshManager.Create(GL, _indices.AsSpan(0, indexCount), _vertices.AsSpan(0, vertexCount), _normals.AsSpan(0, vertexCount), _uvs.AsSpan(0, vertexCount)) : null; diff --git a/src/gaemstone.Client/Systems/MeshManager.cs b/src/gaemstone.Client/Systems/MeshManager.cs index 605c371..9f845ae 100644 --- a/src/gaemstone.Client/Systems/MeshManager.cs +++ b/src/gaemstone.Client/Systems/MeshManager.cs @@ -1,31 +1,42 @@ using System; +using System.IO; using gaemstone.ECS; using Silk.NET.Maths; using Silk.NET.OpenGL; using static gaemstone.Client.Components.RenderingComponents; +using static gaemstone.Client.Components.ResourceComponents; using static gaemstone.Client.Systems.Windowing; using ModelRoot = SharpGLTF.Schema2.ModelRoot; -namespace gaemstone.Client; +namespace gaemstone.Client.Systems; -public static class MeshManager +[Module] +public class MeshManager { private const uint PositionAttribIndex = 0; private const uint NormalAttribIndex = 1; private const uint UvAttribIndex = 2; - public static MeshHandle Load(Universe universe, EntityPath path) + [System] + public static void LoadMeshWhenDefined( + [Game] Canvas canvas, EntityRef entity, + Mesh _1, [Not] MeshHandle _2) { - ModelRoot root; - using (var stream = Resources.GetStream(path)) - root = ModelRoot.ReadGLB(stream, new()); + var path = entity.GetFullPath(); + using var stream = Resources.GetStream(path); + var handle = CreateFromStream(canvas.GL, stream); + entity.Set(handle); + } + + private static MeshHandle CreateFromStream(GL GL, Stream stream) + { + var root = ModelRoot.ReadGLB(stream); var primitive = root.LogicalMeshes[0].Primitives[0]; var indices = primitive.IndexAccessor; var vertices = primitive.VertexAccessors["POSITION"]; var normals = primitive.VertexAccessors["NORMAL"]; - var GL = universe.LookupOrThrow().Get().GL; var vao = GL.GenVertexArray(); GL.BindVertexArray(vao); @@ -48,11 +59,10 @@ public static class MeshManager return new(vao, numVertices); } - public static MeshHandle Create(Universe universe, + public static MeshHandle Create(GL GL, ReadOnlySpan indices, ReadOnlySpan> vertices, ReadOnlySpan> normals, ReadOnlySpan> uvs) { - var GL = universe.LookupOrThrow().Get().GL; var vao = GL.GenVertexArray(); GL.BindVertexArray(vao); @@ -77,10 +87,9 @@ public static class MeshManager return new(vao, indices.Length); } - public static MeshHandle Create(Universe universe, ReadOnlySpan> vertices, + public static MeshHandle Create(GL GL, ReadOnlySpan> vertices, ReadOnlySpan> normals, ReadOnlySpan> uvs) { - var GL = universe.LookupOrThrow().Get().GL; var vao = GL.GenVertexArray(); GL.BindVertexArray(vao); diff --git a/src/gaemstone.Client/Systems/Renderer.cs b/src/gaemstone.Client/Systems/Renderer.cs index 87611ea..9571a5e 100644 --- a/src/gaemstone.Client/Systems/Renderer.cs +++ b/src/gaemstone.Client/Systems/Renderer.cs @@ -87,12 +87,16 @@ public class Renderer var cameraMatrix = invertedTransform * cameraProjection; GL.UniformMatrix4(_cameraMatrixUniform, 1, false, in cameraMatrix.Row1.X); - _renderEntityRule ??= new(universe, new("GlobalTransform, MeshHandle, ?(Texture, $tex), ?TextureHandle($tex)")); + _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(2); - // var texPairs = iter.MaybeField(3); - var textures = iter.MaybeField(4); + 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]; diff --git a/src/gaemstone/gaemstone.csproj b/src/gaemstone/gaemstone.csproj index af362dc..92bd2a3 100644 --- a/src/gaemstone/gaemstone.csproj +++ b/src/gaemstone/gaemstone.csproj @@ -1,7 +1,6 @@ - preview net6.0 disable enable