add submerge overlay back

This commit is contained in:
griffi-gh 2024-05-13 23:43:39 +02:00
parent 13ac29c9a2
commit 06e23d463b
17 changed files with 257 additions and 71 deletions

View file

@ -1 +1,14 @@
//TODO
@group(0) @binding(0)
var<uniform> color: vec4<f32>;
@vertex
fn vs_main(
@location(0) position: vec2<f32>,
) -> @builtin(position) vec4<f32> {
return vec4<f32>(position, 0.0, 1.0);
}
@fragment
fn fs_main() -> @location(0) vec4<f32> {
return color;
}

View file

@ -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")
);

View file

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

View file

@ -34,6 +34,7 @@ pub struct InstanceBuffer {
pub fn create_instance_buffer(
renderer: UniqueView<Renderer>,
) -> 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::<InstanceData>() as u64,

View file

@ -9,6 +9,8 @@ pub fn init_entities_pipeline(
prefabs: UniqueView<GpuPrefabs>,
camera_ubo: UniqueView<CameraUniformBuffer>,
) -> 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 {

View file

@ -9,6 +9,7 @@ pub use fstri::FstriPrimitive;
pub fn init_primitives() -> Workload {
(
cube::init_cube_primitive,
fstri::init_fstri_primitive,
).into_workload()
}

View file

@ -31,6 +31,7 @@ const CUBE_INDICES: &[u16] = &[
];
pub fn init_cube_primitive(storages: AllStoragesView) {
log::info!("init_cube_primitive");
let renderer = storages.borrow::<UniqueView<Renderer>>().unwrap();
storages.add_unique(CubePrimitive(BufferPair {
index: renderer.device().create_buffer_init(&wgpu::util::BufferInitDescriptor {

View file

@ -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::<UniqueView<Renderer>>().unwrap();
let buffer = renderer.device().create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("fstri_vertex_buffer"),

View file

@ -12,6 +12,8 @@ pub fn init_selection_box_pipeline(
depth: UniqueView<DepthTexture>,
camera_ubo: UniqueView<CameraUniformBuffer>,
) -> wgpu::RenderPipeline {
log::info!("init_selection_box_pipeline");
let shader = ren.device().create_shader_module(
wgpu::include_wgsl!("../../../shaders/selection_box.wgsl")
);

View file

@ -21,7 +21,11 @@ pub struct SelectionBoxUniform {
pub bind_group: wgpu::BindGroup,
}
pub fn init_selection_box_uniform(renderer: UniqueView<Renderer>) -> SelectionBoxUniform {
pub fn init_selection_box_uniform(
renderer: UniqueView<Renderer>
) -> 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::<SelectionBoxUniformData>() as u64,

View file

@ -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<SmOverlayRenderState>,
buf: UniqueView<FstriPrimitive>,
) {
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);
}

View file

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

View file

@ -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<SmUniformData>,
pub buffer: wgpu::Buffer,
pub bind_group_layout: wgpu::BindGroupLayout,
pub bind_group: wgpu::BindGroup,
}
pub fn init_sm_uniform(
renderer: UniqueView<Renderer>
) -> SmUniform {
log::info!("init_sm_uniform");
let buffer = renderer.device().create_buffer(&wgpu::BufferDescriptor {
label: Some("smoverlay_uniform"),
size: std::mem::size_of::<SmUniformData>() 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<SmOverlayRenderState>,
renderer: UniqueView<Renderer>,
plr: View<MainPlayer>,
trans: View<Transform>,
world: UniqueView<ChunkStorage>,
) {
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]),
);
}

View file

@ -1,14 +0,0 @@
pub fn create_render_pipeline(
ren: UniqueView<Renderer>,
stri_primitive: UniqueView<FstriPrimitive>,
) -> 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
}

View file

@ -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<UniqueViewMut<RenderTarget>>,
// primitive: NonSendSync<UniqueView<STriPrimitive>>,
// program: NonSendSync<UniqueView<Colored2ShaderPrefab>>,
// plr: View<MainPlayer>,
// trans: View<Transform>,
// world: UniqueView<ChunkStorage>,
// ) {
// 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();
// }

View file

@ -10,10 +10,14 @@ pub fn init_world_pipeline(
textures: UniqueView<GpuPrefabs>,
camera_ubo: UniqueView<CameraUniformBuffer>,
) -> (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),

View file

@ -11,10 +11,10 @@ pub struct FullscreenSettings {
#[derive(Unique)]
pub struct GameSettings {
pub vsync: bool,
// pub vsync: bool,
pub fullscreen: Option<FullscreenSettings>,
pub msaa: Option<u8>,
pub max_anisotropy: Option<u16>,
// pub msaa: Option<u8>,
// pub max_anisotropy: Option<u16>,
/// 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,