From 7b5120b1d43b9f6a4f91cbf129d20729e87c539c Mon Sep 17 00:00:00 2001 From: griffi-gh Date: Sun, 22 Jan 2023 17:01:54 +0100 Subject: [PATCH] chunk rendering --- src/camera.rs | 22 ++++++++++--- src/main.rs | 3 +- src/player.rs | 15 ++++++--- src/prefabs.rs | 4 +-- src/rendering.rs | 82 +++++++++++++++++++++++++++++++++++++++++++++--- src/world.rs | 3 ++ 6 files changed, 113 insertions(+), 16 deletions(-) diff --git a/src/camera.rs b/src/camera.rs index 3efa0f6..501f720 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -1,5 +1,6 @@ -use glam::{Mat4, Vec3, Vec3A}; +use glam::{Mat4, Vec3}; use shipyard::{Component, ViewMut, View, IntoIter, Workload, IntoWorkload}; +use std::f32::consts::PI; use crate::transform::Transform; #[derive(Component)] @@ -11,6 +12,20 @@ pub struct Camera { pub z_near: f32, pub z_far: f32, } +impl Camera { + pub fn new(fov: f32, z_near: f32, z_far: f32, up: Vec3) -> Self { + Self { + fov, z_near, z_far, up, + perspective_matrix: Mat4::default(), + view_matrix: Mat4::default(), + } + } +} +impl Default for Camera { + fn default() -> Self { + Self::new(PI / 3., 0.1, 1024., Vec3::Y) + } +} pub fn compute_cameras() -> Workload { ( @@ -31,12 +46,11 @@ fn update_view_matrix( } fn update_perspective_matrix( - mut vm_camera: ViewMut, - v_transform: View + mut vm_camera: ViewMut ) { //todo compute this on win resize! const ASPECT_RATIO: f32 = 9. / 16.; - for (camera, transform) in (&mut vm_camera, &v_transform).iter() { + for camera in (&mut vm_camera).iter() { camera.perspective_matrix = Mat4::perspective_rh_gl( camera.fov, ASPECT_RATIO, diff --git a/src/main.rs b/src/main.rs index 97232f8..64230cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,7 +23,7 @@ pub(crate) mod settings; pub(crate) mod state; pub(crate) mod camera; -use rendering::{Renderer, RenderTarget, BackgroundColor, clear_background}; +use rendering::{Renderer, RenderTarget, BackgroundColor, clear_background, draw_world}; use world::{ChunkStorage, ChunkMeshStorage, loading::update_loaded_world_around_player}; use player::spawn_player; use prefabs::load_prefabs; @@ -47,6 +47,7 @@ fn update() -> Workload { fn render() -> Workload { ( clear_background, + draw_world, ).into_sequential_workload() } diff --git a/src/player.rs b/src/player.rs index 9990f65..822a1df 100644 --- a/src/player.rs +++ b/src/player.rs @@ -1,7 +1,9 @@ use glam::Mat4; use shipyard::{Component, EntitiesViewMut, ViewMut}; - -use crate::transform::Transform; +use crate::{ + transform::Transform, + camera::Camera, +}; #[derive(Component)] pub struct LocalPlayer; @@ -13,19 +15,22 @@ pub fn spawn_player ( mut entities: EntitiesViewMut, mut vm_player: ViewMut, mut vm_local_player: ViewMut, - mut vm_transform: ViewMut + mut vm_transform: ViewMut, + mut vm_camera: ViewMut, ) { log::info!("spawning player"); entities.add_entity( ( &mut vm_player, &mut vm_local_player, - &mut vm_transform + &mut vm_transform, + &mut vm_camera, ), ( Player, LocalPlayer, - Transform(Mat4::default()) + Transform(Mat4::default()), + Camera::default() ) ); } diff --git a/src/prefabs.rs b/src/prefabs.rs index b77108e..9d2f3ba 100644 --- a/src/prefabs.rs +++ b/src/prefabs.rs @@ -51,10 +51,10 @@ impl AssetPaths for BlockTextures { } #[derive(Unique)] -pub struct BlockTexturesPrefab(SrgbTexture2dArray); +pub struct BlockTexturesPrefab(pub SrgbTexture2dArray); #[derive(Unique)] -pub struct ChunkShaderPrefab(Program); +pub struct ChunkShaderPrefab(pub Program); pub fn load_prefabs(world: &World) { let renderer = world.borrow::>>().unwrap(); diff --git a/src/rendering.rs b/src/rendering.rs index ae07223..30480c9 100644 --- a/src/rendering.rs +++ b/src/rendering.rs @@ -1,13 +1,38 @@ -use shipyard::{Unique, NonSendSync, UniqueView, UniqueViewMut}; +use shipyard::{Unique, NonSendSync, UniqueView, UniqueViewMut, View, IntoIter}; use glium::{ + Display, Surface, uniform, + DrawParameters, + uniforms::{ + Sampler, + SamplerBehavior, + MinifySamplerFilter, + MagnifySamplerFilter + }, + draw_parameters::{ + Depth, + DepthTest, + PolygonMode, + BackfaceCullingMode, + }, glutin::{ event_loop::EventLoop, window::WindowBuilder, ContextBuilder, GlProfile - }, - Display, Surface, + }, }; use glam::Vec3; +use crate::{ + camera::Camera, + prefabs::{ + ChunkShaderPrefab, + BlockTexturesPrefab, + }, + world::{ + ChunkStorage, + ChunkMeshStorage, + chunk::CHUNK_SIZE, + }, +}; #[derive(Unique)] pub struct RenderTarget(pub glium::Frame); @@ -34,6 +59,55 @@ impl Renderer { } } -pub fn clear_background(mut target: NonSendSync>, color: UniqueView) { +pub fn clear_background( + mut target: NonSendSync>, + color: UniqueView, +) { 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>, + chunks: UniqueView, + meshes: NonSendSync>, + program: NonSendSync>, + texture: NonSendSync>, + camera: View, +) { + let camera = camera.iter().next().expect("No cameras in the scene"); + let draw_parameters = DrawParameters { + depth: Depth { + test: DepthTest::IfLess, + write: true, + ..Default::default() + }, + ..Default::default() + }; + let texture_sampler = Sampler(&texture.0, SamplerBehavior { + minify_filter: MinifySamplerFilter::Linear, + magnify_filter: MagnifySamplerFilter::Nearest, + max_anisotropy: 8, + ..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(); + } + } +} diff --git a/src/world.rs b/src/world.rs index 72d19e0..a3d0f5c 100644 --- a/src/world.rs +++ b/src/world.rs @@ -129,4 +129,7 @@ impl ChunkMeshStorage { self.meshes.remove(&key).context("Chunk doesn't exist")?; Ok(()) } + pub fn get(&self, key: usize) -> Option<&ChunkMesh> { + self.meshes.get(&key) + } }