some refactoring, worldgen tasks and more (i forgor 💀)

This commit is contained in:
griffi-gh 2023-01-23 00:16:58 +01:00
parent 8f1821a8f5
commit ee55ef2d2a
8 changed files with 156 additions and 87 deletions

View file

@ -23,8 +23,8 @@ pub(crate) mod settings;
pub(crate) mod state; pub(crate) mod state;
pub(crate) mod camera; pub(crate) mod camera;
use rendering::{Renderer, RenderTarget, BackgroundColor, clear_background, draw_world}; use rendering::{Renderer, RenderTarget, BackgroundColor, clear_background};
use world::{ChunkStorage, ChunkMeshStorage, loading::update_loaded_world_around_player}; use world::{ChunkStorage, ChunkMeshStorage, loading::update_loaded_world_around_player, render::draw_world};
use player::spawn_player; use player::spawn_player;
use prefabs::load_prefabs; use prefabs::load_prefabs;
use settings::GameSettings; use settings::GameSettings;

View file

@ -1,20 +1,6 @@
use shipyard::{Unique, NonSendSync, UniqueView, UniqueViewMut, View, IntoIter}; use shipyard::{Unique, NonSendSync, UniqueView, UniqueViewMut};
use glium::{ use glium::{
Display, Surface, uniform, Display, Surface,
DrawParameters,
uniforms::{
Sampler,
SamplerBehavior,
MinifySamplerFilter,
MagnifySamplerFilter,
SamplerWrapFunction
},
draw_parameters::{
Depth,
DepthTest,
PolygonMode,
BackfaceCullingMode,
},
glutin::{ glutin::{
event_loop::EventLoop, event_loop::EventLoop,
window::WindowBuilder, window::WindowBuilder,
@ -22,18 +8,6 @@ use glium::{
}, },
}; };
use glam::Vec3; use glam::Vec3;
use crate::{
camera::Camera,
prefabs::{
ChunkShaderPrefab,
BlockTexturesPrefab,
},
world::{
ChunkStorage,
ChunkMeshStorage,
chunk::CHUNK_SIZE,
},
};
#[derive(Unique)] #[derive(Unique)]
pub struct RenderTarget(pub glium::Frame); pub struct RenderTarget(pub glium::Frame);
@ -66,52 +40,3 @@ pub fn clear_background(
) { ) {
target.0.clear_color_srgb_and_depth((color.0.x, color.0.y, color.0.z, 1.), 1.); target.0.clear_color_srgb_and_depth((color.0.x, color.0.y, color.0.z, 1.), 1.);
} }
pub fn draw_world(
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
chunks: UniqueView<ChunkStorage>,
meshes: NonSendSync<UniqueView<ChunkMeshStorage>>,
program: NonSendSync<UniqueView<ChunkShaderPrefab>>,
texture: NonSendSync<UniqueView<BlockTexturesPrefab>>,
camera: View<Camera>,
) {
let camera = camera.iter().next().expect("No cameras in the scene");
let draw_parameters = DrawParameters {
depth: Depth {
test: DepthTest::IfLess,
write: true,
..Default::default()
},
polygon_mode: PolygonMode::Fill, //Change to Line for wireframe
backface_culling: BackfaceCullingMode::CullCounterClockwise,
..Default::default()
};
let texture_sampler = Sampler(&texture.0, SamplerBehavior {
minify_filter: MinifySamplerFilter::Linear,
magnify_filter: MagnifySamplerFilter::Nearest,
max_anisotropy: 8,
wrap_function: (SamplerWrapFunction::Clamp, SamplerWrapFunction::Clamp, SamplerWrapFunction::Clamp),
..Default::default()
});
let view = camera.view_matrix.to_cols_array_2d();
let perspective = camera.perspective_matrix.to_cols_array_2d();
for (&position, chunk) in &chunks.chunks {
if let Some(key) = chunk.mesh_index {
let mesh = meshes.get(key).expect("Mesh index pointing to nothing");
let world_position = (position.as_vec3() * CHUNK_SIZE as f32).to_array();
target.0.draw(
&mesh.vertex_buffer,
&mesh.index_buffer,
&program.0,
&uniform! {
position_offset: world_position,
view: view,
perspective: perspective,
tex: texture_sampler
},
&draw_parameters
).unwrap();
}
}
}

View file

@ -11,14 +11,13 @@ pub mod tasks;
pub mod loading; pub mod loading;
pub mod mesh; pub mod mesh;
pub mod neighbors; pub mod neighbors;
pub mod worldgen;
use chunk::{Chunk, ChunkMesh}; use chunk::{Chunk, ChunkMesh};
//TODO separate world struct for render data //TODO separate world struct for render data
// because this is not send-sync // because this is not send-sync
#[derive(Default, Unique)] #[derive(Default, Unique)]
#[track(Modification)] #[track(Modification)]
pub struct ChunkStorage { pub struct ChunkStorage {
@ -30,6 +29,10 @@ impl ChunkStorage {
} }
} }
#[derive(Unique)]
pub struct WorldInfo {
pub seed: u32,
}
#[derive(Default, Unique)] #[derive(Default, Unique)]
pub struct ChunkMeshStorage { pub struct ChunkMeshStorage {

View file

@ -0,0 +1,2 @@
pub mod data;
use data::MeshGenData;

34
src/world/mesh/data.rs Normal file
View file

@ -0,0 +1,34 @@
use crate::world::{
neighbors::AllChunkNeighbors,
chunk::BlockData
};
pub struct MeshGenData {
pub block_data: BlockData,
pub block_data_pos_z: BlockData,
pub block_data_neg_z: BlockData,
pub block_data_pos_y: BlockData,
pub block_data_neg_y: BlockData,
pub block_data_pos_x: BlockData,
pub block_data_neg_x: BlockData,
}
impl<'a> AllChunkNeighbors<'a> {
pub fn mesh_data(&self) -> Option<MeshGenData> {
let center_block_data = self.center.block_data.as_ref()?;
let front_block_data = self.front.block_data.as_ref()?;
let back_block_data = self.back.block_data.as_ref()?;
let top_block_data = self.top.block_data.as_ref()?;
let bottom_block_data = self.bottom.block_data.as_ref()?;
let right_block_data = self.right.block_data.as_ref()?;
let left_block_data = self.left.block_data.as_ref()?;
Some(MeshGenData {
block_data: center_block_data.blocks.clone(),
block_data_pos_z: front_block_data.blocks.clone(),
block_data_neg_z: back_block_data.blocks.clone(),
block_data_pos_y: top_block_data.blocks.clone(),
block_data_neg_y: bottom_block_data.blocks.clone(),
block_data_pos_x: right_block_data.blocks.clone(),
block_data_neg_x: left_block_data.blocks.clone(),
})
}
}

View file

@ -1,4 +1,34 @@
use glium::implement_vertex; use shipyard::{NonSendSync, UniqueView, UniqueViewMut, View, IntoIter};
use glium::{
implement_vertex, uniform,
Surface, DrawParameters,
uniforms::{
Sampler,
SamplerBehavior,
MinifySamplerFilter,
MagnifySamplerFilter,
SamplerWrapFunction
},
draw_parameters::{
Depth,
DepthTest,
PolygonMode,
BackfaceCullingMode,
}
};
use crate::{
camera::Camera,
rendering::RenderTarget,
prefabs::{
ChunkShaderPrefab,
BlockTexturesPrefab,
},
world::{
ChunkStorage,
ChunkMeshStorage,
chunk::CHUNK_SIZE,
},
};
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct ChunkVertex { pub struct ChunkVertex {
@ -8,3 +38,53 @@ pub struct ChunkVertex {
pub tex_index: u8, pub tex_index: u8,
} }
implement_vertex!(ChunkVertex, position, normal, uv, tex_index); implement_vertex!(ChunkVertex, position, normal, uv, tex_index);
pub fn draw_world(
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
chunks: UniqueView<ChunkStorage>,
meshes: NonSendSync<UniqueView<ChunkMeshStorage>>,
program: NonSendSync<UniqueView<ChunkShaderPrefab>>,
texture: NonSendSync<UniqueView<BlockTexturesPrefab>>,
camera: View<Camera>,
) {
let camera = camera.iter().next().expect("No cameras in the scene");
let draw_parameters = DrawParameters {
depth: Depth {
test: DepthTest::IfLess,
write: true,
..Default::default()
},
polygon_mode: PolygonMode::Fill, //Change to Line for wireframe
backface_culling: BackfaceCullingMode::CullCounterClockwise,
..Default::default()
};
let texture_sampler = Sampler(&texture.0, SamplerBehavior {
minify_filter: MinifySamplerFilter::Linear,
magnify_filter: MagnifySamplerFilter::Nearest,
max_anisotropy: 8,
wrap_function: (SamplerWrapFunction::Clamp, SamplerWrapFunction::Clamp, SamplerWrapFunction::Clamp),
..Default::default()
});
let view = camera.view_matrix.to_cols_array_2d();
let perspective = camera.perspective_matrix.to_cols_array_2d();
for (&position, chunk) in &chunks.chunks {
if let Some(key) = chunk.mesh_index {
let mesh = meshes.get(key).expect("Mesh index pointing to nothing");
let world_position = (position.as_vec3() * CHUNK_SIZE as f32).to_array();
target.0.draw(
&mesh.vertex_buffer,
&mesh.index_buffer,
&program.0,
&uniform! {
position_offset: world_position,
view: view,
perspective: perspective,
tex: texture_sampler
},
&draw_parameters
).unwrap();
}
}
}

View file

@ -2,19 +2,21 @@ use flume::{Sender, Receiver};
use glam::IVec3; use glam::IVec3;
use super::{ use super::{
chunk::BlockData, chunk::BlockData,
render::ChunkVertex render::ChunkVertex,
mesh::data::MeshGenData,
worldgen::generate_world,
}; };
pub enum ChunkTask { pub enum ChunkTask {
LoadChunk { LoadChunk {
seed: u32,
position: IVec3 position: IVec3
}, },
GenerateMesh { GenerateMesh {
position: IVec3, position: IVec3,
data: MeshGenData
} }
} }
pub enum ChunkTaskResponse { pub enum ChunkTaskResponse {
LoadedChunk { LoadedChunk {
position: IVec3, position: IVec3,
@ -36,7 +38,18 @@ impl ChunkTaskManager {
channel: flume::bounded::<ChunkTaskResponse>(0), channel: flume::bounded::<ChunkTaskResponse>(0),
} }
} }
pub fn spawn_task() { pub fn spawn_task(&self, task: ChunkTask) {
let sender = self.channel.0.clone();
rayon::spawn(move || {
sender.send(match task {
ChunkTask::GenerateMesh { position, data } => {
todo!()
},
ChunkTask::LoadChunk { position, seed } => {
let chunk_data = generate_world(position, seed);
ChunkTaskResponse::LoadedChunk { position, chunk_data }
}
});
});
} }
} }

12
src/world/worldgen.rs Normal file
View file

@ -0,0 +1,12 @@
use glam::IVec3;
use super::{
chunk::{BlockData, CHUNK_SIZE},
block::Block
};
pub fn generate_world(position: IVec3, seed: u32) -> BlockData {
let mut blocks = Box::new([[[Block::Air; CHUNK_SIZE]; CHUNK_SIZE]; CHUNK_SIZE]);
blocks[0][0][0] = Block::Stone;
//TODO actual world generation
blocks
}