This commit is contained in:
griffi-gh 2023-01-16 23:27:14 +01:00
parent 09d08264d5
commit 2637838be9
4 changed files with 43 additions and 26 deletions

View file

@ -36,10 +36,12 @@ impl World {
pub fn update_loaded_chunks(&mut self, around_position: Vec2, options: &GameOptions, display: &Display) {
let render_dist = options.render_distance as i32 + 1;
let inside_chunk = (around_position / CHUNK_SIZE as f32).as_ivec2();
//Mark all chunks for unload
for (_, chunk) in &mut self.chunks {
chunk.desired = ChunkState::Unload;
}
//Load new/update chunks in range
for x in -render_dist..=render_dist {
for z in -render_dist..=render_dist {
@ -54,34 +56,47 @@ impl World {
} else {
chunk.desired = ChunkState::Rendered;
}
if matches!(chunk.state, ChunkState::Nothing) {
self.thread.queue_load(position);
}
if matches!(chunk.state, ChunkState::Loaded) && matches!(chunk.desired, ChunkState::Rendered) {
fn all_some<'a>(x: [Option<&'a Chunk>; 4]) -> Option<[&'a Chunk; 4]> {
Some([x[0]?, x[1]?, x[2]?, x[3]?])
}
if let Some(neighbors) = all_some(self.chunk_neighbors(chunk.position)) {
if {
neighbors[0].block_data.is_some() &&
neighbors[1].block_data.is_some() &&
neighbors[2].block_data.is_some() &&
neighbors[3].block_data.is_some()
} {
self.thread.queue_mesh(chunk, neighbors);
}
}
}
}
}
//State up/downgrades are handled here!
self.chunks.retain(|&position, chunk| {
//Handle Unload
self.chunks.retain(|_, chunk| !matches!(chunk.desired, ChunkState::Unload));
//State downgrades
for (_, chunk) in &mut self.chunks {
match chunk.desired {
// Any => Unload downgrade
ChunkState::Unload => {
return false
},
// Any => Nothing downgrade
ChunkState::Nothing => {
chunk.block_data = None;
chunk.vertex_buffer = None;
chunk.mesh = None;
chunk.state = ChunkState::Nothing;
},
// Nothing => Loading => Loaded upgrade
ChunkState::Loaded if matches!(chunk.state, ChunkState::Nothing) => {
self.thread.queue_load(position);
},
//Render => Loaded downgrade
ChunkState::Loaded if matches!(chunk.state, ChunkState::Rendering | ChunkState::Rendered) => {
chunk.vertex_buffer = None;
chunk.mesh = None;
chunk.state = ChunkState::Loaded;
},
_ => ()
}
true
});
}
//Apply changes from threads
self.thread.apply_tasks(&mut self.chunks, display);
}

View file

@ -1,5 +1,5 @@
use glam::IVec2;
use glium::VertexBuffer;
use glium::{VertexBuffer, IndexBuffer};
use crate::game::{
blocks::Block,
shaders::chunk::Vertex as ChunkVertex
@ -18,12 +18,11 @@ pub enum ChunkState {
}
pub type ChunkData = [[[Block; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE];
pub type ChunkMesh = VertexBuffer<ChunkVertex>;
pub struct Chunk {
pub position: IVec2,
pub block_data: Option<ChunkData>,
pub vertex_buffer: Option<(bool, ChunkMesh)>,
pub mesh: Option<(bool, VertexBuffer<ChunkVertex>, IndexBuffer<u16>)>,
pub state: ChunkState,
pub desired: ChunkState,
}
@ -32,7 +31,7 @@ impl Chunk {
Self {
position,
block_data: None,
vertex_buffer: None,
mesh: None,
state: ChunkState::Nothing,
desired: ChunkState::Nothing,
}

View file

@ -1,5 +1,5 @@
use glam::IVec2;
use glium::{Display, VertexBuffer};
use glium::{Display, VertexBuffer, IndexBuffer, index::PrimitiveType};
use std::{
thread::{self, JoinHandle},
collections::HashMap,
@ -17,7 +17,7 @@ pub struct WorldThreading {
//Options are needed here to take ownership,
//None values should never appear here!
pub load_tasks: HashMap<IVec2, Option<JoinHandle<ChunkData>>>,
pub mesh_tasks: HashMap<IVec2, Option<JoinHandle<Vec<ChunkVertex>>>>,
pub mesh_tasks: HashMap<IVec2, Option<JoinHandle<(Vec<ChunkVertex>, Vec<u16>)>>>,
}
impl WorldThreading {
pub fn new() -> Self {
@ -93,11 +93,12 @@ impl WorldThreading {
}
log::info!("mesh: done {}", position);
let handle = mem::take(handle).unwrap();
let data = handle.join().unwrap();
let (shape, index) = handle.join().unwrap();
let chunk = chunks.get_mut(position).unwrap();
chunk.vertex_buffer = Some((
chunk.mesh = Some((
true,
VertexBuffer::immutable(display, &data).expect("Failed to build VertexBuffer")
VertexBuffer::immutable(display, &shape).expect("Failed to build VertexBuffer"),
IndexBuffer::immutable(display, PrimitiveType::TrianglesList, &index).expect("Failed to build IndexBuffer")
));
chunk.state = ChunkState::Rendered;
false

View file

@ -1,7 +1,9 @@
use glam::IVec2;
use crate::game::world::chunk::{Chunk, ChunkData};
use crate::game::world::chunk::ChunkData;
use crate::game::shaders::chunk::Vertex as ChunkVertex;
pub fn generate_mesh(position: IVec2, chunk_data: ChunkData, neighbors: [ChunkData; 4]) -> Vec<ChunkVertex> {
vec![]
pub fn generate_mesh(position: IVec2, chunk_data: ChunkData, neighbors: [ChunkData; 4]) -> (Vec<ChunkVertex>, Vec<u16>) {
let vertex = Vec::new();
let index = Vec::new();
(vertex, index)
}