fixed rendering

This commit is contained in:
2025-09-09 19:43:27 +02:00
parent ce456b6b26
commit 50f9d4c0c8
5 changed files with 66 additions and 21 deletions

View File

@@ -25,11 +25,12 @@
public void SetBlock(int x, int y, int z, Blocks block) public void SetBlock(int x, int y, int z, Blocks block)
{ {
Console.WriteLine(x.ToString() + ", " + y.ToString());
int i = GetBlockIndex(x, y, z); int i = GetBlockIndex(x, y, z);
if (i == -1) return; if (i == -1) return;
_blocks[i] = block; _blocks[i] = block;
UpdateChunkMesh(); UpdateChunkMesh();
Renderer.MarkBuffersDirty();
} }
public void SetBlockIndex(int i, Blocks block) public void SetBlockIndex(int i, Blocks block)

View File

@@ -1,6 +1,7 @@
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -13,7 +14,7 @@ namespace Voxel
public int Y; public int Y;
private byte[] _packedData; private byte[] _packedData;
public bool NeedsUpdate = false; public bool NeedsUpdate = false;
public int Length = 0; public int Size = 0;
private List<FaceData> _faces; private List<FaceData> _faces;
public ChunkMesh(int x, int y) public ChunkMesh(int x, int y)
@@ -25,7 +26,7 @@ namespace Voxel
public void SetFaces(List<FaceData> faces) public void SetFaces(List<FaceData> faces)
{ {
Length = faces.Count; Size = faces.Count;
_faces = faces; _faces = faces;
NeedsUpdate = true; NeedsUpdate = true;
} }
@@ -35,7 +36,6 @@ namespace Voxel
if (NeedsUpdate) if (NeedsUpdate)
{ {
_packedData = _faces.SelectMany(f => f.Pack()).ToArray(); _packedData = _faces.SelectMany(f => f.Pack()).ToArray();
NeedsUpdate = false;
} }
return _packedData; return _packedData;

View File

@@ -20,8 +20,9 @@ namespace Voxel
public void BreakBlock() 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; if (!success) return;
_world.SetBlock(x, y, z, Blocks.Air); _world.SetBlock(x, y, z, Blocks.Air);
} }

View File

@@ -1,4 +1,5 @@
using OpenTK.Graphics.OpenGL4; using OpenTK.Graphics.OpenGL4;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace Voxel namespace Voxel
{ {
@@ -6,10 +7,13 @@ namespace Voxel
{ {
private static int _ssbo; private static int _ssbo;
private static int _vao; private static int _vao;
private static bool _buffersDirty;
private static Dictionary<(int, int), int> _chunkBufferSizes = new Dictionary<(int, int), int>();
private static List<ChunkMesh> _chunkMeshes = new List<ChunkMesh>(); private static List<ChunkMesh> _chunkMeshes = new List<ChunkMesh>();
private static Shader _shader; private static Shader _shader;
private static Texture _texture; private static readonly Texture _texture;
private static World _world; private static World? _world;
static Renderer() static Renderer()
{ {
@@ -27,6 +31,8 @@ namespace Voxel
GL.BindVertexArray(_vao); GL.BindVertexArray(_vao);
GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _ssbo); GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _ssbo);
GL.BufferData(BufferTarget.ShaderStorageBuffer, 1024 * 1024 * 2, IntPtr.Zero, BufferUsageHint.DynamicDraw);
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, _ssbo); GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, _ssbo);
} }
@@ -39,9 +45,35 @@ namespace Voxel
_shader.SetMatrix4("view", Camera.view); _shader.SetMatrix4("view", Camera.view);
_shader.SetMatrix4("projection", Camera.projection); _shader.SetMatrix4("projection", Camera.projection);
if (_buffersDirty)
{
UpdateAllChunksBuffer();
_buffersDirty = false;
}
RenderWorld(); 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() private static void RenderWorld()
{ {
if (_world == null) return; if (_world == null) return;
@@ -49,17 +81,28 @@ namespace Voxel
foreach (Chunk chunk in _world.GetAllChunks()) foreach (Chunk chunk in _world.GetAllChunks())
{ {
ChunkMesh chunkMesh = chunk.GetChunkMesh(); 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("chunkX", chunk.X);
_shader.SetInt("chunkY", chunk.Y); _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) public static void SetWorld(World world)
{ {
_world = world; _world = world;
_buffersDirty = true;
}
public static void MarkBuffersDirty()
{
_buffersDirty = true;
} }
} }
} }