should be all working now

This commit is contained in:
griffi-gh 2023-01-17 15:08:19 +01:00
parent 2637838be9
commit 096db79b12
5 changed files with 40 additions and 36 deletions

View file

@ -10,3 +10,4 @@ log = "0.4"
env_logger = "0.10"
strum = { version = "0.24", features = ["derive"] }
glam = { version = "0.22", features = ["debug-glam-assert", "mint", "fast-math"] }
hashbrown = "0.13"

View file

@ -1,6 +1,6 @@
use glam::{Vec2, IVec2};
use glium::Display;
use std::collections::HashMap;
use hashbrown::HashMap;
use crate::game::options::GameOptions;
mod chunk;
@ -50,16 +50,20 @@ impl World {
if !self.chunks.contains_key(&position) {
self.chunks.insert(position, Chunk::new(position));
}
{
//we only need mutable reference here:
let chunk = self.chunks.get_mut(&position).unwrap();
if x == 0 || z == 0 || x == render_dist || z == render_dist {
chunk.desired = ChunkState::Loaded;
} 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) {
//borrow chunk immutably
let chunk = self.chunks.get(&position).unwrap();
if matches!(chunk.state, ChunkState::Nothing) && matches!(chunk.desired, ChunkState::Loaded | ChunkState::Rendered) {
self.thread.queue_load(position);
} else 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]?])
}
@ -70,33 +74,43 @@ impl World {
neighbors[2].block_data.is_some() &&
neighbors[3].block_data.is_some()
} {
self.thread.queue_mesh(chunk, neighbors);
self.thread.queue_mesh(
position,
chunk.block_data.clone().unwrap(),
[
neighbors[0].block_data.clone().unwrap(),
neighbors[1].block_data.clone().unwrap(),
neighbors[2].block_data.clone().unwrap(),
neighbors[3].block_data.clone().unwrap(),
]
);
}
}
}
}
}
//Handle Unload
self.chunks.retain(|_, chunk| !matches!(chunk.desired, ChunkState::Unload));
//State downgrades
for (_, chunk) in &mut self.chunks {
//Unloads and state downgrades
self.chunks.retain(|_, chunk| {
match chunk.desired {
// Chunk unload
ChunkState::Unload => false,
// Any => Nothing downgrade
ChunkState::Nothing => {
chunk.block_data = None;
chunk.mesh = None;
chunk.state = ChunkState::Nothing;
true
},
//Render => Loaded downgrade
ChunkState::Loaded if matches!(chunk.state, ChunkState::Rendering | ChunkState::Rendered) => {
chunk.mesh = None;
chunk.state = ChunkState::Loaded;
true
},
_ => ()
}
_ => true
}
});
//Apply changes from threads
self.thread.apply_tasks(&mut self.chunks, display);
}

View file

@ -17,7 +17,7 @@ pub enum ChunkState {
Rendered,
}
pub type ChunkData = [[[Block; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE];
pub type ChunkData = Box<[[[Block; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE]>;
pub struct Chunk {
pub position: IVec2,

View file

@ -1,10 +1,7 @@
use glam::IVec2;
use glium::{Display, VertexBuffer, IndexBuffer, index::PrimitiveType};
use std::{
thread::{self, JoinHandle},
collections::HashMap,
mem
};
use std::{mem, thread::{self, JoinHandle}};
use hashbrown::HashMap;
use super::chunk::{Chunk, ChunkData, ChunkState};
use crate::game::shaders::chunk::Vertex as ChunkVertex;
@ -38,20 +35,12 @@ impl WorldThreading {
log::warn!("load: discarded {}, reason: new task started", position);
}
}
pub fn queue_mesh(&mut self, chunk: &Chunk, neighbors: [&Chunk; 4]) {
let position = chunk.position;
let data = chunk.block_data.expect("Chunk has no mesh!");
let neighbor_data = [
neighbors[0].block_data.expect("Chunk has no mesh!"),
neighbors[1].block_data.expect("Chunk has no mesh!"),
neighbors[2].block_data.expect("Chunk has no mesh!"),
neighbors[3].block_data.expect("Chunk has no mesh!"),
];
pub fn queue_mesh(&mut self, position: IVec2, chunk: ChunkData, neighbor_data: [ChunkData; 4]) {
let handle = thread::spawn(move || {
mesh_gen::generate_mesh(position, data, neighbor_data)
mesh_gen::generate_mesh(position, chunk, neighbor_data)
});
if self.mesh_tasks.insert(chunk.position, Some(handle)).is_some() {
log::warn!("mesh: discarded {}, reason: new task started", chunk.position);
if self.mesh_tasks.insert(position, Some(handle)).is_some() {
log::warn!("mesh: discarded {}, reason: new task started", position);
}
}
pub fn apply_tasks(&mut self, chunks: &mut HashMap<IVec2, Chunk>, display: &Display) {

View file

@ -4,5 +4,5 @@ use crate::game::{
};
pub fn generate_chunk() -> ChunkData {
[[[Block::Stone; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE]
Box::new([[[Block::Stone; CHUNK_SIZE]; CHUNK_HEIGHT]; CHUNK_SIZE])
}