chunk rendering

This commit is contained in:
griffi-gh 2023-01-22 17:01:54 +01:00
parent 26b43ed2ca
commit 7b5120b1d4
6 changed files with 113 additions and 16 deletions

View file

@ -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<Camera>,
v_transform: View<Transform>
mut vm_camera: ViewMut<Camera>
) {
//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,

View file

@ -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()
}

View file

@ -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<Player>,
mut vm_local_player: ViewMut<LocalPlayer>,
mut vm_transform: ViewMut<Transform>
mut vm_transform: ViewMut<Transform>,
mut vm_camera: ViewMut<Camera>,
) {
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()
)
);
}

View file

@ -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::<NonSendSync<UniqueView<Renderer>>>().unwrap();

View file

@ -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<UniqueViewMut<RenderTarget>>, color: UniqueView<BackgroundColor>) {
pub fn clear_background(
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
color: UniqueView<BackgroundColor>,
) {
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()
},
..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();
}
}
}

View file

@ -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)
}
}