From 50f9d4c0c86fdbeff02aa4ecdbf1a54608e98117 Mon Sep 17 00:00:00 2001 From: Max Westerlund Date: Tue, 9 Sep 2025 19:43:27 +0200 Subject: [PATCH] fixed rendering --- Chunk.cs | 3 ++- ChunkMesh.cs | 6 ++--- Player.cs | 3 ++- Renderer.cs | 53 ++++++++++++++++++++++++++++++++++++++++----- Shaders/shader.vert | 22 +++++++++---------- 5 files changed, 66 insertions(+), 21 deletions(-) diff --git a/Chunk.cs b/Chunk.cs index 330d5e1..33c58c0 100644 --- a/Chunk.cs +++ b/Chunk.cs @@ -25,11 +25,12 @@ public void SetBlock(int x, int y, int z, Blocks block) { - Console.WriteLine(x.ToString() + ", " + y.ToString()); int i = GetBlockIndex(x, y, z); if (i == -1) return; _blocks[i] = block; UpdateChunkMesh(); + + Renderer.MarkBuffersDirty(); } public void SetBlockIndex(int i, Blocks block) diff --git a/ChunkMesh.cs b/ChunkMesh.cs index 560657a..f92e35f 100644 --- a/ChunkMesh.cs +++ b/ChunkMesh.cs @@ -1,6 +1,7 @@ using OpenTK.Graphics.OpenGL4; using System; using System.Collections.Generic; +using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -13,7 +14,7 @@ namespace Voxel public int Y; private byte[] _packedData; public bool NeedsUpdate = false; - public int Length = 0; + public int Size = 0; private List _faces; public ChunkMesh(int x, int y) @@ -25,7 +26,7 @@ namespace Voxel public void SetFaces(List faces) { - Length = faces.Count; + Size = faces.Count; _faces = faces; NeedsUpdate = true; } @@ -35,7 +36,6 @@ namespace Voxel if (NeedsUpdate) { _packedData = _faces.SelectMany(f => f.Pack()).ToArray(); - NeedsUpdate = false; } return _packedData; diff --git a/Player.cs b/Player.cs index e7b6fbc..d64f9a5 100644 --- a/Player.cs +++ b/Player.cs @@ -20,8 +20,9 @@ namespace Voxel public void BreakBlock() { - var (success, hit, x, y, z) = _world.Raycast(Camera.Position, Camera.Front * 10, 100); + var (success, hit, x, y, z) = _world.Raycast(Camera.Position, Camera.Front.Normalized(), 10); if (!success) return; + _world.SetBlock(x, y, z, Blocks.Air); } diff --git a/Renderer.cs b/Renderer.cs index a76f19e..0033bc3 100644 --- a/Renderer.cs +++ b/Renderer.cs @@ -1,4 +1,5 @@ using OpenTK.Graphics.OpenGL4; +using static System.Runtime.InteropServices.JavaScript.JSType; namespace Voxel { @@ -6,10 +7,13 @@ namespace Voxel { private static int _ssbo; private static int _vao; + private static bool _buffersDirty; + + private static Dictionary<(int, int), int> _chunkBufferSizes = new Dictionary<(int, int), int>(); private static List _chunkMeshes = new List(); private static Shader _shader; - private static Texture _texture; - private static World _world; + private static readonly Texture _texture; + private static World? _world; static Renderer() { @@ -27,6 +31,8 @@ namespace Voxel GL.BindVertexArray(_vao); GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _ssbo); + + GL.BufferData(BufferTarget.ShaderStorageBuffer, 1024 * 1024 * 2, IntPtr.Zero, BufferUsageHint.DynamicDraw); GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, _ssbo); } @@ -39,9 +45,35 @@ namespace Voxel _shader.SetMatrix4("view", Camera.view); _shader.SetMatrix4("projection", Camera.projection); + if (_buffersDirty) + { + UpdateAllChunksBuffer(); + _buffersDirty = false; + } + RenderWorld(); } + private static void UpdateAllChunksBuffer() + { + if (_world == null) return; + + int offset = 0; + foreach (Chunk chunk in _world.GetAllChunks()) + { + ChunkMesh chunkMesh = chunk.GetChunkMesh(); + + if (chunkMesh.NeedsUpdate) + { + byte[] data = chunkMesh.GetPackedData(); + GL.BufferSubData(BufferTarget.ShaderStorageBuffer, (IntPtr)offset * 8, chunkMesh.Size * 8, data); + } + + _chunkBufferSizes[(chunk.X, chunk.Y)] = offset; + offset += chunkMesh.Size * 8; + } + } + private static void RenderWorld() { if (_world == null) return; @@ -49,17 +81,28 @@ namespace Voxel foreach (Chunk chunk in _world.GetAllChunks()) { ChunkMesh chunkMesh = chunk.GetChunkMesh(); - byte[] data = chunkMesh.GetPackedData(); + + if (chunkMesh.Size == 0) continue; + + if (!_chunkBufferSizes.TryGetValue((chunk.X, chunk.Y), out int offset)) continue; + _shader.SetInt("chunkX", chunk.X); _shader.SetInt("chunkY", chunk.Y); - GL.BufferData(BufferTarget.ShaderStorageBuffer, chunkMesh.Length * 8, data, BufferUsageHint.StaticRead); - GL.DrawArrays(PrimitiveType.Triangles, 0, chunkMesh.Length * 6); + + //GL.MemoryBarrier(MemoryBarrierFlags.ShaderStorageBarrierBit); + GL.DrawArrays(PrimitiveType.Triangles, offset * 6, chunkMesh.Size * 6); } } public static void SetWorld(World world) { _world = world; + _buffersDirty = true; + } + + public static void MarkBuffersDirty() + { + _buffersDirty = true; } } } diff --git a/Shaders/shader.vert b/Shaders/shader.vert index 83d3160..31b9f16 100644 --- a/Shaders/shader.vert +++ b/Shaders/shader.vert @@ -1,17 +1,17 @@ #version 430 core -struct FaceData { - uint x; - uint y; - uint z; - uint facing; // 0=+X,1=-X,2=+Y,3=-Y,4=+Z,5=-Z - uint texture; - uint lightLevel; -}; + struct FaceData { + uint x; + uint y; + uint z; + uint facing; // 0=+X,1=-X,2=+Y,3=-Y,4=+Z,5=-Z + uint texture; + uint lightLevel; + }; -layout(std430, binding = 0) buffer FaceBuffer { - uint faces[]; -}; + layout(std430, binding = 0) buffer FaceBuffer { + uint faces[]; + }; uniform mat4 view; uniform mat4 projection;