added chunk split meshing

Commit 493d4080cf84 · mgecumshooter · 2026-10-22 13:12 +0300

Changeset
493d4080cf84555bd2e990f1c99276237948268d

View source at this commit

Comments

No comments yet.

Log in to comment

Diff

diff --git a/src/chunk/mod.rs b/src/chunk/mod.rs
--- a/src/chunk/mod.rs
+++ b/src/chunk/mod.rs
@@ -10,13 +10,13 @@
 use crate::voxel::*;
 
 // constants
-pub const CHUNK_SIZE: usize = 16;
+pub const CHUNK_SIZE: usize = 32;
 
 pub struct Chunk {
     pub chunk_pos: Vector3,
     pub voxels: [Voxel; CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE],
     pub dirty: bool,
-    pub mesh: Option<Mesh>,
+    pub meshes: Vec<Mesh>,
 } // pending: add events stack
 
 impl Chunk {
@@ -26,7 +26,7 @@
             chunk_pos: pos,
             voxels: [Voxel::from_kind(VoxelKind::Air); CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE],
             dirty: true,
-            mesh: None,
+            meshes: Vec::new(),
         };
         for x in 0..CHUNK_SIZE {
             for z in 0..CHUNK_SIZE {
@@ -113,6 +113,64 @@
 
 	cos_angle.acos() <= half_fov + angular_margin
     }
+
+    fn flush_mesh_buffer(&mut self,
+			 vertices: &mut Vec<Vector3>,
+			 normals: &mut Vec<Vector3>,
+			 indices: &mut Vec<u16>,
+			 colors: &mut Vec<u8>,
+    ) {
+        let vertex_count = vertices.len();
+        let index_count = indices.len();
+
+        if vertex_count == 0 {
+            return;
+        }
+
+        unsafe {
+            let v_size = vertex_count * std::mem::size_of::<Vector3>();
+            let i_size = index_count * std::mem::size_of::<u16>();
+            let n_size = vertex_count * std::mem::size_of::<Vector3>();
+	    let c_size = colors.len();
+
+            let v_ptr = rlb::ffi::MemAlloc(v_size as u32) as *mut Vector3;
+            let i_ptr = rlb::ffi::MemAlloc(i_size as u32) as *mut u16;
+            let n_ptr = rlb::ffi::MemAlloc(n_size as u32) as *mut Vector3;
+	    let c_ptr = rlb::ffi::MemAlloc(c_size as u32) as *mut u8;
+
+            std::ptr::copy_nonoverlapping(vertices.as_ptr(), v_ptr, vertex_count);
+            std::ptr::copy_nonoverlapping(indices.as_ptr(), i_ptr, index_count);
+            std::ptr::copy_nonoverlapping(normals.as_ptr(), n_ptr, vertex_count);
+	    std::ptr::copy_nonoverlapping(colors.as_ptr(), c_ptr, colors.len());
+
+            let raw_mesh = rlb::ffi::Mesh {
+                vertexCount: vertex_count as i32,
+                triangleCount: (index_count / 3) as i32,
+                vertices: v_ptr as *mut std::ffi::c_float,
+                indices: i_ptr,
+                normals: n_ptr as *mut std::ffi::c_float,
+                texcoords: std::ptr::null_mut(),
+                texcoords2: std::ptr::null_mut(),
+                colors: c_ptr,
+                tangents: std::ptr::null_mut(),
+                animVertices: std::ptr::null_mut(),
+                animNormals: std::ptr::null_mut(),
+                boneCount: 0,
+                boneIndices: std::ptr::null_mut(),
+                boneWeights: std::ptr::null_mut(),
+                vaoId: 0,
+                vboId: std::ptr::null_mut(),
+            };
+
+            let mut mesh = Mesh::from_raw(raw_mesh);
+            mesh.upload(false);
+            self.meshes.push(mesh);
+        }
+	vertices.clear();
+	indices.clear();
+	normals.clear();
+	colors.clear();
+    }
     
     pub fn generate_mesh(&mut self) {
         let mut vertices: Vec<Vector3> = Vec::new();
@@ -120,7 +178,10 @@
         let mut indices: Vec<u16> = Vec::new();
 	let mut colors: Vec<u8> = Vec::new();
 
+	const MAX_VERTICES_PER_MESH: i32 = 65536 - 24;
+
         let mut vertex_offset: i32 = 0;
+	
         for x in 0..CHUNK_SIZE {
             for y in 0..CHUNK_SIZE {
                 for z in 0..CHUNK_SIZE {
@@ -129,18 +190,24 @@
 			    if v.kind == VoxelKind::Air {
 				continue;
 			    }
-			    v
+			    *v
 			}
 			None => continue,
 		    };
 		    
-                    // if let Some(Voxel::Air) = self.get_voxel(x, y, z) {
-                    //     continue;
-                    // }
                     if !self.is_exposed(x, y, z) {
                         continue;
                     }
 
+		    if vertex_offset + 24 > MAX_VERTICES_PER_MESH {
+			self.flush_mesh_buffer(&mut vertices,
+						&mut normals,
+						&mut indices,
+						&mut colors
+			);
+			vertex_offset = 0;
+		    }
+
                     // first side
                     vertices.push(Vector3::new(x as f32, y as f32, z as f32));
                     vertices.push(Vector3::new(
@@ -315,57 +382,7 @@
                 }
             }
         }
-
-        let vertex_count = vertices.len();
-        let index_count = indices.len();
-        let normals_count = normals.len();
-
-        if vertex_count == 0 {
-            self.mesh = None;
-            return;
-        }
-
-        unsafe {
-            let v_size = vertex_count * std::mem::size_of::<Vector3>();
-            let i_size = index_count * std::mem::size_of::<u16>();
-            let n_size = normals_count * std::mem::size_of::<Vector3>();
-	    let c_size = colors.len();
-
-            let v_ptr = rlb::ffi::MemAlloc(v_size as u32) as *mut Vector3;
-            let i_ptr = rlb::ffi::MemAlloc(i_size as u32) as *mut u16;
-            let n_ptr = rlb::ffi::MemAlloc(n_size as u32) as *mut Vector3;
-	    let c_ptr = rlb::ffi::MemAlloc(c_size as u32) as *mut u8;
-
-            std::ptr::copy_nonoverlapping(vertices.as_ptr(), v_ptr, vertex_count);
-            std::ptr::copy_nonoverlapping(indices.as_ptr(), i_ptr, index_count);
-            std::ptr::copy_nonoverlapping(normals.as_ptr(), n_ptr, normals_count);
-	    std::ptr::copy_nonoverlapping(colors.as_ptr(), c_ptr, colors.len());
-
-            let raw_mesh = rlb::ffi::Mesh {
-                vertexCount: vertex_count as i32,
-                triangleCount: (index_count / 3) as i32,
-                vertices: v_ptr as *mut std::ffi::c_float,
-                indices: i_ptr,
-                normals: n_ptr as *mut std::ffi::c_float,
-                texcoords: std::ptr::null_mut(),
-                texcoords2: std::ptr::null_mut(),
-                colors: c_ptr,
-                tangents: std::ptr::null_mut(),
-                animVertices: std::ptr::null_mut(),
-                animNormals: std::ptr::null_mut(),
-                boneCount: 0,
-                boneIndices: std::ptr::null_mut(),
-                boneWeights: std::ptr::null_mut(),
-                vaoId: 0,
-                vboId: std::ptr::null_mut(),
-            };
-
-            let mut mesh = Mesh::from_raw(raw_mesh);
-
-            mesh.upload(false);
-
-            self.mesh = Some(mesh);
-        }
+	self.flush_mesh_buffer(&mut vertices, &mut normals, &mut indices, &mut colors);
     }
 
     // returns voxel by chunk coordinates
@@ -501,7 +518,7 @@
                     chunk_pos: pos,
                     voxels,
                     dirty: true,
-                    mesh: None,
+                    meshes: Vec::new(),
                 });
             }
         }
@@ -523,3 +540,4 @@
 	colors.push(c.3);
     }
 }
+
diff --git a/src/main.rs b/src/main.rs
--- a/src/main.rs
+++ b/src/main.rs
@@ -54,7 +54,7 @@
         *chunk_material.shader_mut() = shader.make_weak();
     }
 
-    let mut world = World::new(6);
+    let mut world = World::new(5);
 
     let mut plr = Player::new(
         Vector3::new(0f32, 50f32, 0f32),
@@ -91,17 +91,26 @@
 			if !chunk.is_visible(&cam) {
 			    continue;
 			}
-                        if let Some(ref mesh) = chunk.mesh {
-                            d3.draw_mesh(
-                                mesh,
-                                chunk_material.clone(),
-                                Matrix::translate(
-                                    chunk.chunk_pos.x * CHUNK_SIZE as f32,
-                                    chunk.chunk_pos.y * CHUNK_SIZE as f32,
-                                    chunk.chunk_pos.z * CHUNK_SIZE as f32,
-                                ),
-                            );
-                        }
+			for mesh in &chunk.meshes {
+			    d3.draw_mesh(mesh, chunk_material.clone(),
+					 Matrix::translate(
+					     chunk.chunk_pos.x * CHUNK_SIZE as f32,
+					     chunk.chunk_pos.y * CHUNK_SIZE as f32,
+					     chunk.chunk_pos.z * CHUNK_SIZE as f32,
+					 ),	 
+			    );
+			}
+                        // if let Some(ref mesh) = chunk.mesh {
+                        //     d3.draw_mesh(
+                        //         mesh,
+                        //         chunk_material.clone(),
+                        //         Matrix::translate(
+                        //             chunk.chunk_pos.x * CHUNK_SIZE as f32,
+                        //             chunk.chunk_pos.y * CHUNK_SIZE as f32,
+                        //             chunk.chunk_pos.z * CHUNK_SIZE as f32,
+                        //         ),
+                        //     );
+                        // }
                         // chunk.draw(&mut shd);
                     }
                 });
diff --git a/src/voxel/mod.rs b/src/voxel/mod.rs
--- a/src/voxel/mod.rs
+++ b/src/voxel/mod.rs
@@ -23,7 +23,7 @@
 	let color = match kind {
 	    VoxelKind::Air => VoxelColor(0, 0, 0, 0),
 	    VoxelKind::Stone => VoxelColor(128, 128, 128, 255),
-	    VoxelKind::Dirt => VoxelColor(96, 136, 67, 255),
+	    VoxelKind::Dirt => VoxelColor(106, 180, 77, 255),
 	    VoxelKind::Wood => VoxelColor(161, 60, 0, 255),
 	};
 	Self { kind, color }