this repo has no description
at master 166 lines 7.4 kB view raw
1using Kestrel.Framework.World; 2using Silk.NET.OpenGL; 3 4namespace Kestrel.Framework.Client.Graphics.Buffers; 5 6public class ChunkMesh(ClientState clientState, Chunk chunk) : Mesh(clientState) 7{ 8 readonly Chunk chunk = chunk; 9 10 public override unsafe void Generate() 11 { 12 vao = clientState.Window.GL.GenVertexArray(); 13 clientState.Window.GL.BindVertexArray(vao); 14 15 vbo = clientState.Window.GL.GenBuffer(); 16 clientState.Window.GL.BindBuffer(BufferTargetARB.ArrayBuffer, vbo); 17 18 Mesher mesher = new(); 19 Chunk? topChunk = chunk.World.GetChunk(chunk.ChunkX, chunk.ChunkY + 1, chunk.ChunkZ); 20 Chunk? bottomChunk = chunk.World.GetChunk(chunk.ChunkX, chunk.ChunkY - 1, chunk.ChunkZ); 21 Chunk? northChunk = chunk.World.GetChunk(chunk.ChunkX, chunk.ChunkY, chunk.ChunkZ + 1); 22 Chunk? southChunk = chunk.World.GetChunk(chunk.ChunkX, chunk.ChunkY, chunk.ChunkZ - 1); 23 Chunk? westChunk = chunk.World.GetChunk(chunk.ChunkX - 1, chunk.ChunkY, chunk.ChunkZ); 24 Chunk? eastChunk = chunk.World.GetChunk(chunk.ChunkX + 1, chunk.ChunkY, chunk.ChunkZ); 25 26 if (!chunk.IsEmpty) 27 { 28 for (int x = 0; x < chunk.World.ChunkSize; x++) 29 { 30 for (int y = 0; y < chunk.World.ChunkSize; y++) 31 { 32 for (int z = 0; z < chunk.World.ChunkSize; z++) 33 { 34 float wx = chunk.ChunkX * chunk.World.ChunkSize + x; 35 float wy = chunk.ChunkY * chunk.World.ChunkSize + y; 36 float wz = chunk.ChunkZ * chunk.World.ChunkSize + z; 37 38 BlockType? block = chunk.GetBlock(x, y, z); 39 if (block == BlockType.Air || block == null) 40 continue; 41 42 if (y + 1 >= chunk.World.ChunkSize) 43 { 44 if (topChunk != null) 45 { 46 if (topChunk.GetBlock(x, 0, z) == BlockType.Air) 47 mesher.AddUpFace(block.Value, x, y, z); 48 } 49 else 50 { 51 // mesher.AddUpFace(block.Value, x, y, z); 52 } 53 } 54 else if (chunk.GetBlock(x, y + 1, z) == BlockType.Air) 55 { 56 mesher.AddUpFace(block.Value, x, y, z); 57 } 58 59 if (y - 1 < 0) 60 { 61 if (bottomChunk != null) 62 { 63 if (bottomChunk.GetBlock(x, chunk.World.ChunkSize - 1, z) == BlockType.Air) 64 mesher.AddDownFace(block.Value, x, y, z); 65 } 66 else 67 { 68 // mesher.AddDownFace(block.Value, x, y, z); 69 } 70 } 71 else if (chunk.GetBlock(x, y - 1, z) == BlockType.Air) 72 { 73 mesher.AddDownFace(block.Value, x, y, z); 74 } 75 76 if (x + 1 >= chunk.World.ChunkSize) 77 { 78 if (eastChunk != null) 79 { 80 if (eastChunk.GetBlock(0, y, z) == BlockType.Air) 81 mesher.AddEastFace(block.Value, x, y, z); 82 } 83 else 84 { 85 // mesher.AddEastFace(block.Value, x, y, z); 86 } 87 } 88 else if (chunk.GetBlock(x + 1, y, z) == BlockType.Air) 89 { 90 mesher.AddEastFace(block.Value, x, y, z); 91 } 92 93 if (x - 1 < 0) 94 { 95 if (westChunk != null) 96 { 97 if (westChunk.GetBlock(chunk.World.ChunkSize - 1, y, z) == BlockType.Air) 98 mesher.AddWestFace(block.Value, x, y, z); 99 } 100 else 101 { 102 // mesher.AddWestFace(block.Value, x, y, z); 103 } 104 } 105 else if (chunk.GetBlock(x - 1, y, z) == BlockType.Air) 106 { 107 mesher.AddWestFace(block.Value, x, y, z); 108 } 109 110 if (z + 1 >= chunk.World.ChunkSize) 111 { 112 if (northChunk != null) 113 { 114 if (northChunk.GetBlock(x, y, 0) == BlockType.Air) 115 mesher.AddNorthFace(block.Value, x, y, z); 116 } 117 else 118 { 119 // mesher.AddNorthFace(block.Value, x, y, z); 120 } 121 } 122 else if (chunk.GetBlock(x, y, z + 1) == BlockType.Air) 123 { 124 mesher.AddNorthFace(block.Value, x, y, z); 125 } 126 127 if (z - 1 < 0) 128 { 129 if (southChunk != null) 130 { 131 if (southChunk.GetBlock(x, y, chunk.World.ChunkSize - 1) == BlockType.Air) 132 mesher.AddSouthFace(block.Value, x, y, z); 133 } 134 else 135 { 136 // mesher.AddSouthFace(block.Value, x, y, z); 137 } 138 } 139 else if (chunk.GetBlock(x, y, z - 1) == BlockType.Air) 140 { 141 mesher.AddSouthFace(block.Value, x, y, z); 142 } 143 } 144 } 145 } 146 } 147 148 Vertices = mesher.Vertices.ToArray(); 149 150 fixed (float* buf = Vertices) 151 clientState.Window.GL.BufferData(BufferTargetARB.ArrayBuffer, (nuint)(Vertices.Length * sizeof(float)), buf, BufferUsageARB.StaticDraw); 152 153 clientState.Window.GL.EnableVertexAttribArray(0); 154 clientState.Window.GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, 6 * sizeof(float), (void*)0); 155 156 clientState.Window.GL.EnableVertexAttribArray(1); 157 clientState.Window.GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 6 * sizeof(float), (void*)(3 * sizeof(float))); 158 159 clientState.Window.GL.EnableVertexAttribArray(2); 160 clientState.Window.GL.VertexAttribPointer(2, 1, VertexAttribPointerType.Float, false, 6 * sizeof(float), (void*)(5 * sizeof(float))); 161 162 // Clean up 163 clientState.Window.GL.BindVertexArray(0); 164 clientState.Window.GL.BindBuffer(BufferTargetARB.ArrayBuffer, 0); 165 } 166}