mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-22 14:58:44 -06:00
Compare commits
12 commits
3f768a8318
...
99cc2d1e72
Author | SHA1 | Date | |
---|---|---|---|
griffi-gh | 99cc2d1e72 | ||
griffi-gh | 85c64c9064 | ||
griffi-gh | 6e9e3fa445 | ||
griffi-gh | 8a4549efea | ||
griffi-gh | 6f25cb728f | ||
griffi-gh | 9a01ecd6f2 | ||
griffi-gh | 8fd1930ce6 | ||
griffi-gh | 674ec97a6e | ||
griffi-gh | f04542ac02 | ||
griffi-gh | dd386acea1 | ||
griffi-gh | d14b5e1b40 | ||
griffi-gh | f4e4886d33 |
|
@ -9,7 +9,7 @@ pub fn init() {
|
||||||
use env_logger::{fmt::Color, Builder, Env};
|
use env_logger::{fmt::Color, Builder, Env};
|
||||||
|
|
||||||
let env = Env::default()
|
let env = Env::default()
|
||||||
.filter_or("RUST_LOG", "trace,gilrs=warn,rusty_xinput=warn,wgpu=warn,wgpu_core=warn,wgpu_hal=warn,hui=info,hui-winit=info,hui-glium=info,hui-wgpu=info");
|
.filter_or("RUST_LOG", "trace,gilrs=warn,rusty_xinput=warn,wgpu=warn,wgpu_core=warn,wgpu_hal=warn,hui=info,hui-winit=info,hui-glium=info,hui-wgpu=info,naga=warn");
|
||||||
Builder::from_env(env)
|
Builder::from_env(env)
|
||||||
.format(|buf, record| {
|
.format(|buf, record| {
|
||||||
let mut level_style = buf.style();
|
let mut level_style = buf.style();
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use fastnoise_lite::FastNoiseLite;
|
|
||||||
use glam::ivec3;
|
use glam::ivec3;
|
||||||
use crate::{block::Block, chunk::CHUNK_SIZE, worldgen::SeedThingy};
|
use crate::{block::Block, chunk::CHUNK_SIZE, worldgen::SeedThingy};
|
||||||
use super::{
|
use super::{
|
||||||
|
|
|
@ -1,23 +1,22 @@
|
||||||
// struct Uniforms {
|
struct CameraUniform {
|
||||||
// transform: mat4x4<f32>;
|
view_proj: mat4x4<f32>,
|
||||||
// };
|
};
|
||||||
|
|
||||||
// @group(1) @binding(0)
|
@group(1) @binding(0)
|
||||||
// var<uniform> uniforms: Uniforms;
|
var<uniform> camera: CameraUniform;
|
||||||
|
|
||||||
struct VertexInput {
|
struct VertexInput {
|
||||||
@location(0) position: vec3<f32>,
|
@location(0) position: vec3<f32>,
|
||||||
@location(1) normal: vec3<f32>,
|
@location(1) normal: vec3<f32>,
|
||||||
@location(2) uv: vec2<f32>,
|
@location(2) uv: vec2<f32>,
|
||||||
@location(3) @interpolate(flat) tex_index: u32,
|
@location(3) tex_index: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VertexOutput {
|
struct VertexOutput {
|
||||||
@builtin(position) clip_position: vec4<f32>,
|
@builtin(position) clip_position: vec4<f32>,
|
||||||
@location(0) uv: vec2<f32>,
|
@location(0) uv: vec2<f32>,
|
||||||
@location(1) normal: vec3<f32>,
|
@location(1) normal: vec3<f32>,
|
||||||
@location(2) color: vec4<f32>,
|
@location(2) @interpolate(flat)tex_index: u32,
|
||||||
@location(3) @interpolate(flat) tex_index: u32,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@vertex
|
@vertex
|
||||||
|
@ -26,7 +25,9 @@ fn vs_main(
|
||||||
) -> VertexOutput {
|
) -> VertexOutput {
|
||||||
var out: VertexOutput;
|
var out: VertexOutput;
|
||||||
out.uv = in.uv;
|
out.uv = in.uv;
|
||||||
out.clip_position = vec4<f32>(in.position, 1.0);
|
out.normal = in.normal;
|
||||||
|
out.tex_index = in.tex_index;
|
||||||
|
out.clip_position = camera.view_proj * vec4<f32>(in.position, 1.0);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,5 +39,9 @@ var s_diffuse: sampler;
|
||||||
|
|
||||||
@fragment
|
@fragment
|
||||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||||
return textureSample(t_diffuse, s_diffuse, in.uv, in.tex_index);
|
let color: vec4<f32> = textureSample(t_diffuse, s_diffuse, in.uv, in.tex_index);
|
||||||
|
if (color.a == 0.) {
|
||||||
|
discard;
|
||||||
|
}
|
||||||
|
return color;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use glam::{Vec3, Mat4};
|
use glam::{Vec3, Mat4};
|
||||||
use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload, track, UniqueView, SystemModificator};
|
use shipyard::{ViewMut, View, IntoIter, Workload, IntoWorkload, track, UniqueView, SystemModificator};
|
||||||
use crate::{transform::Transform, rendering::WindowSize, events::WindowResizedEvent};
|
use crate::{transform::Transform, rendering::Renderer, events::WindowResizedEvent};
|
||||||
use super::Camera;
|
use super::Camera;
|
||||||
|
|
||||||
//maybe parallelize these two?
|
//maybe parallelize these two?
|
||||||
|
@ -18,12 +18,13 @@ fn update_view_matrix(
|
||||||
|
|
||||||
fn update_perspective_matrix(
|
fn update_perspective_matrix(
|
||||||
mut vm_camera: ViewMut<Camera>,
|
mut vm_camera: ViewMut<Camera>,
|
||||||
size: UniqueView<WindowSize>,
|
ren: UniqueView<Renderer>,
|
||||||
) {
|
) {
|
||||||
|
let sz = ren.size_vec2();
|
||||||
for mut camera in (&mut vm_camera).iter() {
|
for mut camera in (&mut vm_camera).iter() {
|
||||||
camera.perspective_matrix = Mat4::perspective_rh_gl(
|
camera.perspective_matrix = Mat4::perspective_rh(
|
||||||
camera.fov,
|
camera.fov,
|
||||||
size.0.x as f32 / size.0.y as f32,
|
sz.x / sz.y,
|
||||||
camera.z_near,
|
camera.z_near,
|
||||||
camera.z_far,
|
camera.z_far,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use kubi_shared::networking::client::ClientId;
|
use kubi_shared::networking::client::ClientId;
|
||||||
use shipyard::{AllStoragesView, Unique, UniqueViewMut};
|
use shipyard::{AllStoragesView, Unique};
|
||||||
|
|
||||||
pub enum ChatMessage {
|
pub enum ChatMessage {
|
||||||
PlayerMessage {
|
PlayerMessage {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//TODO client-side physics
|
//TODO client-side physics
|
||||||
//TODO move this to shared
|
//TODO move this to shared
|
||||||
use glam::{vec3, IVec3, Mat4, Vec3, Vec3Swizzles};
|
use glam::{vec3, Mat4, Vec3, Vec3Swizzles};
|
||||||
use shipyard::{track, AllStoragesView, Component, IntoIter, Unique, UniqueView, View, ViewMut};
|
use shipyard::{track, AllStoragesView, Component, IntoIter, Unique, UniqueView, ViewMut};
|
||||||
use kubi_shared::{block::{Block, CollisionType}, transform::Transform};
|
use kubi_shared::{block::{Block, CollisionType}, transform::Transform};
|
||||||
use crate::{delta_time::DeltaTime, world::ChunkStorage};
|
use crate::{delta_time::DeltaTime, world::ChunkStorage};
|
||||||
|
|
||||||
|
|
|
@ -86,18 +86,18 @@ pub fn process_winit_events(world: &mut World, event: &Event<()>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initial_resize_event(
|
// pub fn initial_resize_event(
|
||||||
mut storages: AllStoragesViewMut,
|
// mut storages: AllStoragesViewMut,
|
||||||
) {
|
// ) {
|
||||||
let (w, h) = {
|
// let (w, h) = {
|
||||||
let renderer = storages.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap();
|
// let renderer = storages.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap();
|
||||||
(renderer.size().width, renderer.size().height)
|
// (renderer.size().width, renderer.size().height)
|
||||||
};
|
// };
|
||||||
storages.add_entity((
|
// storages.add_entity((
|
||||||
EventComponent,
|
// EventComponent,
|
||||||
WindowResizedEvent(UVec2::new(w, h))
|
// WindowResizedEvent(UVec2::new(w, h))
|
||||||
));
|
// ));
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn clear_events(
|
pub fn clear_events(
|
||||||
mut all_storages: AllStoragesViewMut,
|
mut all_storages: AllStoragesViewMut,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use hui::UiInstance;
|
use hui::UiInstance;
|
||||||
//use hui_glium::GliumUiRenderer;
|
//use hui_glium::GliumUiRenderer;
|
||||||
use shipyard::{AllStoragesView, Unique, UniqueView, NonSendSync, UniqueViewMut};
|
use shipyard::{AllStoragesView, Unique, UniqueView, NonSendSync, UniqueViewMut};
|
||||||
use crate::rendering::{Renderer, WindowSize};
|
use crate::rendering::Renderer;
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
pub struct UiState {
|
pub struct UiState {
|
||||||
|
|
|
@ -10,7 +10,7 @@ use nohash_hasher::BuildNoHashHasher;
|
||||||
use shipyard::{AllStoragesView, Unique, View, IntoIter, UniqueViewMut, Workload, IntoWorkload, UniqueView, NonSendSync};
|
use shipyard::{AllStoragesView, Unique, View, IntoIter, UniqueViewMut, Workload, IntoWorkload, UniqueView, NonSendSync};
|
||||||
use crate::{
|
use crate::{
|
||||||
events::{InputDeviceEvent, TouchEvent},
|
events::{InputDeviceEvent, TouchEvent},
|
||||||
rendering::WindowSize
|
rendering::Renderer,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Unique, Clone, Copy, Default, Debug)]
|
#[derive(Unique, Clone, Copy, Default, Debug)]
|
||||||
|
@ -211,10 +211,10 @@ fn update_input_state_gamepad (
|
||||||
|
|
||||||
fn update_input_state_touch (
|
fn update_input_state_touch (
|
||||||
touch_state: UniqueView<RawTouchState>,
|
touch_state: UniqueView<RawTouchState>,
|
||||||
win_size: UniqueView<WindowSize>,
|
renderer: UniqueView<Renderer>,
|
||||||
mut inputs: UniqueViewMut<Inputs>,
|
mut inputs: UniqueViewMut<Inputs>,
|
||||||
) {
|
) {
|
||||||
let w = win_size.0.as_dvec2();
|
let w = renderer.size_uvec2().as_dvec2();
|
||||||
|
|
||||||
//Movement
|
//Movement
|
||||||
if let Some(finger) = touch_state.query_area(
|
if let Some(finger) = touch_state.query_area(
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
use shipyard::{
|
use shipyard::{
|
||||||
World, Workload, IntoWorkload,
|
World, Workload, IntoWorkload,
|
||||||
UniqueView, UniqueViewMut,
|
UniqueView, UniqueViewMut,
|
||||||
NonSendSync, WorkloadModificator,
|
WorkloadModificator,
|
||||||
SystemModificator
|
SystemModificator
|
||||||
};
|
};
|
||||||
use winit::{
|
use winit::{
|
||||||
|
@ -67,22 +67,10 @@ use player::{spawn_player, MainPlayer};
|
||||||
use prefabs::load_prefabs;
|
use prefabs::load_prefabs;
|
||||||
use settings::{load_settings, GameSettings};
|
use settings::{load_settings, GameSettings};
|
||||||
use camera::compute_cameras;
|
use camera::compute_cameras;
|
||||||
use events::{
|
use events::{clear_events, process_winit_events, player_actions::generate_move_events};
|
||||||
clear_events,
|
|
||||||
process_winit_events,
|
|
||||||
initial_resize_event,
|
|
||||||
player_actions::generate_move_events,
|
|
||||||
};
|
|
||||||
use input::{init_input, process_inputs};
|
use input::{init_input, process_inputs};
|
||||||
use player_controller::{debug_switch_ctl_type, update_player_controllers};
|
use player_controller::{debug_switch_ctl_type, update_player_controllers};
|
||||||
// use rendering::{
|
use rendering::{BackgroundColor, Renderer, init_rendering, render_master, update_rendering_early, update_rendering_late};
|
||||||
// clear_background, entities::render_entities, init_window_size, primitives::init_primitives, resize_renderer, selection_box::render_selection_box, sumberge::render_submerged_view, update_window_size, world::{draw_current_chunk_border, draw_world, draw_world_trans, init_trans_chunk_queue}, BackgroundColor, RenderTarget, Renderer
|
|
||||||
// };
|
|
||||||
use rendering::{
|
|
||||||
init_window_size, render_master, resize_renderer, update_window_size,
|
|
||||||
world::{init_trans_chunk_queue, TransChunkQueue},
|
|
||||||
BackgroundColor, Renderer,
|
|
||||||
};
|
|
||||||
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};
|
||||||
use cursor_lock::{debug_toggle_lock, insert_lock_state, lock_cursor_now, update_cursor_lock_state};
|
use cursor_lock::{debug_toggle_lock, insert_lock_state, lock_cursor_now, update_cursor_lock_state};
|
||||||
|
@ -112,11 +100,9 @@ fn pre_startup() -> Workload {
|
||||||
fn startup() -> Workload {
|
fn startup() -> Workload {
|
||||||
(
|
(
|
||||||
init_fixed_timestamp_storage,
|
init_fixed_timestamp_storage,
|
||||||
initial_resize_event,
|
|
||||||
init_window_size,
|
|
||||||
kubi_ui_init,
|
kubi_ui_init,
|
||||||
load_prefabs,
|
load_prefabs,
|
||||||
//init_primitives,
|
init_rendering,
|
||||||
insert_lock_state,
|
insert_lock_state,
|
||||||
init_state,
|
init_state,
|
||||||
initialize_from_args,
|
initialize_from_args,
|
||||||
|
@ -132,14 +118,12 @@ fn startup() -> Workload {
|
||||||
|
|
||||||
fn update() -> Workload {
|
fn update() -> Workload {
|
||||||
(
|
(
|
||||||
|
update_rendering_early,
|
||||||
debug_toggle_lock,
|
debug_toggle_lock,
|
||||||
update_window_size,
|
|
||||||
resize_renderer,
|
|
||||||
update_cursor_lock_state,
|
update_cursor_lock_state,
|
||||||
process_inputs,
|
process_inputs,
|
||||||
kubi_ui_begin,
|
kubi_ui_begin,
|
||||||
(
|
(
|
||||||
init_trans_chunk_queue.run_if_missing_unique::<TransChunkQueue>(),
|
|
||||||
init_game_world.run_if_missing_unique::<ChunkTaskManager>(),
|
init_game_world.run_if_missing_unique::<ChunkTaskManager>(),
|
||||||
(
|
(
|
||||||
spawn_player.run_if_storage_empty::<MainPlayer>(),
|
spawn_player.run_if_storage_empty::<MainPlayer>(),
|
||||||
|
@ -174,6 +158,7 @@ fn update() -> Workload {
|
||||||
update_state,
|
update_state,
|
||||||
exit_on_esc,
|
exit_on_esc,
|
||||||
disconnect_on_exit.run_if(is_multiplayer),
|
disconnect_on_exit.run_if(is_multiplayer),
|
||||||
|
update_rendering_late,
|
||||||
).into_sequential_workload()
|
).into_sequential_workload()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +177,7 @@ fn update() -> Workload {
|
||||||
// ).into_sequential_workload()
|
// ).into_sequential_workload()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
fn after_frame_end() -> Workload {
|
fn after_render() -> Workload {
|
||||||
(
|
(
|
||||||
clear_events,
|
clear_events,
|
||||||
).into_sequential_workload()
|
).into_sequential_workload()
|
||||||
|
@ -241,7 +226,7 @@ pub fn kubi_main(
|
||||||
world.add_workload(startup);
|
world.add_workload(startup);
|
||||||
world.add_workload(update);
|
world.add_workload(update);
|
||||||
//world.add_workload(render);
|
//world.add_workload(render);
|
||||||
world.add_workload(after_frame_end);
|
world.add_workload(after_render);
|
||||||
|
|
||||||
//Save _visualizer.json
|
//Save _visualizer.json
|
||||||
#[cfg(feature = "generate_visualizer_data")]
|
#[cfg(feature = "generate_visualizer_data")]
|
||||||
|
@ -338,7 +323,7 @@ pub fn kubi_main(
|
||||||
// target.0.finish().unwrap();
|
// target.0.finish().unwrap();
|
||||||
|
|
||||||
//After frame end
|
//After frame end
|
||||||
world.run_workload(after_frame_end).unwrap();
|
world.run_workload(after_render).unwrap();
|
||||||
|
|
||||||
//Process control flow changes
|
//Process control flow changes
|
||||||
if world.borrow::<UniqueView<RequestExit>>().unwrap().0 {
|
if world.borrow::<UniqueView<RequestExit>>().unwrap().0 {
|
||||||
|
|
|
@ -38,6 +38,7 @@ impl AssetPaths for BlockTexture {
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
pub struct TexturePrefabs {
|
pub struct TexturePrefabs {
|
||||||
pub block_diffuse_texture: wgpu::Texture,
|
pub block_diffuse_texture: wgpu::Texture,
|
||||||
|
pub block_diffuse_bind_group_layout: wgpu::BindGroupLayout,
|
||||||
pub block_diffuse_bind_group: wgpu::BindGroup,
|
pub block_diffuse_bind_group: wgpu::BindGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,8 +60,12 @@ pub fn load_prefabs(
|
||||||
);
|
);
|
||||||
|
|
||||||
log::info!("Creating bing groups");
|
log::info!("Creating bing groups");
|
||||||
let block_diffuse_view = block_diffuse_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
let block_diffuse_view = block_diffuse_texture.create_view(&wgpu::TextureViewDescriptor {
|
||||||
|
label: Some("block_texture_view"),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
let block_diffuse_sampler = renderer.device().create_sampler(&wgpu::SamplerDescriptor {
|
let block_diffuse_sampler = renderer.device().create_sampler(&wgpu::SamplerDescriptor {
|
||||||
|
label: Some("block_diffuse_sampler"),
|
||||||
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
||||||
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
||||||
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||||
|
@ -107,6 +112,7 @@ pub fn load_prefabs(
|
||||||
});
|
});
|
||||||
storages.add_unique_non_send_sync(TexturePrefabs {
|
storages.add_unique_non_send_sync(TexturePrefabs {
|
||||||
block_diffuse_texture,
|
block_diffuse_texture,
|
||||||
|
block_diffuse_bind_group_layout,
|
||||||
block_diffuse_bind_group,
|
block_diffuse_bind_group,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
use shipyard::{AllStoragesView, AllStoragesViewMut, IntoIter, Unique, UniqueView, UniqueViewMut, View};
|
use shipyard::{AllStoragesViewMut, IntoIter, IntoWorkload, SystemModificator, Unique, UniqueView, UniqueViewMut, View, Workload, WorkloadModificator};
|
||||||
use winit::dpi::PhysicalSize;
|
use winit::dpi::PhysicalSize;
|
||||||
use glam::{Vec3, UVec2};
|
use glam::Vec3;
|
||||||
use crate::{events::WindowResizedEvent, state::is_ingame};
|
use crate::{events::WindowResizedEvent, state::is_ingame};
|
||||||
|
|
||||||
mod renderer;
|
mod renderer;
|
||||||
pub use renderer::Renderer;
|
pub use renderer::Renderer;
|
||||||
|
|
||||||
pub mod primitives;
|
use self::{camera::CameraUniformBuffer, world::WorldRenderState};
|
||||||
|
|
||||||
pub mod world;
|
pub mod world;
|
||||||
pub mod selection_box;
|
pub mod camera;
|
||||||
pub mod entities;
|
pub mod depth;
|
||||||
pub mod sumberge;
|
|
||||||
|
|
||||||
pub struct BufferPair {
|
pub struct BufferPair {
|
||||||
pub index: wgpu::Buffer,
|
pub index: wgpu::Buffer,
|
||||||
|
@ -28,6 +28,27 @@ pub struct RenderCtx<'a> {
|
||||||
pub surface_view: &'a wgpu::TextureView,
|
pub surface_view: &'a wgpu::TextureView,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn init_rendering() -> Workload {
|
||||||
|
(
|
||||||
|
depth::init_depth_texture,
|
||||||
|
camera::init_camera_uniform_buffer,
|
||||||
|
world::init_world_render_state, //TODO run only once ingame
|
||||||
|
).into_sequential_workload()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_rendering_early() -> Workload {
|
||||||
|
(
|
||||||
|
resize_renderer,
|
||||||
|
depth::resize_depth_texture,
|
||||||
|
).into_sequential_workload()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_rendering_late() -> Workload {
|
||||||
|
(
|
||||||
|
camera::update_camera_uniform_buffer,
|
||||||
|
).into_workload()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn render_master(storages: AllStoragesViewMut) {
|
pub fn render_master(storages: AllStoragesViewMut) {
|
||||||
let renderer = storages.borrow::<UniqueView<Renderer>>().unwrap();
|
let renderer = storages.borrow::<UniqueView<Renderer>>().unwrap();
|
||||||
|
|
||||||
|
@ -85,25 +106,25 @@ pub fn resize_renderer(
|
||||||
|
|
||||||
//Deprecated WindowSize thingy
|
//Deprecated WindowSize thingy
|
||||||
|
|
||||||
#[derive(Unique, Clone, Copy)]
|
// #[derive(Unique, Clone, Copy)]
|
||||||
#[repr(transparent)]
|
// #[repr(transparent)]
|
||||||
#[deprecated = "use Renderer.size instead"]
|
// #[deprecated = "use Renderer.size instead"]
|
||||||
#[allow(deprecated)]
|
// #[allow(deprecated)]
|
||||||
pub struct WindowSize(pub UVec2);
|
// pub struct WindowSize(pub UVec2);
|
||||||
|
|
||||||
pub fn init_window_size(storages: AllStoragesView) {
|
// pub fn init_window_size(storages: AllStoragesView) {
|
||||||
let size = storages.borrow::<View<WindowResizedEvent>>().unwrap().iter().next().unwrap().0;
|
// let size = storages.borrow::<View<WindowResizedEvent>>().unwrap().iter().next().unwrap().0;
|
||||||
storages.add_unique(WindowSize(size))
|
// storages.add_unique(WindowSize(size))
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn update_window_size(
|
// pub fn update_window_size(
|
||||||
mut win_size: UniqueViewMut<WindowSize>,
|
// mut win_size: UniqueViewMut<WindowSize>,
|
||||||
resize: View<WindowResizedEvent>,
|
// resize: View<WindowResizedEvent>,
|
||||||
) {
|
// ) {
|
||||||
if let Some(resize) = resize.iter().next() {
|
// if let Some(resize) = resize.iter().next() {
|
||||||
win_size.0 = resize.0;
|
// win_size.0 = resize.0;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// pub fn if_resized (
|
// pub fn if_resized (
|
||||||
// resize: View<WindowResizedEvent>,
|
// resize: View<WindowResizedEvent>,
|
||||||
|
|
83
kubi/src/rendering/camera.rs
Normal file
83
kubi/src/rendering/camera.rs
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
use kubi_shared::transform::Transform;
|
||||||
|
use shipyard::{AllStoragesView, IntoIter, Unique, UniqueView, View};
|
||||||
|
use wgpu::util::DeviceExt;
|
||||||
|
use crate::camera::{self, Camera};
|
||||||
|
use super::Renderer;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy, Default, Pod, Zeroable)]
|
||||||
|
#[repr(C, packed)]
|
||||||
|
pub struct CameraUniformData {
|
||||||
|
pub view_proj: [f32; 4 * 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//TODO if multiple cameras, buffer per camera
|
||||||
|
#[derive(Unique)]
|
||||||
|
pub struct CameraUniformBuffer {
|
||||||
|
pub camera_uniform_buffer: wgpu::Buffer,
|
||||||
|
pub camera_bind_group_layout: wgpu::BindGroupLayout,
|
||||||
|
pub camera_bind_group: wgpu::BindGroup,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CameraUniformBuffer {
|
||||||
|
pub fn init(renderer: &Renderer, data: CameraUniformData) -> Self {
|
||||||
|
let camera_uniform_buffer = renderer.device().create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||||
|
label: Some("camera_uniform_buffer"),
|
||||||
|
contents: bytemuck::cast_slice(&[data]),
|
||||||
|
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
|
||||||
|
});
|
||||||
|
|
||||||
|
let camera_bind_group_layout = renderer.device().create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||||
|
label: Some("camera_bind_group_layout"),
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
let camera_bind_group = renderer.device().create_bind_group(&wgpu::BindGroupDescriptor {
|
||||||
|
label: Some("camera_bind_group"),
|
||||||
|
layout: &camera_bind_group_layout,
|
||||||
|
entries: &[
|
||||||
|
wgpu::BindGroupEntry {
|
||||||
|
binding: 0,
|
||||||
|
resource: camera_uniform_buffer.as_entire_binding(),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
Self { camera_uniform_buffer, camera_bind_group_layout, camera_bind_group }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_default(renderer: &Renderer) -> Self {
|
||||||
|
Self::init(renderer, CameraUniformData::default())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&self, renderer: &Renderer, data: CameraUniformData) {
|
||||||
|
renderer.queue().write_buffer(&self.camera_uniform_buffer, 0, bytemuck::cast_slice(&[data]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_camera_uniform_buffer(storages: AllStoragesView) {
|
||||||
|
let renderer = storages.borrow::<UniqueView<Renderer>>().unwrap();
|
||||||
|
storages.add_unique(CameraUniformBuffer::init_default(&renderer));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_camera_uniform_buffer(
|
||||||
|
renderer: UniqueView<Renderer>,
|
||||||
|
camera_uniform_buffer: UniqueView<CameraUniformBuffer>,
|
||||||
|
camera: View<Camera>,
|
||||||
|
) {
|
||||||
|
let Some(camera) = camera.iter().next() else { return };
|
||||||
|
let proj = camera.perspective_matrix * camera.view_matrix;
|
||||||
|
camera_uniform_buffer.update(&renderer, CameraUniformData { view_proj: proj.to_cols_array() });
|
||||||
|
}
|
72
kubi/src/rendering/depth.rs
Normal file
72
kubi/src/rendering/depth.rs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
use glam::{uvec2, UVec2};
|
||||||
|
use shipyard::{AllStoragesView, Unique, UniqueView, UniqueViewMut};
|
||||||
|
|
||||||
|
use super::Renderer;
|
||||||
|
|
||||||
|
#[derive(Unique)]
|
||||||
|
pub struct DepthTexture {
|
||||||
|
pub depth_texture: wgpu::Texture,
|
||||||
|
pub depth_view: wgpu::TextureView,
|
||||||
|
pub depth_sampler: wgpu::Sampler,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DepthTexture {
|
||||||
|
fn desc(size: UVec2) -> wgpu::TextureDescriptor<'static> {
|
||||||
|
wgpu::TextureDescriptor {
|
||||||
|
label: Some("depth_texture"),
|
||||||
|
size: wgpu::Extent3d {
|
||||||
|
width: size.x,
|
||||||
|
height: size.y,
|
||||||
|
depth_or_array_layers: 1,
|
||||||
|
},
|
||||||
|
mip_level_count: 1,
|
||||||
|
sample_count: 1,
|
||||||
|
dimension: wgpu::TextureDimension::D2,
|
||||||
|
format: wgpu::TextureFormat::Depth32Float,
|
||||||
|
usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING,
|
||||||
|
view_formats: &[wgpu::TextureFormat::Depth32Float],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(renderer: &Renderer) -> Self {
|
||||||
|
let size = uvec2(renderer.size().width, renderer.size().height);
|
||||||
|
let depth_texture_desc = Self::desc(size);
|
||||||
|
let depth_texture = renderer.device().create_texture(&depth_texture_desc);
|
||||||
|
let depth_view = depth_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
let depth_sampler = renderer.device().create_sampler(&wgpu::SamplerDescriptor {
|
||||||
|
label: Some("depth_sampler"),
|
||||||
|
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
||||||
|
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
||||||
|
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||||
|
mag_filter: wgpu::FilterMode::Nearest,
|
||||||
|
min_filter: wgpu::FilterMode::Nearest,
|
||||||
|
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||||
|
compare: Some(wgpu::CompareFunction::LessEqual),
|
||||||
|
..Default::default()
|
||||||
|
});
|
||||||
|
Self { depth_texture, depth_view, depth_sampler }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resize(&mut self, renderer: &Renderer) {
|
||||||
|
let old_size = uvec2(self.depth_texture.size().width, self.depth_texture.size().height);
|
||||||
|
let new_size = uvec2(renderer.size().width, renderer.size().height);
|
||||||
|
if old_size == new_size { return }
|
||||||
|
let depth_texture_desc = Self::desc(new_size);
|
||||||
|
self.depth_texture = renderer.device().create_texture(&depth_texture_desc);
|
||||||
|
self.depth_view = self.depth_texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init_depth_texture(
|
||||||
|
storages: AllStoragesView,
|
||||||
|
) {
|
||||||
|
let renderer = storages.borrow::<UniqueView<Renderer>>().unwrap();
|
||||||
|
storages.add_unique(DepthTexture::init(&renderer));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn resize_depth_texture(
|
||||||
|
mut depth_texture: UniqueViewMut<DepthTexture>,
|
||||||
|
renderer: UniqueView<Renderer>,
|
||||||
|
) {
|
||||||
|
depth_texture.resize(&renderer);
|
||||||
|
}
|
|
@ -75,7 +75,7 @@ impl Renderer {
|
||||||
let size = window.inner_size();
|
let size = window.inner_size();
|
||||||
|
|
||||||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
|
||||||
backends: wgpu::Backends::BROWSER_WEBGPU | wgpu::Backends::VULKAN | wgpu::Backends::GL,
|
backends: wgpu::Backends::all(),
|
||||||
//Disable validation layer
|
//Disable validation layer
|
||||||
flags: wgpu::InstanceFlags::default() & !wgpu::InstanceFlags::VALIDATION,
|
flags: wgpu::InstanceFlags::default() & !wgpu::InstanceFlags::VALIDATION,
|
||||||
//we're using vulkan on windows
|
//we're using vulkan on windows
|
||||||
|
@ -143,6 +143,14 @@ impl Renderer {
|
||||||
self.size
|
self.size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn size_uvec2(&self) -> glam::UVec2 {
|
||||||
|
glam::UVec2::new(self.size.width, self.size.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn size_vec2(&self) -> glam::Vec2 {
|
||||||
|
glam::Vec2::new(self.size.width as f32, self.size.height as f32)
|
||||||
|
}
|
||||||
|
|
||||||
pub fn window(&self) -> &Window {
|
pub fn window(&self) -> &Window {
|
||||||
&self.window
|
&self.window
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,57 +1,43 @@
|
||||||
use bytemuck::{Pod, Zeroable};
|
|
||||||
use glam::{IVec3, Vec3};
|
use glam::{IVec3, Vec3};
|
||||||
use shipyard::{AllStoragesView, IntoIter, NonSendSync, Unique, UniqueView, UniqueViewMut, View};
|
use shipyard::{AllStoragesView, IntoIter, NonSendSync, Unique, UniqueView, UniqueViewMut, View};
|
||||||
use kubi_shared::{chunk::CHUNK_SIZE, transform::Transform};
|
use kubi_shared::{chunk::CHUNK_SIZE, transform::Transform};
|
||||||
use wgpu::util::RenderEncoder;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
camera::Camera,
|
camera::Camera,
|
||||||
prefabs::TexturePrefabs,
|
prefabs::TexturePrefabs,
|
||||||
settings::GameSettings,
|
settings::GameSettings,
|
||||||
world::{ChunkMeshStorage, ChunkStorage},
|
world::{ChunkMeshStorage, ChunkStorage},
|
||||||
};
|
};
|
||||||
use super::{RenderCtx, Renderer};
|
use super::{camera::{self, CameraUniformBuffer}, depth::DepthTexture, RenderCtx};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
mod pipeline;
|
||||||
#[repr(C, packed)]
|
mod vertex;
|
||||||
pub struct ChunkVertex {
|
pub use vertex::ChunkVertex;
|
||||||
pub position: [f32; 3],
|
|
||||||
pub normal: [f32; 3],
|
|
||||||
pub uv: [f32; 2],
|
|
||||||
pub tex_index: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ChunkVertex {
|
|
||||||
pub const LAYOUT: wgpu::VertexBufferLayout<'static> = wgpu::VertexBufferLayout {
|
|
||||||
array_stride: std::mem::size_of::<ChunkVertex>() as wgpu::BufferAddress,
|
|
||||||
step_mode: wgpu::VertexStepMode::Vertex,
|
|
||||||
attributes: &wgpu::vertex_attr_array![
|
|
||||||
0 => Float32x3,
|
|
||||||
1 => Float32x3,
|
|
||||||
2 => Float32x2,
|
|
||||||
3 => Uint32,
|
|
||||||
],
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Unique)]
|
#[derive(Unique)]
|
||||||
pub struct TransChunkQueue(pub Vec<IVec3>);
|
pub struct WorldRenderState {
|
||||||
|
pub pipeline: wgpu::RenderPipeline,
|
||||||
|
pub trans_chunk_queue: Vec<IVec3>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init_trans_chunk_queue(storages: AllStoragesView) {
|
pub fn init_world_render_state(storages: AllStoragesView) {
|
||||||
storages.add_unique(TransChunkQueue(Vec::with_capacity(512)));
|
storages.add_unique(WorldRenderState {
|
||||||
|
pipeline: storages.run(pipeline::init_world_pipeline),
|
||||||
|
trans_chunk_queue: Vec::with_capacity(512),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_world(
|
pub fn draw_world(
|
||||||
ctx: &mut RenderCtx,
|
ctx: &mut RenderCtx,
|
||||||
|
mut state: UniqueViewMut<WorldRenderState>,
|
||||||
|
camera_ubo: UniqueView<CameraUniformBuffer>,
|
||||||
|
depth: UniqueView<DepthTexture>,
|
||||||
textures: UniqueView<TexturePrefabs>,
|
textures: UniqueView<TexturePrefabs>,
|
||||||
|
camera: View<Camera>,
|
||||||
chunks: UniqueView<ChunkStorage>,
|
chunks: UniqueView<ChunkStorage>,
|
||||||
meshes: NonSendSync<UniqueView<ChunkMeshStorage>>,
|
meshes: NonSendSync<UniqueView<ChunkMeshStorage>>,
|
||||||
transform: View<Transform>,
|
//settings: UniqueView<GameSettings>,
|
||||||
camera: View<Camera>,
|
|
||||||
settings: UniqueView<GameSettings>,
|
|
||||||
mut trans_queue: UniqueViewMut<TransChunkQueue>,
|
|
||||||
) {
|
) {
|
||||||
let camera = camera.iter().next().expect("No cameras in the scene");
|
let camera = camera.iter().next().expect("No cameras in the scene");
|
||||||
let camera_matrix = camera.view_matrix * camera.perspective_matrix;
|
|
||||||
|
|
||||||
let mut render_pass = ctx.encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
let mut render_pass = ctx.encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
label: Some("draw_world"),
|
label: Some("draw_world"),
|
||||||
|
@ -63,9 +49,21 @@ pub fn draw_world(
|
||||||
store: wgpu::StoreOp::Store,
|
store: wgpu::StoreOp::Store,
|
||||||
},
|
},
|
||||||
})],
|
})],
|
||||||
|
depth_stencil_attachment: Some(wgpu::RenderPassDepthStencilAttachment {
|
||||||
|
view: &depth.depth_view,
|
||||||
|
depth_ops: Some(wgpu::Operations {
|
||||||
|
load: wgpu::LoadOp::Clear(1.0),
|
||||||
|
store: wgpu::StoreOp::Store,
|
||||||
|
}),
|
||||||
|
stencil_ops: None,
|
||||||
|
}),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
});
|
});
|
||||||
|
|
||||||
|
render_pass.set_pipeline(&state.pipeline);
|
||||||
|
render_pass.set_bind_group(0, &textures.block_diffuse_bind_group, &[]);
|
||||||
|
render_pass.set_bind_group(1, &camera_ubo.camera_bind_group, &[]);
|
||||||
|
|
||||||
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");
|
||||||
|
@ -85,10 +83,8 @@ pub fn draw_world(
|
||||||
|
|
||||||
//Draw chunk mesh
|
//Draw chunk mesh
|
||||||
if mesh.main.index.size() > 0 {
|
if mesh.main.index.size() > 0 {
|
||||||
//TODO
|
|
||||||
render_pass.set_index_buffer(mesh.main.index.slice(..), wgpu::IndexFormat::Uint32);
|
render_pass.set_index_buffer(mesh.main.index.slice(..), wgpu::IndexFormat::Uint32);
|
||||||
render_pass.set_vertex_buffer(0, mesh.main.vertex.slice(..));
|
render_pass.set_vertex_buffer(0, mesh.main.vertex.slice(..));
|
||||||
render_pass.set_bind_group(0, &textures.block_diffuse_bind_group, &[]);
|
|
||||||
render_pass.draw_indexed(0..mesh.main.index_len, 0, 0..1);
|
render_pass.draw_indexed(0..mesh.main.index_len, 0, 0..1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
66
kubi/src/rendering/world/pipeline.rs
Normal file
66
kubi/src/rendering/world/pipeline.rs
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
use shipyard::UniqueView;
|
||||||
|
use crate::{
|
||||||
|
prefabs::TexturePrefabs,
|
||||||
|
rendering::{camera::CameraUniformBuffer, depth::DepthTexture, world::ChunkVertex, Renderer}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn init_world_pipeline(
|
||||||
|
ren: UniqueView<Renderer>,
|
||||||
|
depth: UniqueView<DepthTexture>,
|
||||||
|
textures: UniqueView<TexturePrefabs>,
|
||||||
|
camera_ubo: UniqueView<CameraUniformBuffer>,
|
||||||
|
) -> wgpu::RenderPipeline {
|
||||||
|
let shader = ren.device().create_shader_module(
|
||||||
|
wgpu::include_wgsl!("../../../shaders/world.wgsl")
|
||||||
|
);
|
||||||
|
|
||||||
|
let world_pipeline_layout = ren.device().create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||||
|
label: Some("world_pipeline_layout"),
|
||||||
|
bind_group_layouts: &[
|
||||||
|
&textures.block_diffuse_bind_group_layout,
|
||||||
|
&camera_ubo.camera_bind_group_layout,
|
||||||
|
],
|
||||||
|
push_constant_ranges: &[],
|
||||||
|
});
|
||||||
|
|
||||||
|
ren.device().create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||||
|
label: Some("world_pipeline"),
|
||||||
|
layout: Some(&world_pipeline_layout),
|
||||||
|
fragment: Some(wgpu::FragmentState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: "fs_main",
|
||||||
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
|
targets: &[Some(wgpu::ColorTargetState {
|
||||||
|
format: ren.surface_config().format,
|
||||||
|
blend: Some(wgpu::BlendState::REPLACE),
|
||||||
|
write_mask: wgpu::ColorWrites::ALL,
|
||||||
|
})],
|
||||||
|
}),
|
||||||
|
vertex: wgpu::VertexState {
|
||||||
|
module: &shader,
|
||||||
|
entry_point: "vs_main",
|
||||||
|
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||||
|
buffers: &[
|
||||||
|
ChunkVertex::LAYOUT,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
primitive: wgpu::PrimitiveState {
|
||||||
|
topology: wgpu::PrimitiveTopology::TriangleList,
|
||||||
|
strip_index_format: None,
|
||||||
|
cull_mode: Some(wgpu::Face::Back),
|
||||||
|
front_face: wgpu::FrontFace::Ccw,
|
||||||
|
unclipped_depth: false,
|
||||||
|
polygon_mode: wgpu::PolygonMode::Fill,
|
||||||
|
conservative: false,
|
||||||
|
},
|
||||||
|
depth_stencil: Some(wgpu::DepthStencilState {
|
||||||
|
format: depth.depth_texture.format(),
|
||||||
|
depth_write_enabled: true,
|
||||||
|
depth_compare: wgpu::CompareFunction::Less,
|
||||||
|
stencil: wgpu::StencilState::default(),
|
||||||
|
bias: wgpu::DepthBiasState::default(),
|
||||||
|
}),
|
||||||
|
multisample: wgpu::MultisampleState::default(),
|
||||||
|
multiview: None,
|
||||||
|
})
|
||||||
|
}
|
23
kubi/src/rendering/world/vertex.rs
Normal file
23
kubi/src/rendering/world/vertex.rs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
use bytemuck::{Pod, Zeroable};
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||||
|
#[repr(C, packed)]
|
||||||
|
pub struct ChunkVertex {
|
||||||
|
pub position: [f32; 3],
|
||||||
|
pub normal: [f32; 3],
|
||||||
|
pub uv: [f32; 2],
|
||||||
|
pub tex_index: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChunkVertex {
|
||||||
|
pub const LAYOUT: wgpu::VertexBufferLayout<'static> = wgpu::VertexBufferLayout {
|
||||||
|
array_stride: std::mem::size_of::<ChunkVertex>() as wgpu::BufferAddress,
|
||||||
|
step_mode: wgpu::VertexStepMode::Vertex,
|
||||||
|
attributes: &wgpu::vertex_attr_array![
|
||||||
|
0 => Float32x3,
|
||||||
|
1 => Float32x3,
|
||||||
|
2 => Float32x2,
|
||||||
|
3 => Uint32,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,10 +1,10 @@
|
||||||
use hui::{color, element::{container::Container, text::Text, UiElementExt}, layout::Alignment, size};
|
use hui::{color, element::{container::Container, text::Text, UiElementExt}, layout::Alignment, size};
|
||||||
use shipyard::{NonSendSync, UniqueView, UniqueViewMut};
|
use shipyard::{NonSendSync, UniqueView, UniqueViewMut};
|
||||||
use crate::{chat::{ChatHistory, ChatMessage}, hui_integration::UiState, rendering::WindowSize};
|
use crate::{chat::{ChatHistory, ChatMessage}, hui_integration::UiState, rendering::Renderer};
|
||||||
|
|
||||||
pub fn render_chat(
|
pub fn render_chat(
|
||||||
mut hui: NonSendSync<UniqueViewMut<UiState>>,
|
mut hui: NonSendSync<UniqueViewMut<UiState>>,
|
||||||
size: UniqueView<WindowSize>,
|
ren: UniqueView<Renderer>,
|
||||||
chat: UniqueView<ChatHistory>,
|
chat: UniqueView<ChatHistory>,
|
||||||
) {
|
) {
|
||||||
let messages = chat.get_messages();
|
let messages = chat.get_messages();
|
||||||
|
@ -39,5 +39,5 @@ pub fn render_chat(
|
||||||
.add_child(ui);
|
.add_child(ui);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.add_root(&mut hui.hui, size.0.as_vec2());
|
.add_root(&mut hui.hui, ren.size_vec2());
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
||||||
hui_integration::UiState,
|
hui_integration::UiState,
|
||||||
loading_screen::loading_screen_base,
|
loading_screen::loading_screen_base,
|
||||||
networking::{ConnectionRejectionReason, ServerAddress},
|
networking::{ConnectionRejectionReason, ServerAddress},
|
||||||
rendering::WindowSize,
|
rendering::Renderer,
|
||||||
state::{GameState, NextState}
|
state::{GameState, NextState}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ fn render_connecting_ui(
|
||||||
rejection: Option<UniqueView<ConnectionRejectionReason>>,
|
rejection: Option<UniqueView<ConnectionRejectionReason>>,
|
||||||
join_state: UniqueView<ClientJoinState>,
|
join_state: UniqueView<ClientJoinState>,
|
||||||
mut ui: NonSendSync<UniqueViewMut<UiState>>,
|
mut ui: NonSendSync<UniqueViewMut<UiState>>,
|
||||||
size: UniqueView<WindowSize>,
|
ren: UniqueView<Renderer>,
|
||||||
) {
|
) {
|
||||||
let text = match (rejection, *join_state) {
|
let text = match (rejection, *join_state) {
|
||||||
(Some(err), _) => {
|
(Some(err), _) => {
|
||||||
|
@ -32,7 +32,7 @@ fn render_connecting_ui(
|
||||||
Text::new(text)
|
Text::new(text)
|
||||||
.with_text_size(16)
|
.with_text_size(16)
|
||||||
.add_child(ui);
|
.add_child(ui);
|
||||||
}).add_root(&mut ui.hui, size.0.as_vec2())
|
}).add_root(&mut ui.hui, ren.size_vec2())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn switch_to_loading_if_connected(
|
fn switch_to_loading_if_connected(
|
||||||
|
|
|
@ -6,7 +6,7 @@ use hui::{
|
||||||
size
|
size
|
||||||
};
|
};
|
||||||
use shipyard::{AllStoragesViewMut, IntoIter, NonSendSync, Unique, UniqueView, UniqueViewMut, View};
|
use shipyard::{AllStoragesViewMut, IntoIter, NonSendSync, Unique, UniqueView, UniqueViewMut, View};
|
||||||
use crate::{hui_integration::UiState, player::MainPlayer, rendering::WindowSize, settings::GameSettings, world::raycast::LookingAtBlock};
|
use crate::{hui_integration::UiState, player::MainPlayer, rendering::Renderer, settings::GameSettings, world::raycast::LookingAtBlock};
|
||||||
|
|
||||||
const CROSSHAIR_SIZE: usize = 9;
|
const CROSSHAIR_SIZE: usize = 9;
|
||||||
const CROSSHAIR: &[u8] = &[
|
const CROSSHAIR: &[u8] = &[
|
||||||
|
@ -45,7 +45,7 @@ pub fn init_crosshair_image(storages: AllStoragesViewMut) {
|
||||||
pub fn draw_crosshair(
|
pub fn draw_crosshair(
|
||||||
mut ui: NonSendSync<UniqueViewMut<UiState>>,
|
mut ui: NonSendSync<UniqueViewMut<UiState>>,
|
||||||
crosshair: UniqueView<CrosshairImage>,
|
crosshair: UniqueView<CrosshairImage>,
|
||||||
size: UniqueView<WindowSize>,
|
ren: UniqueView<Renderer>,
|
||||||
player: View<MainPlayer>,
|
player: View<MainPlayer>,
|
||||||
raycast: View<LookingAtBlock>,
|
raycast: View<LookingAtBlock>,
|
||||||
settings: UniqueView<GameSettings>,
|
settings: UniqueView<GameSettings>,
|
||||||
|
@ -57,6 +57,9 @@ pub fn draw_crosshair(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let size = ren.size_uvec2();
|
||||||
|
let size_rounded = uvec2(size.x & !1, size.y & !1).as_vec2();
|
||||||
|
|
||||||
Container::default()
|
Container::default()
|
||||||
.with_size(size!(100%))
|
.with_size(size!(100%))
|
||||||
.with_align(Alignment::Center)
|
.with_align(Alignment::Center)
|
||||||
|
@ -66,5 +69,5 @@ pub fn draw_crosshair(
|
||||||
.with_size(size!((CROSSHAIR_SIZE * 2)))
|
.with_size(size!((CROSSHAIR_SIZE * 2)))
|
||||||
.add_child(ui);
|
.add_child(ui);
|
||||||
})
|
})
|
||||||
.add_root(&mut ui.hui, uvec2(size.0.x & !1, size.0.y & !1).as_vec2());
|
.add_root(&mut ui.hui, size_rounded);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ use crate::{
|
||||||
hui_integration::UiState,
|
hui_integration::UiState,
|
||||||
input::RawKbmInputState,
|
input::RawKbmInputState,
|
||||||
networking::ServerAddress,
|
networking::ServerAddress,
|
||||||
rendering::WindowSize,
|
rendering::Renderer,
|
||||||
state::{GameState, NextState},
|
state::{GameState, NextState},
|
||||||
world::ChunkStorage,
|
world::ChunkStorage,
|
||||||
};
|
};
|
||||||
|
@ -43,7 +43,7 @@ fn render_loading_ui(
|
||||||
addr: Option<UniqueView<ServerAddress>>,
|
addr: Option<UniqueView<ServerAddress>>,
|
||||||
world: UniqueView<ChunkStorage>,
|
world: UniqueView<ChunkStorage>,
|
||||||
mut ui: NonSendSync<UniqueViewMut<UiState>>,
|
mut ui: NonSendSync<UniqueViewMut<UiState>>,
|
||||||
size: UniqueView<WindowSize>
|
ren: UniqueView<Renderer>,
|
||||||
) {
|
) {
|
||||||
let loaded = world.chunks.iter().fold(0, |acc, (&_, chunk)| {
|
let loaded = world.chunks.iter().fold(0, |acc, (&_, chunk)| {
|
||||||
acc + chunk.desired_state.matches_current(chunk.current_state) as usize
|
acc + chunk.desired_state.matches_current(chunk.current_state) as usize
|
||||||
|
@ -83,7 +83,7 @@ fn render_loading_ui(
|
||||||
.add_child(ui)
|
.add_child(ui)
|
||||||
})
|
})
|
||||||
.add_child(ui);
|
.add_child(ui);
|
||||||
}).add_root(&mut ui.hui, size.0.as_vec2());
|
}).add_root(&mut ui.hui, ren.size_vec2());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn switch_to_ingame_if_loaded(
|
fn switch_to_ingame_if_loaded(
|
||||||
|
|
|
@ -6,7 +6,7 @@ use hui::{
|
||||||
};
|
};
|
||||||
use shipyard::{NonSendSync, UniqueView, UniqueViewMut};
|
use shipyard::{NonSendSync, UniqueView, UniqueViewMut};
|
||||||
use winit::keyboard::KeyCode;
|
use winit::keyboard::KeyCode;
|
||||||
use crate::{hui_integration::UiState, input::RawKbmInputState, rendering::WindowSize, settings::GameSettings};
|
use crate::{hui_integration::UiState, input::RawKbmInputState, rendering::Renderer, settings::GameSettings};
|
||||||
|
|
||||||
#[derive(Signal)]
|
#[derive(Signal)]
|
||||||
enum SettingsSignal {
|
enum SettingsSignal {
|
||||||
|
@ -18,7 +18,7 @@ enum SettingsSignal {
|
||||||
|
|
||||||
pub fn render_settings_ui(
|
pub fn render_settings_ui(
|
||||||
mut ui: NonSendSync<UniqueViewMut<UiState>>,
|
mut ui: NonSendSync<UniqueViewMut<UiState>>,
|
||||||
size: UniqueView<WindowSize>,
|
ren: UniqueView<Renderer>,
|
||||||
mut settings: UniqueViewMut<GameSettings>,
|
mut settings: UniqueViewMut<GameSettings>,
|
||||||
kbd: UniqueView<RawKbmInputState>,
|
kbd: UniqueView<RawKbmInputState>,
|
||||||
) {
|
) {
|
||||||
|
@ -99,7 +99,7 @@ pub fn render_settings_ui(
|
||||||
})
|
})
|
||||||
.add_child(ui);
|
.add_child(ui);
|
||||||
})
|
})
|
||||||
.add_root(&mut ui.hui, size.0.as_vec2());
|
.add_root(&mut ui.hui, ren.size_vec2());
|
||||||
|
|
||||||
ui.hui.process_signals(|signal: SettingsSignal| match signal {
|
ui.hui.process_signals(|signal: SettingsSignal| match signal {
|
||||||
SettingsSignal::SetRenderDistance(value) => settings.render_distance = value,
|
SettingsSignal::SetRenderDistance(value) => settings.render_distance = value,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use glam::{IVec3, ivec3};
|
use glam::{ivec3, IVec3, Vec3};
|
||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
use kubi_shared::block::{Block, RenderType, Transparency};
|
use kubi_shared::block::{Block, RenderType, Transparency};
|
||||||
use crate::world::chunk::CHUNK_SIZE;
|
use crate::world::chunk::CHUNK_SIZE;
|
||||||
|
@ -10,7 +10,7 @@ mod builder;
|
||||||
use data::MeshGenData;
|
use data::MeshGenData;
|
||||||
use builder::{MeshBuilder, CubeFace, DiagonalFace};
|
use builder::{MeshBuilder, CubeFace, DiagonalFace};
|
||||||
|
|
||||||
pub fn generate_mesh(data: MeshGenData) -> (
|
pub fn generate_mesh(position: IVec3, data: MeshGenData) -> (
|
||||||
(Vec<ChunkVertex>, Vec<u32>),
|
(Vec<ChunkVertex>, Vec<u32>),
|
||||||
(Vec<ChunkVertex>, Vec<u32>),
|
(Vec<ChunkVertex>, Vec<u32>),
|
||||||
) {
|
) {
|
||||||
|
@ -32,7 +32,7 @@ pub fn generate_mesh(data: MeshGenData) -> (
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut builder = MeshBuilder::new();
|
let mut builder = MeshBuilder::new_with_offset((position * CHUNK_SIZE as i32).as_vec3());
|
||||||
let mut trans_builder = MeshBuilder::new();
|
let mut trans_builder = MeshBuilder::new();
|
||||||
|
|
||||||
for x in 0..CHUNK_SIZE as i32 {
|
for x in 0..CHUNK_SIZE as i32 {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use strum::EnumIter;
|
use strum::EnumIter;
|
||||||
use glam::{Vec3, vec3, IVec3, ivec3};
|
use glam::{ivec3, vec3, IVec3, Vec3};
|
||||||
use std::f32::consts::FRAC_1_SQRT_2;
|
use std::f32::consts::FRAC_1_SQRT_2;
|
||||||
use crate::rendering::world::ChunkVertex;
|
use crate::rendering::world::ChunkVertex;
|
||||||
|
|
||||||
|
@ -79,14 +79,15 @@ const CROSS_FACE_INDICES: [u32; 12] = [
|
||||||
|
|
||||||
|
|
||||||
const UV_COORDS: [[f32; 2]; 4] = [
|
const UV_COORDS: [[f32; 2]; 4] = [
|
||||||
[0., 0.],
|
|
||||||
[0., 1.],
|
[0., 1.],
|
||||||
[1., 0.],
|
[0., 0.],
|
||||||
[1., 1.],
|
[1., 1.],
|
||||||
|
[1., 0.],
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct MeshBuilder {
|
pub struct MeshBuilder {
|
||||||
|
offset: Vec3,
|
||||||
vertex_buffer: Vec<ChunkVertex>,
|
vertex_buffer: Vec<ChunkVertex>,
|
||||||
index_buffer: Vec<u32>,
|
index_buffer: Vec<u32>,
|
||||||
idx_counter: u32,
|
idx_counter: u32,
|
||||||
|
@ -96,6 +97,10 @@ impl MeshBuilder {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_with_offset(offset: Vec3) -> Self {
|
||||||
|
Self { offset, ..Self::new() }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_face(&mut self, face: CubeFace, coord: IVec3, texture: u8) {
|
pub fn add_face(&mut self, face: CubeFace, coord: IVec3, texture: u8) {
|
||||||
let coord = coord.as_vec3();
|
let coord = coord.as_vec3();
|
||||||
let face_index = face as usize;
|
let face_index = face as usize;
|
||||||
|
@ -106,10 +111,10 @@ impl MeshBuilder {
|
||||||
self.vertex_buffer.reserve(4);
|
self.vertex_buffer.reserve(4);
|
||||||
for i in 0..4 {
|
for i in 0..4 {
|
||||||
self.vertex_buffer.push(ChunkVertex {
|
self.vertex_buffer.push(ChunkVertex {
|
||||||
position: (coord + vert[i]).to_array(),
|
position: (coord + vert[i] + self.offset).to_array(),
|
||||||
normal: norm.to_array(),
|
normal: norm.to_array(),
|
||||||
uv: UV_COORDS[i],
|
uv: UV_COORDS[i],
|
||||||
tex_index: texture
|
tex_index: texture as u32
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,18 +134,18 @@ impl MeshBuilder {
|
||||||
self.vertex_buffer.reserve(8);
|
self.vertex_buffer.reserve(8);
|
||||||
for i in 0..4 { //push front vertices
|
for i in 0..4 { //push front vertices
|
||||||
self.vertex_buffer.push(ChunkVertex {
|
self.vertex_buffer.push(ChunkVertex {
|
||||||
position: (coord.as_vec3() + vertices[i]).to_array(),
|
position: (coord.as_vec3() + vertices[i] + self.offset).to_array(),
|
||||||
normal: normal_front,
|
normal: normal_front,
|
||||||
uv: UV_COORDS[i],
|
uv: UV_COORDS[i],
|
||||||
tex_index: front_texture
|
tex_index: front_texture as u32
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
for i in 0..4 { //push back vertices
|
for i in 0..4 { //push back vertices
|
||||||
self.vertex_buffer.push(ChunkVertex {
|
self.vertex_buffer.push(ChunkVertex {
|
||||||
position: (coord.as_vec3() + vertices[i]).to_array(),
|
position: (coord.as_vec3() + vertices[i] + self.offset).to_array(),
|
||||||
normal: normal_back,
|
normal: normal_back,
|
||||||
uv: UV_COORDS[i],
|
uv: UV_COORDS[i],
|
||||||
tex_index: back_texture
|
tex_index: back_texture as u32
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,24 +156,25 @@ impl MeshBuilder {
|
||||||
self.idx_counter += 8;
|
self.idx_counter += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_model(&mut self, position: Vec3, vertices: &[ChunkVertex], indices: Option<&[u32]>) {
|
//XXX: needs offset supprt
|
||||||
//push vertices
|
// pub fn add_model(&mut self, position: Vec3, vertices: &[ChunkVertex], indices: Option<&[u32]>) {
|
||||||
self.vertex_buffer.extend(vertices.iter().map(|vertex| {
|
// //push vertices
|
||||||
let mut vertex = *vertex;
|
// self.vertex_buffer.extend(vertices.iter().map(|vertex| {
|
||||||
vertex.position[0] += position.x;
|
// let mut vertex = *vertex;
|
||||||
vertex.position[0] += position.y;
|
// vertex.position[0] += position.x;
|
||||||
vertex.position[0] += position.z;
|
// vertex.position[0] += position.y;
|
||||||
vertex
|
// vertex.position[0] += position.z;
|
||||||
}));
|
// vertex
|
||||||
//push indices
|
// }));
|
||||||
if let Some(indices) = indices {
|
// //push indices
|
||||||
self.index_buffer.extend(indices.iter().map(|x| x + self.idx_counter));
|
// if let Some(indices) = indices {
|
||||||
} else {
|
// self.index_buffer.extend(indices.iter().map(|x| x + self.idx_counter));
|
||||||
self.index_buffer.extend(0..(self.vertex_buffer.len() as u32));
|
// } else {
|
||||||
}
|
// self.index_buffer.extend(0..(self.vertex_buffer.len() as u32));
|
||||||
//increment idx counter
|
// }
|
||||||
self.idx_counter += vertices.len() as u32;
|
// //increment idx counter
|
||||||
}
|
// self.idx_counter += vertices.len() as u32;
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn finish(self) -> (Vec<ChunkVertex>, Vec<u32>) {
|
pub fn finish(self) -> (Vec<ChunkVertex>, Vec<u32>) {
|
||||||
(self.vertex_buffer, self.index_buffer)
|
(self.vertex_buffer, self.index_buffer)
|
||||||
|
|
|
@ -63,7 +63,7 @@ impl ChunkTaskManager {
|
||||||
let (
|
let (
|
||||||
(vertices, indices),
|
(vertices, indices),
|
||||||
(trans_vertices, trans_indices),
|
(trans_vertices, trans_indices),
|
||||||
) = generate_mesh(data);
|
) = generate_mesh(position, data);
|
||||||
ChunkTaskResponse::GeneratedMesh {
|
ChunkTaskResponse::GeneratedMesh {
|
||||||
position,
|
position,
|
||||||
vertices, indices,
|
vertices, indices,
|
||||||
|
|
Loading…
Reference in a new issue