resolved master merge

Commit fd3c18c648e1 · mgecumshooter · 2026-10-21 12:06 +0300

Changeset
fd3c18c648e197925ca2be0193fa512373db7cc6
Parents
18:6f99fed14ef3 16:26381e4bb667

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
@@ -30,12 +30,12 @@
         let mut s = Self {
             chunk_pos: pos,
             voxels: [Voxel::Air; CHUNK_SIZE*CHUNK_SIZE*CHUNK_SIZE],
-            dirty: false,
+            dirty: true,
             mesh: None
         };
-        for x in 0..31 {
-            for z in 0..31 {
-                let y = x + z;
+        for x in 0..CHUNK_SIZE {
+            for z in 0..CHUNK_SIZE {
+                let y = (x + z).min(CHUNK_SIZE - 1);
                 let i = x + (y * CHUNK_SIZE) + (z * CHUNK_SIZE * CHUNK_SIZE);
                 s.voxels[i] = Voxel::Stone;
             }
@@ -43,6 +43,238 @@
         s
     }
 
+    pub fn generate_mesh(&mut self, rl: &RaylibThread) {
+	let mut vertices: Vec<Vector3> = Vec::new();
+	let mut normals: Vec<Vector3> = Vec::new();
+	let mut indices: Vec<u16> = Vec::new();
+
+	let mut vertex_offset: i32 = 0;
+	for x in 0..CHUNK_SIZE {
+	    for y in 0..CHUNK_SIZE {
+		for z in 0..CHUNK_SIZE {
+		    if let Some(Voxel::Air) = self.get_voxel(x, y, z) {
+			continue;
+		    }
+		    if !self.is_exposed(x, y, z) {
+			continue;
+		    }
+
+
+		    // first side
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32, z as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32 + VOXEL_SIZE as f32, z as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32 + VOXEL_SIZE as f32, y as f32, z as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32 + VOXEL_SIZE as f32, y as f32 + VOXEL_SIZE as f32, z as f32)
+		    );
+		    push_quad_normal(&mut normals, Vector3::new(0f32, 0f32, -1f32));
+		    
+		    // second side
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32, z as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32 + VOXEL_SIZE as f32, z as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32, z as f32 + VOXEL_SIZE as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32 + VOXEL_SIZE as f32, z as f32 + VOXEL_SIZE as f32)
+		    );
+		    push_quad_normal(&mut normals, Vector3::new(-1f32, 0f32, 0f32));
+		    
+		    // third side
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32, z as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32 + VOXEL_SIZE as f32, y as f32, z as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32, z as f32 + VOXEL_SIZE as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32 + VOXEL_SIZE as f32, y as f32, z as f32 + VOXEL_SIZE as f32)
+		    );
+		    push_quad_normal(&mut normals, Vector3::new(0f32, -1f32, 0f32));
+
+		    // fourth side
+		    vertices.push(
+			Vector3::
+			new(x as f32+VOXEL_SIZE as f32, y as f32+VOXEL_SIZE as f32, z as f32+VOXEL_SIZE as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32 + VOXEL_SIZE as f32, z as f32 + VOXEL_SIZE as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32 + VOXEL_SIZE as f32, y as f32 + VOXEL_SIZE as f32, z as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32 + VOXEL_SIZE as f32, z as f32)
+		    );
+		    push_quad_normal(&mut normals, Vector3::new(0f32, 1f32, 0f32));
+
+		    // fifth side
+		    vertices.push(
+			Vector3::
+			new(x as f32+VOXEL_SIZE as f32, y as f32+VOXEL_SIZE as f32, z as f32+VOXEL_SIZE as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32 + VOXEL_SIZE as f32, y as f32, z as f32 + VOXEL_SIZE as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32 + VOXEL_SIZE as f32, y as f32 + VOXEL_SIZE as f32, z as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32 + VOXEL_SIZE as f32, y as f32, z as f32)
+		    );
+		    push_quad_normal(&mut normals, Vector3::new(1f32, 0f32, 0f32));
+
+		    // sixth side
+		    vertices.push(
+			Vector3::
+			new(x as f32+VOXEL_SIZE as f32, y as f32+VOXEL_SIZE as f32, z as f32+VOXEL_SIZE as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32 + VOXEL_SIZE as f32, y as f32, z as f32 + VOXEL_SIZE as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32 + VOXEL_SIZE as f32, z as f32 + VOXEL_SIZE as f32)
+		    );
+		    vertices.push(
+			Vector3::
+			new(x as f32, y as f32, z as f32 + VOXEL_SIZE as f32)
+		    );
+		    push_quad_normal(&mut normals, Vector3::new(0f32, 0f32, 1f32));
+
+
+		    indices.push(0 as u16 + vertex_offset as u16);
+		    indices.push(1 as u16 + vertex_offset as u16);
+		    indices.push(2 as u16 + vertex_offset as u16);
+		    indices.push(2 as u16 + vertex_offset as u16);
+		    indices.push(1 as u16 + vertex_offset as u16);
+		    indices.push(3 as u16 + vertex_offset as u16);
+
+		    indices.push(4 as u16 + vertex_offset as u16);
+		    indices.push(6 as u16 + vertex_offset as u16);
+		    indices.push(5 as u16 + vertex_offset as u16);
+		    indices.push(5 as u16 + vertex_offset as u16);
+		    indices.push(6 as u16 + vertex_offset as u16);
+		    indices.push(7 as u16 + vertex_offset as u16);
+
+		    indices.push(8 as u16 + vertex_offset as u16);
+		    indices.push(9 as u16 + vertex_offset as u16);
+		    indices.push(10 as u16 + vertex_offset as u16);
+		    indices.push(10 as u16 + vertex_offset as u16);
+		    indices.push(9 as u16 + vertex_offset as u16);
+		    indices.push(11 as u16 + vertex_offset as u16);
+
+		    indices.push(12 as u16 + vertex_offset as u16);
+		    indices.push(14 as u16 + vertex_offset as u16);
+		    indices.push(13 as u16 + vertex_offset as u16);
+		    indices.push(13 as u16 + vertex_offset as u16);
+		    indices.push(14 as u16 + vertex_offset as u16);
+		    indices.push(15 as u16 + vertex_offset as u16);
+
+		    indices.push(16 as u16 + vertex_offset as u16);
+		    indices.push(17 as u16 + vertex_offset as u16);
+		    indices.push(18 as u16 + vertex_offset as u16);
+		    indices.push(18 as u16 + vertex_offset as u16);
+		    indices.push(17 as u16 + vertex_offset as u16);
+		    indices.push(19 as u16 + vertex_offset as u16);
+
+		    indices.push(20 as u16 + vertex_offset as u16);
+		    indices.push(22 as u16 + vertex_offset as u16);
+		    indices.push(21 as u16 + vertex_offset as u16);
+		    indices.push(21 as u16 + vertex_offset as u16);
+		    indices.push(22 as u16 + vertex_offset as u16);
+		    indices.push(23 as u16 + vertex_offset as u16);
+
+
+
+		    vertex_offset += 24;
+
+		}
+	    }
+	}
+
+	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 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;
+
+            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);
+
+            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: std::ptr::null_mut(),
+		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);
+	}
+	
+    }
+
     // returns voxel by chunk coordinates
     pub fn get_voxel(&self, x: usize, y: usize, z: usize) -> Option<&Voxel> {
         if x >= CHUNK_SIZE || y >= CHUNK_SIZE || z >= CHUNK_SIZE {
@@ -187,7 +419,7 @@
 		return Some(Self{
 		    chunk_pos: pos,
 		    voxels,
-		    dirty: false,
+		    dirty: true,
 		    mesh: None,
 		});
 	    }
@@ -195,3 +427,11 @@
 	None
     }
 }
+
+
+fn push_quad_normal(normals: &mut Vec<Vector3>, n: Vector3) {
+    for _ in 0..4 {
+        normals.push(n);
+    }
+}
+
diff --git a/src/main.rs b/src/main.rs
--- a/src/main.rs
+++ b/src/main.rs
@@ -12,7 +12,7 @@
 // internal modules
 use chunk::*;
 use player::Player;
-use util::Cube;
+use util::*;
 use world::*;
 
 fn main() {
@@ -28,31 +28,32 @@
     rl.hide_cursor();
     rl.disable_cursor();
 
+    rl.set_trace_log(TraceLogLevel::LOG_WARNING);
+
     // shader stuff
-    let mut shader = rl
-        .load_shader(
-            &rl_thd,
-            Some("shaders/vert.glsl"),
-            Some("shaders/frag.glsl"),
-        )
-        .unwrap();
-    let mut post_shader = rl
-        .load_shader(&rl_thd, None, Some("shaders/post.glsl"))
-        .unwrap();
-    let mut rend_tex = rl
-        .load_render_texture(
-            &rl_thd,
-            rl.get_render_width() as u32,
-            rl.get_render_height() as u32,
-        )
-        .unwrap();
+    let mut shader = rl.load_shader(&rl_thd, Some("shaders/vert.glsl"), Some("shaders/frag.glsl")).unwrap();
+    let mut post_shader = rl.load_shader(&rl_thd, None, Some("shaders/post.glsl")).unwrap();
+
+    let depth_loc = post_shader.get_shader_location("depth_tex");
+
+    assert!(depth_loc >= 0, "Uniform depth_tex not found");
+    
+    // let mut rend_tex = rl.load_render_texture
+    // 	(&rl_thd, rl.get_render_width() as u32, rl.get_render_height() as u32).unwrap();
+
+    let mut chunk_material = rl.load_material_default(&rl_thd);
+    let mut rend_tex = unsafe { load_depth_tex(rl.get_render_width(), rl.get_render_height()) };
+    unsafe {
+	*chunk_material.shader_mut() = shader.make_weak();	
+    }
+    // chunk_material.set_shader(&shader);
 
     // chunks
     // let test_chunk = Chunk::new(Vector3::zero());
 
     // let test2 = [&test_chunk];
 
-    let mut world = World::new(2);
+    let mut world = World::new(4);
 
     let mut plr = Player::new(
         Vector3::new(0f32, 10f32, 0f32),
@@ -61,21 +62,18 @@
 
     // main game loop
     while !rl.window_should_close() {
-        world.update_around_player(plr.get_eye_pos());
-
-        let active_chunks: Vec<&Chunk> = world.chunks.values().collect();
-        plr.update(&rl, &active_chunks);
-        plr.apply_to_camera(&mut cam);
+	world.load_around_player(plr.get_eye_pos());
+	world.update_chunks(&rl_thd);
 
-        if rend_tex.width() != rl.get_render_width() || rend_tex.height() != rl.get_render_height()
-        {
-            rend_tex = rl
-                .load_render_texture(
-                    &rl_thd,
-                    rl.get_render_width() as u32,
-                    rl.get_render_height() as u32,
-                )
-                .unwrap();
+	let active_chunks: Vec<&Chunk> = world.chunks.values().collect();
+	plr.update(&rl, &active_chunks);
+	plr.apply_to_camera(&mut cam);
+
+	
+        if rend_tex.width() != rl.get_render_width() || rend_tex.height() != rl.get_render_height() {
+	    rend_tex = unsafe { load_depth_tex(rl.get_render_width(), rl.get_render_height()) };
+            // rend_tex = rl.load_render_texture
+	    // 	(&rl_thd, rl.get_render_width() as u32, rl.get_render_height() as u32).unwrap();
         }
 
         rl.draw(&rl_thd, |mut d| {
@@ -83,26 +81,38 @@
                 tx.clear_background(Color::new(30, 30, 30, 255));
                 tx.draw_mode3D(cam, |mut d3, _| {
                     d3.draw_grid(100, 1f32);
-                    d3.draw_shader_mode(&mut shader, |mut shd| {
-                        // test_chunk.draw(&mut shd);
-                        for chunk in world.chunks.values() {
-                            chunk.draw(&mut shd);
-                        }
-                    });
+		    for chunk in world.chunks.values() {
+			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);
+		    }
                 });
             });
+	    post_shader.set_shader_value_texture(
+		post_shader.get_shader_location("depth_tex"),
+		unsafe { Texture2D::from_raw(rend_tex.depth).make_weak() }
+	    );
             d.draw_shader_mode(&mut post_shader, |mut shd| {
-                shd.draw_texture_rec(
-                    &rend_tex,
-                    Rectangle {
-                        x: 0f32,
-                        y: 0f32,
-                        width: rend_tex.texture().width as f32,
-                        height: -rend_tex.texture().height as f32,
-                    },
-                    Vector2::zero(),
-                    Color::WHITE,
-                );
+		unsafe {
+		    rlb::ffi::rlSetUniformSampler(
+			depth_loc,
+			rend_tex.depth.id
+		    );
+		}
+                shd.draw_texture_rec(&rend_tex, Rectangle{
+                    x: 0f32,
+                    y: 0f32,
+                    width: rend_tex.texture().width as f32,
+                    height: -rend_tex.texture().height as f32
+                }, Vector2::zero(), Color::WHITE);
             });
             d.draw_text(
                 &format!(
diff --git a/src/util/mod.rs b/src/util/mod.rs
--- a/src/util/mod.rs
+++ b/src/util/mod.rs
@@ -1,5 +1,6 @@
 use super::rlb;
 use rlb::prelude::*;
+// use rlb::core::*;
 
 pub struct Cube {
     pub width: f32,
@@ -30,3 +31,62 @@
 	    self.min.z < other.max.z && self.max.z > other.min.z
     }
 }
+
+// had to do this ;(
+pub fn load_depth_tex(width: i32, height: i32) -> RenderTexture2D {
+    unsafe {
+	let fbo_id = rlb::ffi::rlLoadFramebuffer();
+	rlb::ffi::rlEnableFramebuffer(fbo_id);
+
+	let col_tex_id = rlb::ffi::rlLoadTexture(
+	    std::ptr::null(),
+	    width,
+	    height,
+	    rlb::ffi::PixelFormat::PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 as i32,
+	    1
+	);
+
+	rlb::ffi::rlFramebufferAttach(
+	    fbo_id,
+	    col_tex_id,
+	    rlb::ffi::rlFramebufferAttachType::RL_ATTACHMENT_COLOR_CHANNEL0 as i32,
+	    rlb::ffi::rlFramebufferAttachTextureType::RL_ATTACHMENT_TEXTURE2D as i32,
+	    0
+	);
+
+	let depth_tex_id = rlb::ffi::rlLoadTextureDepth(width, height, false);
+
+	rlb::ffi::rlFramebufferAttach(
+	    fbo_id,
+	    depth_tex_id,
+	    rlb::ffi::rlFramebufferAttachType::RL_ATTACHMENT_DEPTH as i32,
+	    rlb::ffi::rlFramebufferAttachTextureType::RL_ATTACHMENT_TEXTURE2D as i32,
+	    0
+	);
+	
+	let fbo_complete = rlb::ffi::rlFramebufferComplete(fbo_id);
+	rlb::ffi::rlDisableFramebuffer();
+	assert!(
+	    fbo_complete,
+	    "Framebuffer incomplete!"
+	);
+	
+	RenderTexture2D::from_raw(rlb::ffi::RenderTexture2D {
+	    id: fbo_id,
+	    texture: rlb::ffi::Texture2D {
+		id: col_tex_id,
+		width,
+		height,
+		mipmaps: 1,
+		format: rlb::ffi::PixelFormat::PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 as i32,
+	    },
+	    depth: rlb::ffi::Texture2D {
+		id: depth_tex_id,
+		width,
+		height,
+		mipmaps: 1,
+		format: 19,
+	    },
+	})
+    }
+}
diff --git a/src/world/mod.rs b/src/world/mod.rs
--- a/src/world/mod.rs
+++ b/src/world/mod.rs
@@ -15,7 +15,23 @@
 	}
     }
 
-    pub fn update_around_player(&mut self, player_pos: Vector3) {
+    pub fn update_chunks(&mut self, rl: &RaylibThread) {
+	const CHUNK_PER_FRAME: usize = 2;
+	let mut processed = 0;
+	
+	for (_, mut chunk) in &mut self.chunks {
+	    if processed >= CHUNK_PER_FRAME {
+		break;
+	    }
+	    if chunk.dirty {
+		chunk.generate_mesh(rl);
+		chunk.dirty = false;
+		processed += 1;
+	    }
+	}
+    }
+
+    pub fn load_around_player(&mut self, player_pos: Vector3) {
 	let p_chunk_x = (player_pos.x / CHUNK_SIZE as f32).floor() as i32;
 	let p_chunk_y = (player_pos.y / CHUNK_SIZE as f32).floor() as i32;
 	let p_chunk_z = (player_pos.z / CHUNK_SIZE as f32).floor() as i32;
@@ -56,7 +72,7 @@
 	    }
 	}
 	for coords in to_unload {
-	    if let Some(chunk) = self.chunks.remove(&coords) {
+	    if let Some(mut chunk) = self.chunks.remove(&coords) {
 		chunk.save();
 	    }
 	}