uniforms, bind groups and other nice stuff

This commit is contained in:
griffi-gh 2023-07-20 03:03:52 +02:00
parent 0dc53e033b
commit cafd0a4b3d
18 changed files with 415 additions and 322 deletions

View file

@ -2,7 +2,7 @@ use serde::{Serialize, Deserialize};
use strum::EnumIter; use strum::EnumIter;
#[derive(Serialize, Deserialize, Clone, Copy, Debug, EnumIter)] #[derive(Serialize, Deserialize, Clone, Copy, Debug, EnumIter)]
#[repr(u8)] #[repr(u32)]
pub enum BlockTexture { pub enum BlockTexture {
Stone, Stone,
Dirt, Dirt,

View file

@ -1,4 +1,4 @@
use shipyard::{NonSendSync, UniqueView, Unique, AllStoragesView}; use shipyard::{UniqueView, Unique, AllStoragesView};
use kubi_shared::block::BlockTexture; use kubi_shared::block::BlockTexture;
use crate::rendering::Renderer; use crate::rendering::Renderer;
@ -6,7 +6,6 @@ mod texture;
mod shaders; mod shaders;
use texture::load_asset_texture_array; use texture::load_asset_texture_array;
use shaders::include_shader_prefab;
pub trait AssetPaths { pub trait AssetPaths {
fn file_name(self) -> &'static str; fn file_name(self) -> &'static str;
@ -41,10 +40,10 @@ pub struct BlockTexturesAsset(pub wgpu::Texture);
pub fn load_prefabs( pub fn load_prefabs(
storages: AllStoragesView, storages: AllStoragesView,
renderer: NonSendSync<UniqueView<Renderer>> renderer: UniqueView<Renderer>
) { ) {
log::info!("Loading textures..."); log::info!("Loading textures...");
storages.add_unique_non_send_sync(BlockTexturesAsset( storages.add_unique(BlockTexturesAsset(
load_asset_texture_array::<BlockTexture>("blocks".into(), &renderer) load_asset_texture_array::<BlockTexture>("blocks".into(), &renderer)
)); ));
} }

View file

@ -8,6 +8,8 @@ mod frustum;
use matrices::update_matrices; use matrices::update_matrices;
use frustum::{Frustum, update_frustum}; use frustum::{Frustum, update_frustum};
//TODO: handle cases where we have multiple cameras
#[derive(Component)] #[derive(Component)]
pub struct Camera { pub struct Camera {
pub view_matrix: Mat4, pub view_matrix: Mat4,

View file

@ -7,7 +7,7 @@ pub struct CursorLock(pub bool);
pub fn update_cursor_lock_state( pub fn update_cursor_lock_state(
lock: UniqueView<CursorLock>, lock: UniqueView<CursorLock>,
renderer: NonSendSync<UniqueView<Renderer>> renderer: UniqueView<Renderer>
) { ) {
#[cfg(not(target_os = "android"))] #[cfg(not(target_os = "android"))]
if lock.is_inserted_or_modified() { if lock.is_inserted_or_modified() {

View file

@ -82,7 +82,7 @@ pub fn initial_resize_event(
mut storages: AllStoragesViewMut, mut storages: AllStoragesViewMut,
) { ) {
let size = { let size = {
let renderer = storages.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap(); let renderer = storages.borrow::<UniqueView<Renderer>>().unwrap();
UVec2::new(renderer.size.width, renderer.size.height) UVec2::new(renderer.size.width, renderer.size.height)
}; };
storages.add_entity(( storages.add_entity((

View file

@ -59,10 +59,11 @@ use rendering::{
Renderer, Renderer,
RenderTarget, RenderTarget,
BackgroundColor, BackgroundColor,
init_rendering_internals,
world::{draw_world, draw_current_chunk_border}, world::{draw_world, draw_current_chunk_border},
selection_box::render_selection_box, selection_box::render_selection_box,
entities::render_entities, entities::render_entities,
renderer_finish_init, camera_uniform::update_camera_uniform,
}; };
use block_placement::update_block_placement; use block_placement::update_block_placement;
use delta_time::{DeltaTime, init_delta_time}; use delta_time::{DeltaTime, init_delta_time};
@ -84,7 +85,7 @@ fn pre_startup() -> Workload {
fn startup() -> Workload { fn startup() -> Workload {
( (
renderer_finish_init, init_rendering_internals,
init_fixed_timestamp_storage, init_fixed_timestamp_storage,
initial_resize_event, initial_resize_event,
load_prefabs, load_prefabs,
@ -133,9 +134,11 @@ fn update() -> Workload {
).into_sequential_workload() ).into_sequential_workload()
} }
//TODO move this to the renderer module
fn render() -> Workload { fn render() -> Workload {
( (
( (
update_camera_uniform,
draw_world, draw_world,
draw_current_chunk_border, draw_current_chunk_border,
render_selection_box, render_selection_box,
@ -191,7 +194,7 @@ pub fn kubi_main() {
//Initialize renderer //Initialize renderer
{ {
let settings = world.borrow::<UniqueView<GameSettings>>().unwrap(); let settings = world.borrow::<UniqueView<GameSettings>>().unwrap();
world.add_unique_non_send_sync(Renderer::init_blocking(&event_loop, &settings)); world.add_unique(Renderer::init_blocking(&event_loop, &settings));
} }
world.add_unique(BackgroundColor(vec3(0.5, 0.5, 1.))); world.add_unique(BackgroundColor(vec3(0.5, 0.5, 1.)));
@ -215,7 +218,7 @@ pub fn kubi_main() {
Event::WindowEvent { event, .. } => match event { Event::WindowEvent { event, .. } => match event {
WindowEvent::Resized(new_size) => { WindowEvent::Resized(new_size) => {
//this can be in a system but I don't care //this can be in a system but I don't care
world.borrow::<NonSendSync<UniqueViewMut<Renderer>>>().unwrap().resize(new_size); world.borrow::<UniqueViewMut<Renderer>>().unwrap().resize(new_size);
} }
WindowEvent::CloseRequested => { WindowEvent::CloseRequested => {
log::info!("exit requested"); log::info!("exit requested");
@ -237,7 +240,7 @@ pub fn kubi_main() {
//Start rendering (maybe use custom views for this?) //Start rendering (maybe use custom views for this?)
let target = { let target = {
let renderer = world.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap(); let renderer = world.borrow::<UniqueView<Renderer>>().unwrap();
renderer.begin() renderer.begin()
}; };
world.add_unique(target); world.add_unique(target);

View file

@ -1,4 +1,4 @@
use shipyard::{Unique, View, Workload, SystemModificator, IntoWorkload}; use shipyard::{Unique, Workload, IntoWorkload, WorkloadModificator};
use winit::{ use winit::{
event_loop::EventLoop, event_loop::EventLoop,
window::{Window, WindowBuilder, Fullscreen}, window::{Window, WindowBuilder, Fullscreen},
@ -6,17 +6,18 @@ use winit::{
}; };
use glam::{Vec3, Mat4}; use glam::{Vec3, Mat4};
use pollster::FutureExt as _; use pollster::FutureExt as _;
use crate::{events::WindowResizedEvent, settings::{GameSettings, FullscreenMode}}; use crate::settings::{GameSettings, FullscreenMode};
use self::{pipelines::init_pipelines, primitives::init_primitives, shaders::compile_shaders}; use self::{primitives::init_primitives, shaders::compile_shaders, camera_uniform::init_camera_uniform};
pub mod shaders; pub mod shaders;
pub mod pipelines;
pub mod primitives; pub mod primitives;
pub mod world;
pub mod selection_box; pub mod selection_box;
pub mod entities; pub mod entities;
pub mod world;
pub mod camera_uniform;
//TODO remove this if possible
pub const OPENGL_TO_WGPU_MATRIX: Mat4 = Mat4::from_cols_array(&[ pub const OPENGL_TO_WGPU_MATRIX: Mat4 = Mat4::from_cols_array(&[
1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0,
@ -24,7 +25,6 @@ pub const OPENGL_TO_WGPU_MATRIX: Mat4 = Mat4::from_cols_array(&[
0.0, 0.0, 0.5, 1.0, 0.0, 0.0, 0.5, 1.0,
]); ]);
#[derive(Unique)] #[derive(Unique)]
pub struct RenderTarget { pub struct RenderTarget {
pub output: wgpu::SurfaceTexture, pub output: wgpu::SurfaceTexture,
@ -218,17 +218,14 @@ impl Renderer {
} }
} }
pub fn renderer_finish_init() -> Workload { /// THIS DOES NOT INIT [`Renderer`]!
pub fn init_rendering_internals() -> Workload {
( (
compile_shaders, init_camera_uniform,
init_pipelines.after_all(compile_shaders),
init_primitives, init_primitives,
compile_shaders,
(
world::init_gpu_data,
).into_workload().after_all(compile_shaders),
).into_workload() ).into_workload()
} }
#[deprecated]
pub fn if_resized (
resize: View<WindowResizedEvent>,
) -> bool {
resize.len() > 0
}

View file

@ -0,0 +1,45 @@
use shipyard::{Unique, UniqueView, AllStoragesView, View, IntoIter};
use wgpu::util::DeviceExt;
use crate::camera::Camera;
use super::{Renderer, OPENGL_TO_WGPU_MATRIX};
#[repr(C, packed)]
#[derive(Clone, Copy, Default, bytemuck::Pod, bytemuck::Zeroable)]
struct CameraUniform {
view_proj: [[f32; 4]; 4],
}
#[derive(Unique)]
pub struct CameraUniformBuffer(pub wgpu::Buffer);
pub fn init_camera_uniform(
storages: AllStoragesView
) {
let buffer = {
let renderer = storages.borrow::<UniqueView<Renderer>>().unwrap();
CameraUniformBuffer(
renderer.device.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
label: Some("CameraUniformBuffer"),
contents: bytemuck::cast_slice(&[CameraUniform::default()]),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
}
)
)
};
storages.add_unique(buffer);
}
pub fn update_camera_uniform(
renderer: UniqueView<Renderer>,
camera: View<Camera>,
buffer: UniqueView<CameraUniformBuffer>,
) {
//Just pick the first camera, if it exists, of course
let Some(camera) = camera.iter().next() else { return };
renderer.queue.write_buffer(&buffer.0, 0, bytemuck::cast_slice(&[
CameraUniform {
view_proj: (camera.perspective_matrix * camera.view_matrix * OPENGL_TO_WGPU_MATRIX).to_cols_array_2d()
}
]));
}

View file

@ -10,35 +10,34 @@ use super::shaders::Shaders;
pub fn render_entities() {} pub fn render_entities() {}
#[cfg(fuck)] // pub fn render_entities(
pub fn render_entities( // mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
mut target: NonSendSync<UniqueViewMut<RenderTarget>>, // buffers: NonSendSync<UniqueView<CenteredCubePrimitive>>,
buffers: NonSendSync<UniqueView<CenteredCubePrimitive>>, // shaders: NonSendSync<UniqueView<Shaders>>,
shaders: NonSendSync<UniqueView<Shaders>>, // camera: View<Camera>,
camera: View<Camera>, // settings: UniqueView<GameSettings>,
settings: UniqueView<GameSettings>, // entities: View<Entity>,
entities: View<Entity>, // transform: View<Transform>,
transform: View<Transform>, // ) {
) { // let (camera_id, camera) = camera.iter().with_id().next().expect("No cameras in the scene");
let (camera_id, camera) = camera.iter().with_id().next().expect("No cameras in the scene");
let draw_parameters = DrawParameters { // let draw_parameters = DrawParameters {
depth: Depth { // depth: Depth {
test: DepthTest::IfLess, // test: DepthTest::IfLess,
write: true, // write: true,
..Default::default() // ..Default::default()
}, // },
multisampling: settings.msaa.is_some(), // multisampling: settings.msaa.is_some(),
polygon_mode: PolygonMode::Fill, // polygon_mode: PolygonMode::Fill,
backface_culling: BackfaceCullingMode::CullClockwise, // backface_culling: BackfaceCullingMode::CullClockwise,
..Default::default() // ..Default::default()
}; // };
let view = camera.view_matrix.to_cols_array_2d(); // let view = camera.view_matrix.to_cols_array_2d();
let perspective = camera.perspective_matrix.to_cols_array_2d(); // let perspective = camera.perspective_matrix.to_cols_array_2d();
for (entity_id, (_, trans)) in (&entities, &transform).iter().with_id() { // for (entity_id, (_, trans)) in (&entities, &transform).iter().with_id() {
//skip rendering camera holder (as the entity would block the view) // //skip rendering camera holder (as the entity would block the view)
if entity_id == camera_id { continue } // if entity_id == camera_id { continue }
// render entity // render entity
// target.0.draw( // target.0.draw(
@ -53,5 +52,5 @@ pub fn render_entities(
// }, // },
// &draw_parameters // &draw_parameters
// ).unwrap(); // ).unwrap();
} // }
} // }

View file

@ -1,51 +0,0 @@
use shipyard::{Unique, AllStoragesView, NonSendSync, UniqueView};
use super::{shaders::Shaders, Renderer};
#[derive(Unique)]
pub struct Pipelines {
pub world: wgpu::RenderPipeline
}
pub fn init_pipelines(
storages: AllStoragesView
) {
let renderer = storages.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap();
let shaders = storages.borrow::<UniqueView<Shaders>>().unwrap();
storages.add_unique(Pipelines {
world: renderer.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("WorldRenderPipeline"),
layout: Some(&renderer.device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("WorldRenderPipelineLayout"),
bind_group_layouts: &[],
push_constant_ranges: &[],
})),
vertex: wgpu::VertexState {
module: &shaders.world,
entry_point: "vs_main",
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shaders.world,
entry_point: "fs_main",
targets: &[Some(wgpu::ColorTargetState {
format: renderer.config.format,
blend: Some(wgpu::BlendState::REPLACE),
write_mask: wgpu::ColorWrites::ALL,
})],
}),
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
polygon_mode: wgpu::PolygonMode::Fill,
unclipped_depth: false,
conservative: false,
},
//TODO enable depth buffer
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
multiview: None,
}),
})
}

View file

@ -57,7 +57,7 @@ const CUBE_INDICES: &[u16] = &[
pub(super) fn init_cube_primitive( pub(super) fn init_cube_primitive(
storages: AllStoragesView, storages: AllStoragesView,
renderer: NonSendSync<UniqueView<Renderer>> renderer: UniqueView<Renderer>
) { ) {
storages.add_unique( storages.add_unique(
CubePrimitive { CubePrimitive {

View file

@ -19,7 +19,7 @@ const RECT_INDEX: &[u16] = &[0, 1, 2, 1, 3, 2];
pub(super) fn init_rect_primitive( pub(super) fn init_rect_primitive(
storages: AllStoragesView, storages: AllStoragesView,
renderer: NonSendSync<UniqueView<Renderer>> renderer: UniqueView<Renderer>
) { ) {
let vert = renderer.device.create_buffer_init( let vert = renderer.device.create_buffer_init(
&wgpu::util::BufferInitDescriptor { &wgpu::util::BufferInitDescriptor {

View file

@ -13,42 +13,41 @@ const SMOL: f32 = 0.0001;
pub fn render_selection_box() { } pub fn render_selection_box() { }
#[cfg(fuck)] // pub fn render_selection_box(
pub fn render_selection_box( // lookat: View<LookingAtBlock>,
lookat: View<LookingAtBlock>, // camera: View<Camera>,
camera: View<Camera>, // mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
mut target: NonSendSync<UniqueViewMut<RenderTarget>>, // program: NonSendSync<UniqueView<ColoredShaderPrefab>>,
program: NonSendSync<UniqueView<ColoredShaderPrefab>>, // buffers: UniqueView<CubePrimitive>,
buffers: UniqueView<CubePrimitive>, // ) {
) { // let camera = camera.iter().next().unwrap();
let camera = camera.iter().next().unwrap(); // let Some(lookat) = lookat.iter().next() else { return };
let Some(lookat) = lookat.iter().next() else { return }; // let Some(lookat) = lookat.0 else { return };
let Some(lookat) = lookat.0 else { return };
//Darken block // //Darken block
target.0.draw( // target.0.draw(
&buffers.0, // &buffers.0,
&buffers.1, // &buffers.1,
&program.0, // &program.0,
&uniform! { // &uniform! {
color: [0., 0., 0., 0.5_f32], // color: [0., 0., 0., 0.5_f32],
model: Mat4::from_scale_rotation_translation( // model: Mat4::from_scale_rotation_translation(
Vec3::splat(1. + SMOL * 2.), // Vec3::splat(1. + SMOL * 2.),
Quat::default(), // Quat::default(),
lookat.block_position.as_vec3() - Vec3::splat(SMOL) // lookat.block_position.as_vec3() - Vec3::splat(SMOL)
).to_cols_array_2d(), // ).to_cols_array_2d(),
perspective: camera.perspective_matrix.to_cols_array_2d(), // perspective: camera.perspective_matrix.to_cols_array_2d(),
view: camera.view_matrix.to_cols_array_2d(), // view: camera.view_matrix.to_cols_array_2d(),
}, // },
&DrawParameters { // &DrawParameters {
backface_culling: BackfaceCullingMode::CullClockwise, // backface_culling: BackfaceCullingMode::CullClockwise,
blend: Blend::alpha_blending(), // blend: Blend::alpha_blending(),
depth: Depth { // depth: Depth {
//this may be unreliable... unless scale is applied! hacky... // //this may be unreliable... unless scale is applied! hacky...
test: DepthTest::IfLessOrEqual, // test: DepthTest::IfLessOrEqual,
..Default::default() // ..Default::default()
}, // },
..Default::default() // ..Default::default()
} // }
).unwrap(); // ).unwrap();
} // }

View file

@ -31,7 +31,7 @@ macro_rules! build_shaders {
pub fn compile_shaders( pub fn compile_shaders(
storages: AllStoragesView, storages: AllStoragesView,
) { ) {
let renderer = &storages.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap(); let renderer = &storages.borrow::<UniqueView<Renderer>>().unwrap();
storages.add_unique(build_shaders! { storages.add_unique(build_shaders! {
Shaders [renderer, "../../shaders"] { Shaders [renderer, "../../shaders"] {
world: "world.wgsl", world: "world.wgsl",

View file

@ -1,5 +1,5 @@
use glam::{Vec3, Mat4, Quat, ivec3}; use glam::{Vec3, Mat4, Quat, ivec3};
use shipyard::{NonSendSync, UniqueView, UniqueViewMut, View, IntoIter, track, Unique}; use shipyard::{NonSendSync, UniqueView, UniqueViewMut, View, IntoIter, track, Unique, AllStoragesView};
use wgpu::util::DeviceExt; use wgpu::util::DeviceExt;
use crate::{ use crate::{
camera::Camera, camera::Camera,
@ -12,7 +12,7 @@ use crate::{
chunk::CHUNK_SIZE, chunk::CHUNK_SIZE,
}, settings::GameSettings, }, settings::GameSettings,
}; };
use super::{RenderTarget, shaders::Shaders, Renderer}; use super::{Renderer, RenderTarget, shaders::Shaders, camera_uniform::CameraUniformBuffer};
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
@ -20,181 +20,281 @@ pub struct ChunkVertex {
pub position: [f32; 3], pub position: [f32; 3],
pub normal: [f32; 3], pub normal: [f32; 3],
pub uv: [f32; 2], pub uv: [f32; 2],
pub tex_index: u8, pub tex_index: u32,
} }
#[repr(C, packed)] #[repr(C, packed)]
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)] #[derive(Clone, Copy, Default, bytemuck::Pod, bytemuck::Zeroable)]
struct WorldUniform { struct WorldUniform {
position_offset: [f32; 3], position: [f32; 3], //XXX: should use i32?
view_proj: [[f32; 4]; 4], }
#[derive(Unique)]
struct GpuData {
pipeline: wgpu::RenderPipeline,
uniform_buffer: wgpu::Buffer,
bind_group: wgpu::BindGroup,
}
pub fn init_gpu_data(
storages: AllStoragesView,
) {
let renderer = storages.borrow::<UniqueView<Renderer>>().unwrap();
let shaders: UniqueView<'_, Shaders> = storages.borrow::<UniqueView<Shaders>>().unwrap();
let camera_uniform = storages.borrow::<UniqueView<CameraUniformBuffer>>().unwrap();
let pipeline = renderer.device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
label: Some("WorldRenderPipeline"),
layout: Some(&renderer.device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
label: Some("WorldRenderPipelineLayout"),
bind_group_layouts: &[],
push_constant_ranges: &[],
})),
vertex: wgpu::VertexState {
module: &shaders.world,
entry_point: "vs_main",
buffers: &[],
},
fragment: Some(wgpu::FragmentState {
module: &shaders.world,
entry_point: "fs_main",
targets: &[Some(wgpu::ColorTargetState {
format: renderer.config.format,
blend: Some(wgpu::BlendState::REPLACE),
write_mask: wgpu::ColorWrites::ALL,
})],
}),
primitive: wgpu::PrimitiveState {
topology: wgpu::PrimitiveTopology::TriangleList,
strip_index_format: None,
front_face: wgpu::FrontFace::Ccw,
cull_mode: Some(wgpu::Face::Back),
polygon_mode: wgpu::PolygonMode::Fill,
unclipped_depth: false,
conservative: false,
},
//TODO enable depth buffer
depth_stencil: None,
multisample: wgpu::MultisampleState::default(),
multiview: None,
});
let uniform_buffer = renderer.device.create_buffer_init(
&wgpu::util::BufferInitDescriptor {
label: Some("WorldUniformBuffer"),
contents: bytemuck::cast_slice(&[WorldUniform::default()]),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
}
);
let bind_group_layout = renderer.device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
entries: &[
wgpu::BindGroupLayoutEntry {
binding: 0,
visibility: wgpu::ShaderStages::VERTEX,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
},
wgpu::BindGroupLayoutEntry {
binding: 1,
visibility: wgpu::ShaderStages::VERTEX,
ty: wgpu::BindingType::Buffer {
ty: wgpu::BufferBindingType::Uniform,
has_dynamic_offset: false,
min_binding_size: None,
},
count: None,
}
],
label: Some("WorldBindGroupLayout"),
});
let bind_group = renderer.device.create_bind_group(&wgpu::BindGroupDescriptor {
layout: &bind_group_layout,
entries: &[
wgpu::BindGroupEntry {
binding: 0,
resource: camera_uniform.0.as_entire_binding(),
},
wgpu::BindGroupEntry {
binding: 1,
resource: uniform_buffer.as_entire_binding(),
}
],
label: Some("WorldBindGroup"),
});
storages.add_unique(GpuData { pipeline, uniform_buffer, bind_group });
} }
pub fn draw_world( pub fn draw_world(
renderer: UniqueView<Renderer>, renderer: UniqueView<Renderer>,
mut target: UniqueViewMut<RenderTarget>, mut target: UniqueViewMut<RenderTarget>,
gpu_data: UniqueView<GpuData>,
chunks: UniqueView<ChunkStorage>, chunks: UniqueView<ChunkStorage>,
meshes: UniqueView<ChunkMeshStorage>, meshes: UniqueView<ChunkMeshStorage>,
shaders: UniqueView<Shaders>, shaders: UniqueView<Shaders>,
texture: UniqueView<BlockTexturesAsset>, texture: UniqueView<BlockTexturesAsset>,
camera: View<Camera>,
settings: UniqueView<GameSettings> settings: UniqueView<GameSettings>
) { ) {
let camera = camera.iter().next().expect("No cameras in the scene");
for (&position, chunk) in &chunks.chunks { for (&position, chunk) in &chunks.chunks {
if let Some(key) = chunk.mesh_index { if let Some(key) = chunk.mesh_index {
let mesh = meshes.get(key).expect("Mesh index pointing to nothing"); let mesh = meshes.get(key).expect("Mesh index pointing to nothing");
let world_position = position.as_vec3() * CHUNK_SIZE as f32; let world_position = position.as_vec3() * CHUNK_SIZE as f32;
//TODO culling //TODO culling like in the glium version
//Draw chunk mesh //Draw chunk mesh
//TODO: i need renderpass here!
} }
} }
} }
#[cfg(fuck)]
pub fn draw_world(
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
chunks: UniqueView<ChunkStorage>,
meshes: NonSendSync<UniqueView<ChunkMeshStorage>>,
program: NonSendSync<UniqueView<ChunkShaderPrefab>>,
texture: NonSendSync<UniqueView<BlockTexturesAsset>>,
camera: View<Camera>,
settings: UniqueView<GameSettings>
) {
let camera = camera.iter().next().expect("No cameras in the scene");
let draw_parameters = DrawParameters {
depth: Depth {
test: DepthTest::IfLess,
write: true,
..Default::default()
},
multisampling: settings.msaa.is_some(),
polygon_mode: PolygonMode::Fill, //Change to Line for wireframe
backface_culling: BackfaceCullingMode::CullClockwise,
..Default::default()
};
let texture_sampler = Sampler(&texture.0, SamplerBehavior {
minify_filter: MinifySamplerFilter::LinearMipmapLinear,
magnify_filter: MagnifySamplerFilter::Nearest,
max_anisotropy: settings.max_anisotropy.unwrap_or_default(),
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 { // pub fn draw_world(
if let Some(key) = chunk.mesh_index { // mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
let mesh = meshes.get(key).expect("Mesh index pointing to nothing"); // chunks: UniqueView<ChunkStorage>,
let world_position = position.as_vec3() * CHUNK_SIZE as f32; // meshes: NonSendSync<UniqueView<ChunkMeshStorage>>,
// program: NonSendSync<UniqueView<ChunkShaderPrefab>>,
// texture: NonSendSync<UniqueView<BlockTexturesAsset>>,
// camera: View<Camera>,
// settings: UniqueView<GameSettings>
// ) {
// let camera = camera.iter().next().expect("No cameras in the scene");
// let draw_parameters = DrawParameters {
// depth: Depth {
// test: DepthTest::IfLess,
// write: true,
// ..Default::default()
// },
// multisampling: settings.msaa.is_some(),
// polygon_mode: PolygonMode::Fill, //Change to Line for wireframe
// backface_culling: BackfaceCullingMode::CullClockwise,
// ..Default::default()
// };
// let texture_sampler = Sampler(&texture.0, SamplerBehavior {
// minify_filter: MinifySamplerFilter::LinearMipmapLinear,
// magnify_filter: MagnifySamplerFilter::Nearest,
// max_anisotropy: settings.max_anisotropy.unwrap_or_default(),
// 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();
//Skip mesh if its empty // for (&position, chunk) in &chunks.chunks {
if mesh.index_buffer.len() == 0 { // if let Some(key) = chunk.mesh_index {
continue // let mesh = meshes.get(key).expect("Mesh index pointing to nothing");
} // let world_position = position.as_vec3() * CHUNK_SIZE as f32;
//Frustum culling // //Skip mesh if its empty
{ // if mesh.index_buffer.len() == 0 {
let minp = world_position; // continue
let maxp = world_position + Vec3::splat(CHUNK_SIZE as f32); // }
if !camera.frustum.is_box_visible(minp, maxp) {
continue
}
}
//Draw chunk mesh // //Frustum culling
target.0.draw( // {
&mesh.vertex_buffer, // let minp = world_position;
&mesh.index_buffer, // let maxp = world_position + Vec3::splat(CHUNK_SIZE as f32);
&program.0, // if !camera.frustum.is_box_visible(minp, maxp) {
&uniform! { // continue
position_offset: world_position.to_array(), // }
view: view, // }
perspective: perspective,
tex: texture_sampler, // //Draw chunk mesh
}, // target.0.draw(
&draw_parameters // &mesh.vertex_buffer,
).unwrap(); // &mesh.index_buffer,
} // &program.0,
} // &uniform! {
} // position_offset: world_position.to_array(),
// view: view,
// perspective: perspective,
// tex: texture_sampler,
// },
// &draw_parameters
// ).unwrap();
// }
// }
// }
pub fn draw_current_chunk_border() {} pub fn draw_current_chunk_border() {}
#[cfg(fuck)]
pub fn draw_current_chunk_border( // pub fn draw_current_chunk_border(
mut target: NonSendSync<UniqueViewMut<RenderTarget>>, // mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
player: View<MainPlayer>, // player: View<MainPlayer>,
transforms: View<Transform, track::All>, // transforms: View<Transform, track::All>,
buffers: UniqueView<CubePrimitive>, // buffers: UniqueView<CubePrimitive>,
program: NonSendSync<UniqueView<ColoredShaderPrefab>>, // program: NonSendSync<UniqueView<ColoredShaderPrefab>>,
camera: View<Camera>, // camera: View<Camera>,
settings: UniqueView<GameSettings>, // settings: UniqueView<GameSettings>,
) { // ) {
#[cfg(fuck)] { // #[cfg(fuck)] {
if cfg!(target_os = "android") { // if cfg!(target_os = "android") {
return // return
} // }
if !settings.debug_draw_current_chunk_border { // if !settings.debug_draw_current_chunk_border {
return // return
} // }
let camera = camera.iter().next().expect("No cameras in the scene"); // let camera = camera.iter().next().expect("No cameras in the scene");
let view = camera.view_matrix.to_cols_array_2d(); // let view = camera.view_matrix.to_cols_array_2d();
let perspective = camera.perspective_matrix.to_cols_array_2d(); // let perspective = camera.perspective_matrix.to_cols_array_2d();
let (_, &player_transform) = (&player, &transforms).iter().next().expect("No player"); // let (_, &player_transform) = (&player, &transforms).iter().next().expect("No player");
let (_, _, player_position) = player_transform.0.to_scale_rotation_translation(); // let (_, _, player_position) = player_transform.0.to_scale_rotation_translation();
let player_in_chunk = ivec3( // let player_in_chunk = ivec3(
(player_position.x as i32).div_euclid(CHUNK_SIZE as i32), // (player_position.x as i32).div_euclid(CHUNK_SIZE as i32),
(player_position.y as i32).div_euclid(CHUNK_SIZE as i32), // (player_position.y as i32).div_euclid(CHUNK_SIZE as i32),
(player_position.z as i32).div_euclid(CHUNK_SIZE as i32), // (player_position.z as i32).div_euclid(CHUNK_SIZE as i32),
); // );
let world_position = player_in_chunk.as_vec3() * CHUNK_SIZE as f32; // let world_position = player_in_chunk.as_vec3() * CHUNK_SIZE as f32;
target.0.draw( // target.0.draw(
&buffers.0, // &buffers.0,
&buffers.1, // &buffers.1,
&program.0, // &program.0,
&uniform! { // &uniform! {
model: Mat4::from_scale_rotation_translation( // model: Mat4::from_scale_rotation_translation(
Vec3::splat(CHUNK_SIZE as f32), // Vec3::splat(CHUNK_SIZE as f32),
Quat::default(), // Quat::default(),
world_position // world_position
).to_cols_array_2d(), // ).to_cols_array_2d(),
color: [0.25f32; 4], // color: [0.25f32; 4],
view: view, // view: view,
perspective: perspective, // perspective: perspective,
}, // },
&DrawParameters { // &DrawParameters {
depth: Depth { // depth: Depth {
test: DepthTest::IfLess, // test: DepthTest::IfLess,
..Default::default() // ..Default::default()
}, // },
blend: Blend::alpha_blending(), // blend: Blend::alpha_blending(),
..Default::default() // ..Default::default()
} // }
).unwrap(); // ).unwrap();
target.0.draw( // target.0.draw(
&buffers.0, // &buffers.0,
&buffers.1, // &buffers.1,
&program.0, // &program.0,
&uniform! { // &uniform! {
model: Mat4::from_scale_rotation_translation( // model: Mat4::from_scale_rotation_translation(
Vec3::splat(CHUNK_SIZE as f32), // Vec3::splat(CHUNK_SIZE as f32),
Quat::default(), // Quat::default(),
world_position // world_position
).to_cols_array_2d(), // ).to_cols_array_2d(),
color: [0.0f32; 4], // color: [0.0f32; 4],
view: view, // view: view,
perspective: perspective, // perspective: perspective,
}, // },
&DrawParameters { // &DrawParameters {
polygon_mode: PolygonMode::Point, // polygon_mode: PolygonMode::Point,
line_width: Some(2.), // line_width: Some(2.),
point_size: Some(5.), // point_size: Some(5.),
..Default::default() // ..Default::default()
} // }
).unwrap(); // ).unwrap();
} // }
} // }

View file

@ -91,7 +91,7 @@ pub fn update_chunks_if_player_moved(
fn unload_downgrade_chunks( fn unload_downgrade_chunks(
mut vm_world: UniqueViewMut<ChunkStorage>, mut vm_world: UniqueViewMut<ChunkStorage>,
mut vm_meshes: NonSendSync<UniqueViewMut<ChunkMeshStorage>> mut vm_meshes: UniqueViewMut<ChunkMeshStorage>
) { ) {
if !vm_world.is_modified() { if !vm_world.is_modified() {
return return
@ -184,8 +184,8 @@ fn start_required_tasks(
fn process_completed_tasks( fn process_completed_tasks(
task_manager: UniqueView<ChunkTaskManager>, task_manager: UniqueView<ChunkTaskManager>,
mut world: UniqueViewMut<ChunkStorage>, mut world: UniqueViewMut<ChunkStorage>,
mut meshes: NonSendSync<UniqueViewMut<ChunkMeshStorage>>, mut meshes: UniqueViewMut<ChunkMeshStorage>,
renderer: NonSendSync<UniqueView<Renderer>>, renderer: UniqueView<Renderer>,
state: UniqueView<GameState>, state: UniqueView<GameState>,
mut queue: UniqueViewMut<BlockUpdateQueue>, mut queue: UniqueViewMut<BlockUpdateQueue>,
) { ) {

View file

@ -65,7 +65,7 @@ pub fn generate_mesh(data: MeshGenData) -> (Vec<ChunkVertex>, Vec<u32>) {
CubeFace::Back => textures.back, CubeFace::Back => textures.back,
CubeFace::Bottom => textures.bottom, CubeFace::Bottom => textures.bottom,
}; };
builder.add_face(face, coord, face_texture as u8); builder.add_face(face, coord, face_texture as u32);
} }
} }
}, },
@ -73,14 +73,14 @@ pub fn generate_mesh(data: MeshGenData) -> (Vec<ChunkVertex>, Vec<u32>) {
builder.add_diagonal_face( builder.add_diagonal_face(
coord, coord,
DiagonalFace::LeftZ, DiagonalFace::LeftZ,
textures.0.front as u8, textures.0.front as u32,
textures.0.back as u8 textures.0.back as u32
); );
builder.add_diagonal_face( builder.add_diagonal_face(
coord, coord,
DiagonalFace::RigthZ, DiagonalFace::RigthZ,
textures.1.front as u8, textures.1.front as u32,
textures.1.back as u8 textures.1.back as u32
); );
}, },
} }

View file

@ -96,7 +96,7 @@ impl MeshBuilder {
Self::default() Self::default()
} }
pub fn add_face(&mut self, face: CubeFace, coord: IVec3, texture: u8) { pub fn add_face(&mut self, face: CubeFace, coord: IVec3, texture: u32) {
let coord = coord.as_vec3(); let coord = coord.as_vec3();
let face_index = face as usize; let face_index = face as usize;
@ -120,7 +120,7 @@ impl MeshBuilder {
self.idx_counter += 4; self.idx_counter += 4;
} }
pub fn add_diagonal_face(&mut self, coord: IVec3, face_type: DiagonalFace, front_texture: u8, back_texture: u8) { pub fn add_diagonal_face(&mut self, coord: IVec3, face_type: DiagonalFace, front_texture: u32, back_texture: u32) {
//Push vertices //Push vertices
let face_type = face_type as usize; let face_type = face_type as usize;
let vertices = CROSS_FACES[face_type]; let vertices = CROSS_FACES[face_type];