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
}
public enum Orientation : uint
public enum Orientation : byte
{
West = 0, // + X
East = 1, // - X
@@ -58,10 +58,21 @@
{
Blocks = new Dictionary<Blocks, BlockDefinition>
{
{ 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,

View File

@@ -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<ushort, BlockData> _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<ushort, BlockData>();
_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<FaceData> faces = new List<FaceData>(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;
}
}

View File

@@ -8,11 +8,24 @@ namespace Voxel
{
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;
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();
}

View File

@@ -6,7 +6,7 @@ namespace Voxel
{
private static int _ssbo;
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 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<FaceData> faces)
public static void AddChunkMesh(ChunkMesh chunkMesh)
{
_faces.AddRange(faces);
_needsUpdate = true;
}
public static void ClearFaces()
{
_faces.Clear();
_chunkMeshes.Add(chunkMesh);
}
}
}

View File

@@ -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

View File

@@ -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);

View File

@@ -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)