From 3678eaa5f8ed4b4ab9c85e78ef660ec33350a517 Mon Sep 17 00:00:00 2001 From: maxwes08 Date: Wed, 3 Sep 2025 15:08:21 +0200 Subject: [PATCH] chunk meshes --- Blocks.cs | 21 ++++++++++++++++----- Chunk.cs | 17 ++++++++++------- ChunkMesh.cs | 19 ++++++++++++++++--- Program.cs | 10 ++++++---- Renderer.cs | 33 +++++++++++++++++---------------- Shaders/shader.vert | 4 +++- Window.cs | 1 - World.cs | 5 +---- 8 files changed, 69 insertions(+), 41 deletions(-) diff --git a/Blocks.cs b/Blocks.cs index 75d7f92..1e1c195 100644 --- a/Blocks.cs +++ b/Blocks.cs @@ -10,7 +10,7 @@ Bedrock } - public enum Orientation : uint + public enum Orientation : byte { West = 0, // + X East = 1, // - X @@ -58,10 +58,21 @@ { Blocks = new Dictionary { - { Voxel.Blocks.Stone, new BlockDefinition(Voxel.Blocks.Stone, Voxel.Textures.Stone) }, - { Voxel.Blocks.Dirt, new BlockDefinition(Voxel.Blocks.Dirt, Voxel.Textures.Dirt) }, - { Voxel.Blocks.OakPlanks, new BlockDefinition(Voxel.Blocks.OakPlanks, Voxel.Textures.OakPlanks) }, - { Voxel.Blocks.Bedrock, new BlockDefinition(Voxel.Blocks.Bedrock, Voxel.Textures.Bedrock) }, + {Voxel.Blocks.Stone, new BlockDefinition( + Voxel.Blocks.Stone, Textures.Stone + )}, + + {Voxel.Blocks.Dirt, new BlockDefinition( + Voxel.Blocks.Dirt, Textures.Dirt + )}, + + {Voxel.Blocks.OakPlanks, new BlockDefinition( + Voxel.Blocks.OakPlanks, Textures.OakPlanks + )}, + + {Voxel.Blocks.Bedrock, new BlockDefinition( + Voxel.Blocks.Bedrock, Textures.Bedrock + )}, { Voxel.Blocks.Grass, new BlockDefinition( Voxel.Blocks.Grass, diff --git a/Chunk.cs b/Chunk.cs index 011f28c..c6fdb53 100644 --- a/Chunk.cs +++ b/Chunk.cs @@ -4,16 +4,16 @@ { public static int Size = 16; public static int Height = 256; - public readonly int PositionX; - public readonly int PositionY; + public readonly int X; + public readonly int Y; private Dictionary _blockData; private Blocks[] _blocks; - public Chunk(int positionX, int positionY) + public Chunk(int x, int y) { - PositionX = positionX; - PositionY = positionY; + X = x; + Y = y; _blockData = new Dictionary(); _blocks = new Blocks[Size * Size * Height]; @@ -84,7 +84,8 @@ public ChunkMesh GetChunkMesh() { - ChunkMesh chunkMesh = new ChunkMesh(Size * Size * Height / 2); + ChunkMesh chunkMesh = new ChunkMesh(X, Y); + List faces = new List(Size * Size * Height / 2); // offsets table @@ -121,12 +122,14 @@ faceData.Y = (byte)y; faceData.Z = (byte)z; - chunkMesh.Faces.Add(faceData); + faces.Add(faceData); } } } } + chunkMesh.SetFaces(faces); + return chunkMesh; } } diff --git a/ChunkMesh.cs b/ChunkMesh.cs index bf15bb6..d522a38 100644 --- a/ChunkMesh.cs +++ b/ChunkMesh.cs @@ -8,11 +8,24 @@ namespace Voxel { public class ChunkMesh { - public List Faces; + public int X; + public int Y; + public byte[] PackedData; + public bool NeedsUpdate = true; + public int Length = 0; - public ChunkMesh(int maxBlocks) + public ChunkMesh(int x, int y) { - Faces = new List(maxBlocks * 6); + PackedData = new byte[0]; + X = x; + Y = y; + } + + public void SetFaces(List faces) + { + Length = faces.Count; + PackedData = faces.SelectMany(f => f.Pack()).ToArray(); + NeedsUpdate = true; } } } diff --git a/Program.cs b/Program.cs index a4e4e5c..01c6a7d 100644 --- a/Program.cs +++ b/Program.cs @@ -15,12 +15,14 @@ internal class Program window.Player = player; - Chunk chunk = new Chunk(0, 0); + Chunk chunk0 = new Chunk(0, 0); + Chunk chunk1 = new Chunk(0, 1); - world.AddChunk(chunk); + world.AddChunk(chunk0); + world.AddChunk(chunk1); - ChunkMesh chunkMesh = chunk.GetChunkMesh(); - Renderer.AddFaces(chunkMesh.Faces); + Renderer.AddChunkMesh(chunk0.GetChunkMesh()); + Renderer.AddChunkMesh(chunk1.GetChunkMesh()); window.Run(); } diff --git a/Renderer.cs b/Renderer.cs index 098bf06..faac26d 100644 --- a/Renderer.cs +++ b/Renderer.cs @@ -6,7 +6,7 @@ namespace Voxel { private static int _ssbo; private static int _vao; - private static List _faces = new List(); + private static List _chunkMeshes = new List(); private static Shader _shader; private static Texture _texture; private static bool _needsUpdate = false; @@ -35,31 +35,32 @@ namespace Voxel GL.BindVertexArray(_vao); GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _ssbo); - if (_needsUpdate) - { - _needsUpdate = false; - byte[] data = _faces.SelectMany(f => f.Pack()).ToArray(); - GL.BufferData(BufferTarget.ShaderStorageBuffer, data.Length, data, BufferUsageHint.StaticRead); - } + //if (_needsUpdate) + //{ + // _needsUpdate = false; + // byte[] data = _faces.SelectMany(f => f.Pack()).ToArray(); + // GL.BufferData(BufferTarget.ShaderStorageBuffer, data.Length, data, BufferUsageHint.StaticRead); + //} _shader.Use(); _shader.SetMatrix4("view", Camera.view); _shader.SetMatrix4("projection", Camera.projection); - GL.DrawArrays(PrimitiveType.Triangles, 0, _faces.Count * 6); + for (int i = 0; i < _chunkMeshes.Count; i++) + { + ChunkMesh chunkMesh = _chunkMeshes[i]; + _shader.SetInt("chunkX", chunkMesh.X); + _shader.SetInt("chunkY", chunkMesh.Y); + GL.BufferData(BufferTarget.ShaderStorageBuffer, chunkMesh.PackedData.Length, chunkMesh.PackedData, BufferUsageHint.StaticRead); + GL.DrawArrays(PrimitiveType.Triangles, 0, chunkMesh.Length * 6); + } //Console.WriteLine("Rendered " + _faces.Count.ToString() + " faces"); } - public static void AddFaces(List faces) + public static void AddChunkMesh(ChunkMesh chunkMesh) { - _faces.AddRange(faces); - _needsUpdate = true; - } - - public static void ClearFaces() - { - _faces.Clear(); + _chunkMeshes.Add(chunkMesh); } } } diff --git a/Shaders/shader.vert b/Shaders/shader.vert index 6a3d0c4..83d3160 100644 --- a/Shaders/shader.vert +++ b/Shaders/shader.vert @@ -15,6 +15,8 @@ layout(std430, binding = 0) buffer FaceBuffer { uniform mat4 view; uniform mat4 projection; +uniform int chunkX; +uniform int chunkY; out vec2 fragUV; out float lighting; @@ -92,7 +94,7 @@ void main() uint texture = u1 & 0xFFu; uint lightLevel = (u1 >> 8) & 0xFFu; - vec3 basePos = vec3(x, y, z); + vec3 basePos = vec3(x + chunkX * 16, y, z + chunkY * 16); vec4 worldPos = vec4(basePos + offsets[facing][vertIndex], 1.0); float light = float(lightLevel) / 255.0; // use later for caves and stuff diff --git a/Window.cs b/Window.cs index 5a7ac56..dc3b408 100644 --- a/Window.cs +++ b/Window.cs @@ -70,7 +70,6 @@ namespace Voxel GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); CursorState = CursorState.Grabbed; - Cursor = MouseCursor.Default; VSync = VSyncMode.On; Camera.UpdateProjection(Width, Height); diff --git a/World.cs b/World.cs index c7008a2..fc7dcb9 100644 --- a/World.cs +++ b/World.cs @@ -22,7 +22,7 @@ namespace Voxel // Add a chunk public void AddChunk(Chunk chunk) { - _chunks[(chunk.PositionX, chunk.PositionY)] = chunk; + _chunks[(chunk.X, chunk.Y)] = chunk; } // Remove a chunk @@ -63,9 +63,6 @@ namespace Voxel int localZ = worldZ % Chunk.Size; chunk.SetBlock(localX, worldY, localZ, block); - Renderer.ClearFaces(); - ChunkMesh chunkMesh = chunk.GetChunkMesh(); - Renderer.AddFaces(chunkMesh.Faces); } public (Blocks block, int x, int y, int z) Raycast(float length)