mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-13 19:08:41 -06:00
uniforms, bind groups and other nice stuff
This commit is contained in:
parent
0dc53e033b
commit
cafd0a4b3d
|
@ -2,7 +2,7 @@ use serde::{Serialize, Deserialize};
|
|||
use strum::EnumIter;
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Copy, Debug, EnumIter)]
|
||||
#[repr(u8)]
|
||||
#[repr(u32)]
|
||||
pub enum BlockTexture {
|
||||
Stone,
|
||||
Dirt,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use shipyard::{NonSendSync, UniqueView, Unique, AllStoragesView};
|
||||
use shipyard::{UniqueView, Unique, AllStoragesView};
|
||||
use kubi_shared::block::BlockTexture;
|
||||
use crate::rendering::Renderer;
|
||||
|
||||
|
@ -6,7 +6,6 @@ mod texture;
|
|||
mod shaders;
|
||||
|
||||
use texture::load_asset_texture_array;
|
||||
use shaders::include_shader_prefab;
|
||||
|
||||
pub trait AssetPaths {
|
||||
fn file_name(self) -> &'static str;
|
||||
|
@ -41,10 +40,10 @@ pub struct BlockTexturesAsset(pub wgpu::Texture);
|
|||
|
||||
pub fn load_prefabs(
|
||||
storages: AllStoragesView,
|
||||
renderer: NonSendSync<UniqueView<Renderer>>
|
||||
renderer: UniqueView<Renderer>
|
||||
) {
|
||||
log::info!("Loading textures...");
|
||||
storages.add_unique_non_send_sync(BlockTexturesAsset(
|
||||
storages.add_unique(BlockTexturesAsset(
|
||||
load_asset_texture_array::<BlockTexture>("blocks".into(), &renderer)
|
||||
));
|
||||
}
|
||||
|
|
|
@ -8,6 +8,8 @@ mod frustum;
|
|||
use matrices::update_matrices;
|
||||
use frustum::{Frustum, update_frustum};
|
||||
|
||||
//TODO: handle cases where we have multiple cameras
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Camera {
|
||||
pub view_matrix: Mat4,
|
||||
|
|
|
@ -7,7 +7,7 @@ pub struct CursorLock(pub bool);
|
|||
|
||||
pub fn update_cursor_lock_state(
|
||||
lock: UniqueView<CursorLock>,
|
||||
renderer: NonSendSync<UniqueView<Renderer>>
|
||||
renderer: UniqueView<Renderer>
|
||||
) {
|
||||
#[cfg(not(target_os = "android"))]
|
||||
if lock.is_inserted_or_modified() {
|
||||
|
|
|
@ -82,7 +82,7 @@ pub fn initial_resize_event(
|
|||
mut storages: AllStoragesViewMut,
|
||||
) {
|
||||
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)
|
||||
};
|
||||
storages.add_entity((
|
||||
|
|
|
@ -59,10 +59,11 @@ use rendering::{
|
|||
Renderer,
|
||||
RenderTarget,
|
||||
BackgroundColor,
|
||||
init_rendering_internals,
|
||||
world::{draw_world, draw_current_chunk_border},
|
||||
selection_box::render_selection_box,
|
||||
entities::render_entities,
|
||||
renderer_finish_init,
|
||||
camera_uniform::update_camera_uniform,
|
||||
};
|
||||
use block_placement::update_block_placement;
|
||||
use delta_time::{DeltaTime, init_delta_time};
|
||||
|
@ -84,7 +85,7 @@ fn pre_startup() -> Workload {
|
|||
|
||||
fn startup() -> Workload {
|
||||
(
|
||||
renderer_finish_init,
|
||||
init_rendering_internals,
|
||||
init_fixed_timestamp_storage,
|
||||
initial_resize_event,
|
||||
load_prefabs,
|
||||
|
@ -133,9 +134,11 @@ fn update() -> Workload {
|
|||
).into_sequential_workload()
|
||||
}
|
||||
|
||||
//TODO move this to the renderer module
|
||||
fn render() -> Workload {
|
||||
(
|
||||
(
|
||||
update_camera_uniform,
|
||||
draw_world,
|
||||
draw_current_chunk_border,
|
||||
render_selection_box,
|
||||
|
@ -191,7 +194,7 @@ pub fn kubi_main() {
|
|||
//Initialize renderer
|
||||
{
|
||||
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.)));
|
||||
|
||||
|
@ -215,7 +218,7 @@ pub fn kubi_main() {
|
|||
Event::WindowEvent { event, .. } => match event {
|
||||
WindowEvent::Resized(new_size) => {
|
||||
//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 => {
|
||||
log::info!("exit requested");
|
||||
|
@ -237,7 +240,7 @@ pub fn kubi_main() {
|
|||
|
||||
//Start rendering (maybe use custom views for this?)
|
||||
let target = {
|
||||
let renderer = world.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap();
|
||||
let renderer = world.borrow::<UniqueView<Renderer>>().unwrap();
|
||||
renderer.begin()
|
||||
};
|
||||
world.add_unique(target);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use shipyard::{Unique, View, Workload, SystemModificator, IntoWorkload};
|
||||
use shipyard::{Unique, Workload, IntoWorkload, WorkloadModificator};
|
||||
use winit::{
|
||||
event_loop::EventLoop,
|
||||
window::{Window, WindowBuilder, Fullscreen},
|
||||
|
@ -6,17 +6,18 @@ use winit::{
|
|||
};
|
||||
use glam::{Vec3, Mat4};
|
||||
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 pipelines;
|
||||
pub mod primitives;
|
||||
pub mod world;
|
||||
pub mod selection_box;
|
||||
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(&[
|
||||
1.0, 0.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,
|
||||
]);
|
||||
|
||||
|
||||
#[derive(Unique)]
|
||||
pub struct RenderTarget {
|
||||
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_pipelines.after_all(compile_shaders),
|
||||
init_camera_uniform,
|
||||
init_primitives,
|
||||
compile_shaders,
|
||||
(
|
||||
world::init_gpu_data,
|
||||
).into_workload().after_all(compile_shaders),
|
||||
).into_workload()
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
pub fn if_resized (
|
||||
resize: View<WindowResizedEvent>,
|
||||
) -> bool {
|
||||
resize.len() > 0
|
||||
}
|
||||
|
|
45
kubi/src/rendering/camera_uniform.rs
Normal file
45
kubi/src/rendering/camera_uniform.rs
Normal 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()
|
||||
}
|
||||
]));
|
||||
}
|
|
@ -10,48 +10,47 @@ use super::shaders::Shaders;
|
|||
|
||||
pub fn render_entities() {}
|
||||
|
||||
#[cfg(fuck)]
|
||||
pub fn render_entities(
|
||||
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
|
||||
buffers: NonSendSync<UniqueView<CenteredCubePrimitive>>,
|
||||
shaders: NonSendSync<UniqueView<Shaders>>,
|
||||
camera: View<Camera>,
|
||||
settings: UniqueView<GameSettings>,
|
||||
entities: View<Entity>,
|
||||
transform: View<Transform>,
|
||||
) {
|
||||
let (camera_id, camera) = camera.iter().with_id().next().expect("No cameras in the scene");
|
||||
// pub fn render_entities(
|
||||
// mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
|
||||
// buffers: NonSendSync<UniqueView<CenteredCubePrimitive>>,
|
||||
// shaders: NonSendSync<UniqueView<Shaders>>,
|
||||
// camera: View<Camera>,
|
||||
// settings: UniqueView<GameSettings>,
|
||||
// entities: View<Entity>,
|
||||
// transform: View<Transform>,
|
||||
// ) {
|
||||
// let (camera_id, camera) = camera.iter().with_id().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,
|
||||
backface_culling: BackfaceCullingMode::CullClockwise,
|
||||
..Default::default()
|
||||
};
|
||||
let view = camera.view_matrix.to_cols_array_2d();
|
||||
let perspective = camera.perspective_matrix.to_cols_array_2d();
|
||||
// let draw_parameters = DrawParameters {
|
||||
// depth: Depth {
|
||||
// test: DepthTest::IfLess,
|
||||
// write: true,
|
||||
// ..Default::default()
|
||||
// },
|
||||
// multisampling: settings.msaa.is_some(),
|
||||
// polygon_mode: PolygonMode::Fill,
|
||||
// backface_culling: BackfaceCullingMode::CullClockwise,
|
||||
// ..Default::default()
|
||||
// };
|
||||
// let view = camera.view_matrix.to_cols_array_2d();
|
||||
// let perspective = camera.perspective_matrix.to_cols_array_2d();
|
||||
|
||||
for (entity_id, (_, trans)) in (&entities, &transform).iter().with_id() {
|
||||
//skip rendering camera holder (as the entity would block the view)
|
||||
if entity_id == camera_id { continue }
|
||||
// for (entity_id, (_, trans)) in (&entities, &transform).iter().with_id() {
|
||||
// //skip rendering camera holder (as the entity would block the view)
|
||||
// if entity_id == camera_id { continue }
|
||||
|
||||
//render entity
|
||||
// target.0.draw(
|
||||
// &buffers.0,
|
||||
// &buffers.1,
|
||||
// &program.0,
|
||||
// &uniform! {
|
||||
// color: [1.0, 1.0, 1.0, 1.0_f32],
|
||||
// model: trans.0.to_cols_array_2d(),
|
||||
// view: view,
|
||||
// perspective: perspective,
|
||||
// },
|
||||
// &draw_parameters
|
||||
// ).unwrap();
|
||||
}
|
||||
}
|
||||
// render entity
|
||||
// target.0.draw(
|
||||
// &buffers.0,
|
||||
// &buffers.1,
|
||||
// &program.0,
|
||||
// &uniform! {
|
||||
// color: [1.0, 1.0, 1.0, 1.0_f32],
|
||||
// model: trans.0.to_cols_array_2d(),
|
||||
// view: view,
|
||||
// perspective: perspective,
|
||||
// },
|
||||
// &draw_parameters
|
||||
// ).unwrap();
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -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,
|
||||
}),
|
||||
})
|
||||
}
|
|
@ -57,7 +57,7 @@ const CUBE_INDICES: &[u16] = &[
|
|||
|
||||
pub(super) fn init_cube_primitive(
|
||||
storages: AllStoragesView,
|
||||
renderer: NonSendSync<UniqueView<Renderer>>
|
||||
renderer: UniqueView<Renderer>
|
||||
) {
|
||||
storages.add_unique(
|
||||
CubePrimitive {
|
||||
|
|
|
@ -19,7 +19,7 @@ const RECT_INDEX: &[u16] = &[0, 1, 2, 1, 3, 2];
|
|||
|
||||
pub(super) fn init_rect_primitive(
|
||||
storages: AllStoragesView,
|
||||
renderer: NonSendSync<UniqueView<Renderer>>
|
||||
renderer: UniqueView<Renderer>
|
||||
) {
|
||||
let vert = renderer.device.create_buffer_init(
|
||||
&wgpu::util::BufferInitDescriptor {
|
||||
|
|
|
@ -13,42 +13,41 @@ const SMOL: f32 = 0.0001;
|
|||
|
||||
pub fn render_selection_box() { }
|
||||
|
||||
#[cfg(fuck)]
|
||||
pub fn render_selection_box(
|
||||
lookat: View<LookingAtBlock>,
|
||||
camera: View<Camera>,
|
||||
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
|
||||
program: NonSendSync<UniqueView<ColoredShaderPrefab>>,
|
||||
buffers: UniqueView<CubePrimitive>,
|
||||
) {
|
||||
let camera = camera.iter().next().unwrap();
|
||||
let Some(lookat) = lookat.iter().next() else { return };
|
||||
let Some(lookat) = lookat.0 else { return };
|
||||
// pub fn render_selection_box(
|
||||
// lookat: View<LookingAtBlock>,
|
||||
// camera: View<Camera>,
|
||||
// mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
|
||||
// program: NonSendSync<UniqueView<ColoredShaderPrefab>>,
|
||||
// buffers: UniqueView<CubePrimitive>,
|
||||
// ) {
|
||||
// let camera = camera.iter().next().unwrap();
|
||||
// let Some(lookat) = lookat.iter().next() else { return };
|
||||
// let Some(lookat) = lookat.0 else { return };
|
||||
|
||||
//Darken block
|
||||
target.0.draw(
|
||||
&buffers.0,
|
||||
&buffers.1,
|
||||
&program.0,
|
||||
&uniform! {
|
||||
color: [0., 0., 0., 0.5_f32],
|
||||
model: Mat4::from_scale_rotation_translation(
|
||||
Vec3::splat(1. + SMOL * 2.),
|
||||
Quat::default(),
|
||||
lookat.block_position.as_vec3() - Vec3::splat(SMOL)
|
||||
).to_cols_array_2d(),
|
||||
perspective: camera.perspective_matrix.to_cols_array_2d(),
|
||||
view: camera.view_matrix.to_cols_array_2d(),
|
||||
},
|
||||
&DrawParameters {
|
||||
backface_culling: BackfaceCullingMode::CullClockwise,
|
||||
blend: Blend::alpha_blending(),
|
||||
depth: Depth {
|
||||
//this may be unreliable... unless scale is applied! hacky...
|
||||
test: DepthTest::IfLessOrEqual,
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}
|
||||
).unwrap();
|
||||
}
|
||||
// //Darken block
|
||||
// target.0.draw(
|
||||
// &buffers.0,
|
||||
// &buffers.1,
|
||||
// &program.0,
|
||||
// &uniform! {
|
||||
// color: [0., 0., 0., 0.5_f32],
|
||||
// model: Mat4::from_scale_rotation_translation(
|
||||
// Vec3::splat(1. + SMOL * 2.),
|
||||
// Quat::default(),
|
||||
// lookat.block_position.as_vec3() - Vec3::splat(SMOL)
|
||||
// ).to_cols_array_2d(),
|
||||
// perspective: camera.perspective_matrix.to_cols_array_2d(),
|
||||
// view: camera.view_matrix.to_cols_array_2d(),
|
||||
// },
|
||||
// &DrawParameters {
|
||||
// backface_culling: BackfaceCullingMode::CullClockwise,
|
||||
// blend: Blend::alpha_blending(),
|
||||
// depth: Depth {
|
||||
// //this may be unreliable... unless scale is applied! hacky...
|
||||
// test: DepthTest::IfLessOrEqual,
|
||||
// ..Default::default()
|
||||
// },
|
||||
// ..Default::default()
|
||||
// }
|
||||
// ).unwrap();
|
||||
// }
|
||||
|
|
|
@ -31,7 +31,7 @@ macro_rules! build_shaders {
|
|||
pub fn compile_shaders(
|
||||
storages: AllStoragesView,
|
||||
) {
|
||||
let renderer = &storages.borrow::<NonSendSync<UniqueView<Renderer>>>().unwrap();
|
||||
let renderer = &storages.borrow::<UniqueView<Renderer>>().unwrap();
|
||||
storages.add_unique(build_shaders! {
|
||||
Shaders [renderer, "../../shaders"] {
|
||||
world: "world.wgsl",
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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 crate::{
|
||||
camera::Camera,
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
|||
chunk::CHUNK_SIZE,
|
||||
}, settings::GameSettings,
|
||||
};
|
||||
use super::{RenderTarget, shaders::Shaders, Renderer};
|
||||
use super::{Renderer, RenderTarget, shaders::Shaders, camera_uniform::CameraUniformBuffer};
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
|
@ -20,181 +20,281 @@ pub struct ChunkVertex {
|
|||
pub position: [f32; 3],
|
||||
pub normal: [f32; 3],
|
||||
pub uv: [f32; 2],
|
||||
pub tex_index: u8,
|
||||
pub tex_index: u32,
|
||||
}
|
||||
|
||||
#[repr(C, packed)]
|
||||
#[derive(Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
#[derive(Clone, Copy, Default, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
struct WorldUniform {
|
||||
position_offset: [f32; 3],
|
||||
view_proj: [[f32; 4]; 4],
|
||||
position: [f32; 3], //XXX: should use i32?
|
||||
}
|
||||
|
||||
#[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(
|
||||
renderer: UniqueView<Renderer>,
|
||||
mut target: UniqueViewMut<RenderTarget>,
|
||||
gpu_data: UniqueView<GpuData>,
|
||||
chunks: UniqueView<ChunkStorage>,
|
||||
meshes: UniqueView<ChunkMeshStorage>,
|
||||
shaders: UniqueView<Shaders>,
|
||||
texture: UniqueView<BlockTexturesAsset>,
|
||||
camera: View<Camera>,
|
||||
settings: UniqueView<GameSettings>
|
||||
) {
|
||||
let camera = camera.iter().next().expect("No cameras in the scene");
|
||||
for (&position, chunk) in &chunks.chunks {
|
||||
if let Some(key) = chunk.mesh_index {
|
||||
let mesh = meshes.get(key).expect("Mesh index pointing to nothing");
|
||||
let world_position = position.as_vec3() * CHUNK_SIZE as f32;
|
||||
|
||||
//TODO culling
|
||||
//TODO culling like in the glium version
|
||||
|
||||
//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 {
|
||||
if let Some(key) = chunk.mesh_index {
|
||||
let mesh = meshes.get(key).expect("Mesh index pointing to nothing");
|
||||
let world_position = position.as_vec3() * CHUNK_SIZE as f32;
|
||||
// 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();
|
||||
|
||||
//Skip mesh if its empty
|
||||
if mesh.index_buffer.len() == 0 {
|
||||
continue
|
||||
}
|
||||
// for (&position, chunk) in &chunks.chunks {
|
||||
// if let Some(key) = chunk.mesh_index {
|
||||
// let mesh = meshes.get(key).expect("Mesh index pointing to nothing");
|
||||
// let world_position = position.as_vec3() * CHUNK_SIZE as f32;
|
||||
|
||||
//Frustum culling
|
||||
{
|
||||
let minp = world_position;
|
||||
let maxp = world_position + Vec3::splat(CHUNK_SIZE as f32);
|
||||
if !camera.frustum.is_box_visible(minp, maxp) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
// //Skip mesh if its empty
|
||||
// if mesh.index_buffer.len() == 0 {
|
||||
// continue
|
||||
// }
|
||||
|
||||
//Draw chunk mesh
|
||||
target.0.draw(
|
||||
&mesh.vertex_buffer,
|
||||
&mesh.index_buffer,
|
||||
&program.0,
|
||||
&uniform! {
|
||||
position_offset: world_position.to_array(),
|
||||
view: view,
|
||||
perspective: perspective,
|
||||
tex: texture_sampler,
|
||||
},
|
||||
&draw_parameters
|
||||
).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
// //Frustum culling
|
||||
// {
|
||||
// let minp = world_position;
|
||||
// let maxp = world_position + Vec3::splat(CHUNK_SIZE as f32);
|
||||
// if !camera.frustum.is_box_visible(minp, maxp) {
|
||||
// continue
|
||||
// }
|
||||
// }
|
||||
|
||||
// //Draw chunk mesh
|
||||
// target.0.draw(
|
||||
// &mesh.vertex_buffer,
|
||||
// &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() {}
|
||||
|
||||
#[cfg(fuck)]
|
||||
pub fn draw_current_chunk_border(
|
||||
mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
|
||||
player: View<MainPlayer>,
|
||||
transforms: View<Transform, track::All>,
|
||||
buffers: UniqueView<CubePrimitive>,
|
||||
program: NonSendSync<UniqueView<ColoredShaderPrefab>>,
|
||||
camera: View<Camera>,
|
||||
settings: UniqueView<GameSettings>,
|
||||
) {
|
||||
#[cfg(fuck)] {
|
||||
if cfg!(target_os = "android") {
|
||||
return
|
||||
}
|
||||
if !settings.debug_draw_current_chunk_border {
|
||||
return
|
||||
}
|
||||
let camera = camera.iter().next().expect("No cameras in the scene");
|
||||
let view = camera.view_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_position) = player_transform.0.to_scale_rotation_translation();
|
||||
let player_in_chunk = ivec3(
|
||||
(player_position.x 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),
|
||||
);
|
||||
let world_position = player_in_chunk.as_vec3() * CHUNK_SIZE as f32;
|
||||
target.0.draw(
|
||||
&buffers.0,
|
||||
&buffers.1,
|
||||
&program.0,
|
||||
&uniform! {
|
||||
model: Mat4::from_scale_rotation_translation(
|
||||
Vec3::splat(CHUNK_SIZE as f32),
|
||||
Quat::default(),
|
||||
world_position
|
||||
).to_cols_array_2d(),
|
||||
color: [0.25f32; 4],
|
||||
view: view,
|
||||
perspective: perspective,
|
||||
},
|
||||
&DrawParameters {
|
||||
depth: Depth {
|
||||
test: DepthTest::IfLess,
|
||||
..Default::default()
|
||||
},
|
||||
blend: Blend::alpha_blending(),
|
||||
..Default::default()
|
||||
}
|
||||
).unwrap();
|
||||
target.0.draw(
|
||||
&buffers.0,
|
||||
&buffers.1,
|
||||
&program.0,
|
||||
&uniform! {
|
||||
model: Mat4::from_scale_rotation_translation(
|
||||
Vec3::splat(CHUNK_SIZE as f32),
|
||||
Quat::default(),
|
||||
world_position
|
||||
).to_cols_array_2d(),
|
||||
color: [0.0f32; 4],
|
||||
view: view,
|
||||
perspective: perspective,
|
||||
},
|
||||
&DrawParameters {
|
||||
polygon_mode: PolygonMode::Point,
|
||||
line_width: Some(2.),
|
||||
point_size: Some(5.),
|
||||
..Default::default()
|
||||
}
|
||||
).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn draw_current_chunk_border(
|
||||
// mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
|
||||
// player: View<MainPlayer>,
|
||||
// transforms: View<Transform, track::All>,
|
||||
// buffers: UniqueView<CubePrimitive>,
|
||||
// program: NonSendSync<UniqueView<ColoredShaderPrefab>>,
|
||||
// camera: View<Camera>,
|
||||
// settings: UniqueView<GameSettings>,
|
||||
// ) {
|
||||
// #[cfg(fuck)] {
|
||||
// if cfg!(target_os = "android") {
|
||||
// return
|
||||
// }
|
||||
// if !settings.debug_draw_current_chunk_border {
|
||||
// return
|
||||
// }
|
||||
// let camera = camera.iter().next().expect("No cameras in the scene");
|
||||
// let view = camera.view_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_position) = player_transform.0.to_scale_rotation_translation();
|
||||
// let player_in_chunk = ivec3(
|
||||
// (player_position.x 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),
|
||||
// );
|
||||
// let world_position = player_in_chunk.as_vec3() * CHUNK_SIZE as f32;
|
||||
// target.0.draw(
|
||||
// &buffers.0,
|
||||
// &buffers.1,
|
||||
// &program.0,
|
||||
// &uniform! {
|
||||
// model: Mat4::from_scale_rotation_translation(
|
||||
// Vec3::splat(CHUNK_SIZE as f32),
|
||||
// Quat::default(),
|
||||
// world_position
|
||||
// ).to_cols_array_2d(),
|
||||
// color: [0.25f32; 4],
|
||||
// view: view,
|
||||
// perspective: perspective,
|
||||
// },
|
||||
// &DrawParameters {
|
||||
// depth: Depth {
|
||||
// test: DepthTest::IfLess,
|
||||
// ..Default::default()
|
||||
// },
|
||||
// blend: Blend::alpha_blending(),
|
||||
// ..Default::default()
|
||||
// }
|
||||
// ).unwrap();
|
||||
// target.0.draw(
|
||||
// &buffers.0,
|
||||
// &buffers.1,
|
||||
// &program.0,
|
||||
// &uniform! {
|
||||
// model: Mat4::from_scale_rotation_translation(
|
||||
// Vec3::splat(CHUNK_SIZE as f32),
|
||||
// Quat::default(),
|
||||
// world_position
|
||||
// ).to_cols_array_2d(),
|
||||
// color: [0.0f32; 4],
|
||||
// view: view,
|
||||
// perspective: perspective,
|
||||
// },
|
||||
// &DrawParameters {
|
||||
// polygon_mode: PolygonMode::Point,
|
||||
// line_width: Some(2.),
|
||||
// point_size: Some(5.),
|
||||
// ..Default::default()
|
||||
// }
|
||||
// ).unwrap();
|
||||
// }
|
||||
// }
|
||||
|
|
|
@ -91,7 +91,7 @@ pub fn update_chunks_if_player_moved(
|
|||
|
||||
fn unload_downgrade_chunks(
|
||||
mut vm_world: UniqueViewMut<ChunkStorage>,
|
||||
mut vm_meshes: NonSendSync<UniqueViewMut<ChunkMeshStorage>>
|
||||
mut vm_meshes: UniqueViewMut<ChunkMeshStorage>
|
||||
) {
|
||||
if !vm_world.is_modified() {
|
||||
return
|
||||
|
@ -184,8 +184,8 @@ fn start_required_tasks(
|
|||
fn process_completed_tasks(
|
||||
task_manager: UniqueView<ChunkTaskManager>,
|
||||
mut world: UniqueViewMut<ChunkStorage>,
|
||||
mut meshes: NonSendSync<UniqueViewMut<ChunkMeshStorage>>,
|
||||
renderer: NonSendSync<UniqueView<Renderer>>,
|
||||
mut meshes: UniqueViewMut<ChunkMeshStorage>,
|
||||
renderer: UniqueView<Renderer>,
|
||||
state: UniqueView<GameState>,
|
||||
mut queue: UniqueViewMut<BlockUpdateQueue>,
|
||||
) {
|
||||
|
|
|
@ -65,7 +65,7 @@ pub fn generate_mesh(data: MeshGenData) -> (Vec<ChunkVertex>, Vec<u32>) {
|
|||
CubeFace::Back => textures.back,
|
||||
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(
|
||||
coord,
|
||||
DiagonalFace::LeftZ,
|
||||
textures.0.front as u8,
|
||||
textures.0.back as u8
|
||||
textures.0.front as u32,
|
||||
textures.0.back as u32
|
||||
);
|
||||
builder.add_diagonal_face(
|
||||
coord,
|
||||
DiagonalFace::RigthZ,
|
||||
textures.1.front as u8,
|
||||
textures.1.back as u8
|
||||
textures.1.front as u32,
|
||||
textures.1.back as u32
|
||||
);
|
||||
},
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ impl MeshBuilder {
|
|||
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 face_index = face as usize;
|
||||
|
||||
|
@ -120,7 +120,7 @@ impl MeshBuilder {
|
|||
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
|
||||
let face_type = face_type as usize;
|
||||
let vertices = CROSS_FACES[face_type];
|
||||
|
|
Loading…
Reference in a new issue