chunk meshes

This commit is contained in:
maxwes08
2025-09-03 15:08:21 +02:00
parent 94ebc4ace4
commit 3678eaa5f8
8 changed files with 69 additions and 41 deletions

View File

@@ -10,7 +10,7 @@
Bedrock Bedrock
} }
public enum Orientation : uint public enum Orientation : byte
{ {
West = 0, // + X West = 0, // + X
East = 1, // - X East = 1, // - X
@@ -58,10 +58,21 @@
{ {
Blocks = new Dictionary<Blocks, BlockDefinition> Blocks = new Dictionary<Blocks, BlockDefinition>
{ {
{ Voxel.Blocks.Stone, new BlockDefinition(Voxel.Blocks.Stone, Voxel.Textures.Stone) }, {Voxel.Blocks.Stone, new BlockDefinition(
{ Voxel.Blocks.Dirt, new BlockDefinition(Voxel.Blocks.Dirt, Voxel.Textures.Dirt) }, Voxel.Blocks.Stone, Textures.Stone
{ Voxel.Blocks.OakPlanks, new BlockDefinition(Voxel.Blocks.OakPlanks, Voxel.Textures.OakPlanks) }, )},
{ Voxel.Blocks.Bedrock, new BlockDefinition(Voxel.Blocks.Bedrock, Voxel.Textures.Bedrock) },
{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, new BlockDefinition(
Voxel.Blocks.Grass, Voxel.Blocks.Grass,

View File

@@ -4,16 +4,16 @@
{ {
public static int Size = 16; public static int Size = 16;
public static int Height = 256; public static int Height = 256;
public readonly int PositionX; public readonly int X;
public readonly int PositionY; public readonly int Y;
private Dictionary<ushort, BlockData> _blockData; private Dictionary<ushort, BlockData> _blockData;
private Blocks[] _blocks; private Blocks[] _blocks;
public Chunk(int positionX, int positionY) public Chunk(int x, int y)
{ {
PositionX = positionX; X = x;
PositionY = positionY; Y = y;
_blockData = new Dictionary<ushort, BlockData>(); _blockData = new Dictionary<ushort, BlockData>();
_blocks = new Blocks[Size * Size * Height]; _blocks = new Blocks[Size * Size * Height];
@@ -84,7 +84,8 @@
public ChunkMesh GetChunkMesh() public ChunkMesh GetChunkMesh()
{ {
ChunkMesh chunkMesh = new ChunkMesh(Size * Size * Height / 2); ChunkMesh chunkMesh = new ChunkMesh(X, Y);
List<FaceData> faces = new List<FaceData>(Size * Size * Height / 2);
// offsets table // offsets table
@@ -121,12 +122,14 @@
faceData.Y = (byte)y; faceData.Y = (byte)y;
faceData.Z = (byte)z; faceData.Z = (byte)z;
chunkMesh.Faces.Add(faceData); faces.Add(faceData);
} }
} }
} }
} }
chunkMesh.SetFaces(faces);
return chunkMesh; return chunkMesh;
} }
} }

View File

@@ -8,11 +8,24 @@ namespace Voxel
{ {
public class ChunkMesh public class ChunkMesh
{ {
public List<FaceData> 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<FaceData>(maxBlocks * 6); PackedData = new byte[0];
X = x;
Y = y;
}
public void SetFaces(List<FaceData> faces)
{
Length = faces.Count;
PackedData = faces.SelectMany(f => f.Pack()).ToArray();
NeedsUpdate = true;
} }
} }
} }

View File

@@ -15,12 +15,14 @@ internal class Program
window.Player = player; 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.AddChunkMesh(chunk0.GetChunkMesh());
Renderer.AddFaces(chunkMesh.Faces); Renderer.AddChunkMesh(chunk1.GetChunkMesh());
window.Run(); window.Run();
} }

View File

@@ -6,7 +6,7 @@ namespace Voxel
{ {
private static int _ssbo; private static int _ssbo;
private static int _vao; private static int _vao;
private static List<FaceData> _faces = new List<FaceData>(); private static List<ChunkMesh> _chunkMeshes = new List<ChunkMesh>();
private static Shader _shader; private static Shader _shader;
private static Texture _texture; private static Texture _texture;
private static bool _needsUpdate = false; private static bool _needsUpdate = false;
@@ -35,31 +35,32 @@ namespace Voxel
GL.BindVertexArray(_vao); GL.BindVertexArray(_vao);
GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _ssbo); GL.BindBuffer(BufferTarget.ShaderStorageBuffer, _ssbo);
if (_needsUpdate) //if (_needsUpdate)
{ //{
_needsUpdate = false; // _needsUpdate = false;
byte[] data = _faces.SelectMany(f => f.Pack()).ToArray(); // byte[] data = _faces.SelectMany(f => f.Pack()).ToArray();
GL.BufferData(BufferTarget.ShaderStorageBuffer, data.Length, data, BufferUsageHint.StaticRead); // GL.BufferData(BufferTarget.ShaderStorageBuffer, data.Length, data, BufferUsageHint.StaticRead);
} //}
_shader.Use(); _shader.Use();
_shader.SetMatrix4("view", Camera.view); _shader.SetMatrix4("view", Camera.view);
_shader.SetMatrix4("projection", Camera.projection); _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"); //Console.WriteLine("Rendered " + _faces.Count.ToString() + " faces");
} }
public static void AddFaces(List<FaceData> faces) public static void AddChunkMesh(ChunkMesh chunkMesh)
{ {
_faces.AddRange(faces); _chunkMeshes.Add(chunkMesh);
_needsUpdate = true;
}
public static void ClearFaces()
{
_faces.Clear();
} }
} }
} }

View File

@@ -15,6 +15,8 @@ layout(std430, binding = 0) buffer FaceBuffer {
uniform mat4 view; uniform mat4 view;
uniform mat4 projection; uniform mat4 projection;
uniform int chunkX;
uniform int chunkY;
out vec2 fragUV; out vec2 fragUV;
out float lighting; out float lighting;
@@ -92,7 +94,7 @@ void main()
uint texture = u1 & 0xFFu; uint texture = u1 & 0xFFu;
uint lightLevel = (u1 >> 8) & 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); vec4 worldPos = vec4(basePos + offsets[facing][vertIndex], 1.0);
float light = float(lightLevel) / 255.0; // use later for caves and stuff float light = float(lightLevel) / 255.0; // use later for caves and stuff

View File

@@ -70,7 +70,6 @@ namespace Voxel
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
CursorState = CursorState.Grabbed; CursorState = CursorState.Grabbed;
Cursor = MouseCursor.Default;
VSync = VSyncMode.On; VSync = VSyncMode.On;
Camera.UpdateProjection(Width, Height); Camera.UpdateProjection(Width, Height);

View File

@@ -22,7 +22,7 @@ namespace Voxel
// Add a chunk // Add a chunk
public void AddChunk(Chunk chunk) public void AddChunk(Chunk chunk)
{ {
_chunks[(chunk.PositionX, chunk.PositionY)] = chunk; _chunks[(chunk.X, chunk.Y)] = chunk;
} }
// Remove a chunk // Remove a chunk
@@ -63,9 +63,6 @@ namespace Voxel
int localZ = worldZ % Chunk.Size; int localZ = worldZ % Chunk.Size;
chunk.SetBlock(localX, worldY, localZ, block); 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) public (Blocks block, int x, int y, int z) Raycast(float length)