diff --git a/kubi/shaders/c2d.wgsl b/kubi/shaders/c2d.wgsl index 471ce88..c6fce2e 100644 --- a/kubi/shaders/c2d.wgsl +++ b/kubi/shaders/c2d.wgsl @@ -1 +1,14 @@ -//TODO +@group(0) @binding(0) +var color: vec4; + +@vertex +fn vs_main( + @location(0) position: vec2, +) -> @builtin(position) vec4 { + return vec4(position, 0.0, 1.0); +} + +@fragment +fn fs_main() -> @location(0) vec4 { + return color; +} diff --git a/kubi/src/prefabs/loader.rs b/kubi/src/prefabs/loader.rs index f32834b..ab11b32 100644 --- a/kubi/src/prefabs/loader.rs +++ b/kubi/src/prefabs/loader.rs @@ -80,6 +80,8 @@ pub fn load_texture2d_prefab( assman: &AssetManager, path: &Path, ) -> wgpu::Texture { + log::info!("loading texture2d: {path:?}"); + let image = image::load( BufReader::new(assman.open_asset(path).expect("Failed to open texture file")), image::ImageFormat::Png @@ -116,6 +118,8 @@ pub fn load_obj_prefab( assman: &AssetManager, path: &Path, ) -> BufferPair { + log::info!("loading obj prefab: {path:?}"); + let mut reader = BufReader::new( assman.open_asset(path).expect("Failed to open texture file") ); diff --git a/kubi/src/rendering.rs b/kubi/src/rendering.rs index 923e8ac..288627b 100644 --- a/kubi/src/rendering.rs +++ b/kubi/src/rendering.rs @@ -1,4 +1,4 @@ -use shipyard::{AllStoragesViewMut, IntoIter, IntoWorkload, SystemModificator, Unique, UniqueView, UniqueViewMut, View, Workload}; +use shipyard::{AllStoragesViewMut, IntoIter, IntoWorkload, SystemModificator, Unique, UniqueView, UniqueViewMut, View, Workload, WorkloadModificator}; use winit::dpi::PhysicalSize; use glam::Vec3; use crate::{events::WindowResizedEvent, hui_integration::kubi_ui_draw, state::is_ingame}; @@ -13,6 +13,7 @@ pub mod background; pub mod world; pub mod camera_uniform; pub mod depth; +pub mod smoverlay; pub struct BufferPair { pub index: wgpu::Buffer, @@ -40,6 +41,7 @@ pub fn init_rendering() -> Workload { world::init_world_render_state, //req: depth, camera entities::init_entities_render_state, //req: depth, camera selection_box::init_selection_box_render_state, //req: depth, camera, primitives + smoverlay::init_smoverlay_render_state, //req: primitives ).into_sequential_workload() } @@ -53,8 +55,11 @@ pub fn update_rendering_early() -> Workload { pub fn update_rendering_late() -> Workload { ( camera_uniform::update_camera_uniform_buffer, - selection_box::update_selection_box_render_state.run_if(is_ingame), - entities::update_entities_render_state.run_if(is_ingame), + ( + selection_box::update_selection_box_render_state, + entities::update_entities_render_state, + smoverlay::update_smoverlay_render_state, + ).into_workload().run_if(is_ingame), ).into_workload() } @@ -78,6 +83,7 @@ pub fn render_master(storages: AllStoragesViewMut) { storages.run_with_data(selection_box::draw_selection_box, &mut data); storages.run_with_data(entities::render_entities, &mut data); storages.run_with_data(world::rpass_submit_trans_bundle, &mut data); + storages.run_with_data(smoverlay::render_submerged_view, &mut data); } storages.run_with_data(kubi_ui_draw, &mut data); diff --git a/kubi/src/rendering/entities/instance.rs b/kubi/src/rendering/entities/instance.rs index 271949a..6ad7226 100644 --- a/kubi/src/rendering/entities/instance.rs +++ b/kubi/src/rendering/entities/instance.rs @@ -34,6 +34,7 @@ pub struct InstanceBuffer { pub fn create_instance_buffer( renderer: UniqueView, ) -> InstanceBuffer { + log::info!("entities: create_instance_buffer"); let buffer = renderer.device().create_buffer(&wgpu::BufferDescriptor { label: Some("instance_buffer"), size: 255 * std::mem::size_of::() as u64, diff --git a/kubi/src/rendering/entities/pipeline.rs b/kubi/src/rendering/entities/pipeline.rs index b7e8e42..bacc587 100644 --- a/kubi/src/rendering/entities/pipeline.rs +++ b/kubi/src/rendering/entities/pipeline.rs @@ -9,6 +9,8 @@ pub fn init_entities_pipeline( prefabs: UniqueView, camera_ubo: UniqueView, ) -> wgpu::RenderPipeline { + log::info!("init_entities_pipeline"); + let module = renderer.device().create_shader_module(include_wgsl!("../../../shaders/entities.wgsl")); let pipeline_layout = renderer.device().create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { diff --git a/kubi/src/rendering/primitives.rs b/kubi/src/rendering/primitives.rs index 05ef112..457bace 100644 --- a/kubi/src/rendering/primitives.rs +++ b/kubi/src/rendering/primitives.rs @@ -9,6 +9,7 @@ pub use fstri::FstriPrimitive; pub fn init_primitives() -> Workload { ( cube::init_cube_primitive, + fstri::init_fstri_primitive, ).into_workload() } diff --git a/kubi/src/rendering/primitives/cube.rs b/kubi/src/rendering/primitives/cube.rs index 3abd3e2..ff74e96 100644 --- a/kubi/src/rendering/primitives/cube.rs +++ b/kubi/src/rendering/primitives/cube.rs @@ -31,6 +31,7 @@ const CUBE_INDICES: &[u16] = &[ ]; pub fn init_cube_primitive(storages: AllStoragesView) { + log::info!("init_cube_primitive"); let renderer = storages.borrow::>().unwrap(); storages.add_unique(CubePrimitive(BufferPair { index: renderer.device().create_buffer_init(&wgpu::util::BufferInitDescriptor { diff --git a/kubi/src/rendering/primitives/fstri.rs b/kubi/src/rendering/primitives/fstri.rs index b6eb26d..7e22d5f 100644 --- a/kubi/src/rendering/primitives/fstri.rs +++ b/kubi/src/rendering/primitives/fstri.rs @@ -4,16 +4,16 @@ use crate::rendering::Renderer; use super::PrimitiveVertex2; pub const FSTRI_VERTICES: &[PrimitiveVertex2] = &[ - PrimitiveVertex2 { position: [0.0, 0.0] }, - PrimitiveVertex2 { position: [1.0, 0.0] }, - PrimitiveVertex2 { position: [0.0, 1.0] }, - PrimitiveVertex2 { position: [1.0, 1.0] }, + PrimitiveVertex2 { position: [-1.0, -1.0] }, + PrimitiveVertex2 { position: [ 3.0, -1.0] }, + PrimitiveVertex2 { position: [-1.0, 3.0] }, ]; #[derive(Unique)] -pub struct FstriPrimitive(wgpu::Buffer); +pub struct FstriPrimitive(pub wgpu::Buffer); pub fn init_fstri_primitive(storages: AllStoragesView) { + log::info!("init_fstri_primitive"); let renderer = storages.borrow::>().unwrap(); let buffer = renderer.device().create_buffer_init(&wgpu::util::BufferInitDescriptor { label: Some("fstri_vertex_buffer"), diff --git a/kubi/src/rendering/selection_box/pipeline.rs b/kubi/src/rendering/selection_box/pipeline.rs index 352ce83..ab15dcd 100644 --- a/kubi/src/rendering/selection_box/pipeline.rs +++ b/kubi/src/rendering/selection_box/pipeline.rs @@ -12,6 +12,8 @@ pub fn init_selection_box_pipeline( depth: UniqueView, camera_ubo: UniqueView, ) -> wgpu::RenderPipeline { + log::info!("init_selection_box_pipeline"); + let shader = ren.device().create_shader_module( wgpu::include_wgsl!("../../../shaders/selection_box.wgsl") ); diff --git a/kubi/src/rendering/selection_box/uniform.rs b/kubi/src/rendering/selection_box/uniform.rs index 8ee8f5e..cf551ad 100644 --- a/kubi/src/rendering/selection_box/uniform.rs +++ b/kubi/src/rendering/selection_box/uniform.rs @@ -21,7 +21,11 @@ pub struct SelectionBoxUniform { pub bind_group: wgpu::BindGroup, } -pub fn init_selection_box_uniform(renderer: UniqueView) -> SelectionBoxUniform { +pub fn init_selection_box_uniform( + renderer: UniqueView +) -> SelectionBoxUniform { + log::info!("init_selection_box_uniform"); + let buffer = renderer.device().create_buffer(&wgpu::BufferDescriptor { label: Some("selection_box_uniform"), size: std::mem::size_of::() as u64, diff --git a/kubi/src/rendering/smoverlay.rs b/kubi/src/rendering/smoverlay.rs new file mode 100644 index 0000000..e0e66fc --- /dev/null +++ b/kubi/src/rendering/smoverlay.rs @@ -0,0 +1,48 @@ +use shipyard::{AllStoragesView, Unique, UniqueView}; +use super::{primitives::FstriPrimitive, RenderCtx, Renderer}; + +mod uniform; +mod pipeline; +use uniform::SmUniform; + +#[derive(Unique)] +pub struct SmOverlayRenderState { + pub uniform: SmUniform, + pub pipeline: wgpu::RenderPipeline, +} + +pub fn init_smoverlay_render_state(storages: AllStoragesView) { + let uniform = storages.run(uniform::init_sm_uniform); + let pipeline = storages.run_with_data(pipeline::init_smoverlay_pipeline, &uniform); + storages.add_unique(SmOverlayRenderState { uniform, pipeline }); +} + +pub use uniform::update_sm_uniform as update_smoverlay_render_state; + +pub fn render_submerged_view( + ctx: &mut RenderCtx, + state: UniqueView, + buf: UniqueView, +) { + if state.uniform.stored_data.is_none() { return } + + let mut rpass = ctx.encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("smoverlay_render_pass"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: ctx.surface_view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Load, + store: wgpu::StoreOp::Store, + }, + })], + depth_stencil_attachment: None, + timestamp_writes: None, + occlusion_query_set: None, + }); + + rpass.set_pipeline(&state.pipeline); + rpass.set_bind_group(0, &state.uniform.bind_group, &[]); + rpass.set_vertex_buffer(0, buf.0.slice(..)); + rpass.draw(0..3, 0..1); +} diff --git a/kubi/src/rendering/smoverlay/pipeline.rs b/kubi/src/rendering/smoverlay/pipeline.rs new file mode 100644 index 0000000..df35e3e --- /dev/null +++ b/kubi/src/rendering/smoverlay/pipeline.rs @@ -0,0 +1,57 @@ +use shipyard::UniqueView; +use crate::rendering::{primitives::PrimitiveVertex2, Renderer}; +use super::uniform::SmUniform; + +pub fn init_smoverlay_pipeline( + uniform: &SmUniform, + renderer: UniqueView +) -> wgpu::RenderPipeline { + let module = renderer.device().create_shader_module( + wgpu::include_wgsl!("../../../shaders/c2d.wgsl") + ); + + let rp_layout = renderer.device().create_pipeline_layout( + &wgpu::PipelineLayoutDescriptor { + label: Some("smoverlay_pipeline_layout"), + bind_group_layouts: &[ + &uniform.bind_group_layout, + ], + push_constant_ranges: &[], + } + ); + + renderer.device().create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("smoverlay_pipeline"), + layout: Some(&rp_layout), + vertex: wgpu::VertexState { + module: &module, + compilation_options: wgpu::PipelineCompilationOptions::default(), + entry_point: "vs_main", + buffers: &[ + PrimitiveVertex2::LAYOUT, + ], + }, + fragment: Some(wgpu::FragmentState { + module: &module, + compilation_options: wgpu::PipelineCompilationOptions::default(), + entry_point: "fs_main", + targets: &[Some(wgpu::ColorTargetState { + format: renderer.surface_config().format, + blend: Some(wgpu::BlendState::ALPHA_BLENDING), + 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, + conservative: false, + unclipped_depth: false, + }, + depth_stencil: None, + multisample: wgpu::MultisampleState::default(), + multiview: None, + }) +} diff --git a/kubi/src/rendering/smoverlay/uniform.rs b/kubi/src/rendering/smoverlay/uniform.rs new file mode 100644 index 0000000..c859739 --- /dev/null +++ b/kubi/src/rendering/smoverlay/uniform.rs @@ -0,0 +1,94 @@ +use bytemuck::{Pod, Zeroable}; +use kubi_shared::transform::Transform; +use shipyard::{IntoIter, UniqueView, UniqueViewMut, View}; +use crate::{player::MainPlayer, rendering::Renderer, world::ChunkStorage}; +use super::SmOverlayRenderState; + +#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)] +#[repr(C, packed)] +pub struct SmUniformData { + pub color: [f32; 4], +} + +pub struct SmUniform { + pub stored_data: Option, + pub buffer: wgpu::Buffer, + pub bind_group_layout: wgpu::BindGroupLayout, + pub bind_group: wgpu::BindGroup, +} + +pub fn init_sm_uniform( + renderer: UniqueView +) -> SmUniform { + log::info!("init_sm_uniform"); + + let buffer = renderer.device().create_buffer(&wgpu::BufferDescriptor { + label: Some("smoverlay_uniform"), + size: std::mem::size_of::() as u64, + usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + mapped_at_creation: false, + }); + + let bind_group_layout = renderer.device().create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("smoverlay_bind_group_layout"), + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + count: None, + }], + }); + + let bind_group = renderer.device().create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("smoverlay_bind_group"), + layout: &bind_group_layout, + entries: &[wgpu::BindGroupEntry { + binding: 0, + resource: buffer.as_entire_binding(), + }], + }); + + SmUniform { + stored_data: None, + buffer, + bind_group_layout, + bind_group, + } +} + +pub fn update_sm_uniform( + mut state: UniqueViewMut, + renderer: UniqueView, + plr: View, + trans: View, + world: UniqueView, +) { + state.uniform.stored_data = None; + + let (_, plr_trans) = (&plr, &trans).iter().next().expect("Main player MIA"); + let plr_pos = plr_trans.0.to_scale_rotation_translation().2; + let block_at_pos = world.get_block(plr_pos.floor().as_ivec3()); + let Some(block_at_pos) = block_at_pos else { return }; + let Some(color) = block_at_pos.descriptor().submerge else { return }; + + let new_data = SmUniformData { + color: color.to_array() + }; + + if state.uniform.stored_data == Some(new_data) { + return + } + state.uniform.stored_data = Some(new_data); + + log::debug!("update_sm_uniform: {:?}", new_data); + + renderer.queue().write_buffer( + &state.uniform.buffer, + 0, + bytemuck::cast_slice(&[new_data]), + ); +} diff --git a/kubi/src/rendering/submerge/pipeline.rs b/kubi/src/rendering/submerge/pipeline.rs deleted file mode 100644 index 0bcd41a..0000000 --- a/kubi/src/rendering/submerge/pipeline.rs +++ /dev/null @@ -1,14 +0,0 @@ -pub fn create_render_pipeline( - ren: UniqueView, - stri_primitive: UniqueView, -) -> wgpu::RenderPipeline { - let shader = ren.device().create_shader_module( - wgpu::include_wgsl!("../../../shaders/c2d.wgsl") - ); - let pipeline_layout = ren.device().create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: Some("smoverlay_pipeline_layout"), - bind_group_layouts: &[&ren.bind_group_layout], - push_constant_ranges: &[], - }); - //TODO -} diff --git a/kubi/src/rendering/sumberge.rs b/kubi/src/rendering/sumberge.rs deleted file mode 100644 index 89eebb0..0000000 --- a/kubi/src/rendering/sumberge.rs +++ /dev/null @@ -1,41 +0,0 @@ -mod pipeline; - -// use glium::{uniform, Blend, DrawParameters, Surface}; -// use kubi_shared::transform::Transform; -// use shipyard::{IntoIter, NonSendSync, UniqueView, UniqueViewMut, View}; -// use crate::{ -// player::MainPlayer, -// prefabs::Colored2ShaderPrefab, -// rendering::primitives::stri::STriPrimitive, -// world::ChunkStorage, -// }; -// use super::RenderTarget; - -// pub fn render_submerged_view( -// mut target: NonSendSync>, -// primitive: NonSendSync>, -// program: NonSendSync>, -// plr: View, -// trans: View, -// world: UniqueView, -// ) { -// let (_, plr_trans) = (&plr, &trans).iter().next().expect("Main player MIA"); -// let plr_pos = plr_trans.0.to_scale_rotation_translation().2; -// let block_at_pos = world.get_block(plr_pos.floor().as_ivec3()); -// let Some(block_at_pos) = block_at_pos else { return }; -// let Some(color) = block_at_pos.descriptor().submerge else { return }; - -// let draw_parameters = DrawParameters { -// blend: Blend::alpha_blending(), -// ..Default::default() -// }; -// target.0.draw( -// &primitive.0, -// &primitive.1, -// &program.0, -// &uniform! { -// color: color.to_array(), -// }, -// &draw_parameters, -// ).unwrap(); -// } diff --git a/kubi/src/rendering/world/pipeline.rs b/kubi/src/rendering/world/pipeline.rs index 692cb7c..6d960c6 100644 --- a/kubi/src/rendering/world/pipeline.rs +++ b/kubi/src/rendering/world/pipeline.rs @@ -10,10 +10,14 @@ pub fn init_world_pipeline( textures: UniqueView, camera_ubo: UniqueView, ) -> (wgpu::RenderPipeline, wgpu::RenderPipeline) { + log::info!("init_world_pipeline: creating shader module"); + let shader = ren.device().create_shader_module( wgpu::include_wgsl!("../../../shaders/world.wgsl") ); + log::info!("init_world_pipeline: creating pipeline layout"); + let world_pipeline_layout = ren.device().create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("world_pipeline_layout"), bind_group_layouts: &[ @@ -23,6 +27,8 @@ pub fn init_world_pipeline( push_constant_ranges: &[], }); + log::info!("init_world_pipeline: create main pipeline"); + let pipeline_main = ren.device().create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("world_pipeline"), layout: Some(&world_pipeline_layout), @@ -64,6 +70,8 @@ pub fn init_world_pipeline( multiview: None, }); + log::info!("init_world_pipeline: create trans pipeline"); + let pipeline_trans = ren.device().create_render_pipeline(&wgpu::RenderPipelineDescriptor { label: Some("world_pipeline_trans"), layout: Some(&world_pipeline_layout), diff --git a/kubi/src/settings.rs b/kubi/src/settings.rs index a0abbbe..9a83be3 100644 --- a/kubi/src/settings.rs +++ b/kubi/src/settings.rs @@ -11,10 +11,10 @@ pub struct FullscreenSettings { #[derive(Unique)] pub struct GameSettings { - pub vsync: bool, + // pub vsync: bool, pub fullscreen: Option, - pub msaa: Option, - pub max_anisotropy: Option, + // pub msaa: Option, + // pub max_anisotropy: Option, /// there's a 1 chunk border of loaded but invisible around this pub render_distance: u8, pub mouse_sensitivity: f32, @@ -24,10 +24,10 @@ pub struct GameSettings { impl Default for GameSettings { fn default() -> Self { Self { - vsync: false, + // vsync: false, fullscreen: None, - msaa: Some(4), - max_anisotropy: Some(16), + // msaa: Some(4), + // max_anisotropy: Some(16), render_distance: match true { cfg!(debug_assertions) => 5, cfg!(target_os = "android") => 6,