mirror of
https://github.com/griffi-gh/kubi.git
synced 2024-11-21 14:28:43 -06:00
kitty? kitty!
This commit is contained in:
parent
3f0697d573
commit
eec672d665
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -1242,6 +1242,7 @@ dependencies = [
|
|||
"static_assertions",
|
||||
"strum",
|
||||
"tinyset",
|
||||
"tobj",
|
||||
"uflow",
|
||||
"wgpu",
|
||||
"winapi",
|
||||
|
@ -2420,6 +2421,15 @@ dependencies = [
|
|||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tobj"
|
||||
version = "4.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3bd4ba05f29e4c65b6c0c11a58b6465ffa820bac890d76ad407b4e81d8372e8"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.12"
|
||||
|
|
BIN
assets-src/playermodel1.blend
Normal file
BIN
assets-src/playermodel1.blend
Normal file
Binary file not shown.
64
assets/playermodel1.obj
Normal file
64
assets/playermodel1.obj
Normal file
|
@ -0,0 +1,64 @@
|
|||
# Blender 4.0.0 Beta
|
||||
# www.blender.org
|
||||
o Cube
|
||||
v 1.000000 1.000000 -1.000000
|
||||
v 1.000000 -1.000000 -1.000000
|
||||
v 1.000000 1.000000 1.000000
|
||||
v 1.000000 -1.000000 1.000000
|
||||
v -1.000000 1.000000 -1.000000
|
||||
v -1.000000 -1.000000 -1.000000
|
||||
v -1.000000 1.000000 1.000000
|
||||
v -1.000000 -1.000000 1.000000
|
||||
v 1.000000 1.500000 -1.000000
|
||||
v 1.000000 1.500000 1.000000
|
||||
v 1.000000 1.000000 -0.333333
|
||||
v 1.000000 1.000000 0.333333
|
||||
vn -0.0000 1.0000 -0.0000
|
||||
vn -0.0000 -0.0000 1.0000
|
||||
vn -1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -1.0000 -0.0000
|
||||
vn 1.0000 -0.0000 -0.0000
|
||||
vn -0.0000 -0.0000 -1.0000
|
||||
vt 0.204555 0.291387
|
||||
vt 0.043204 0.462923
|
||||
vt 0.043204 0.291387
|
||||
vt 0.259623 0.207472
|
||||
vt 0.024467 0.457472
|
||||
vt 0.024467 0.207472
|
||||
vt 0.177715 0.183914
|
||||
vt 0.010921 0.538561
|
||||
vt 0.010921 0.183914
|
||||
vt 0.246583 0.218979
|
||||
vt 0.011426 0.468979
|
||||
vt 0.011426 0.218979
|
||||
vt 0.896961 0.811182
|
||||
vt 0.168955 0.037222
|
||||
vt 0.896961 0.037221
|
||||
vt 0.177715 0.538561
|
||||
vt 0.010921 0.361238
|
||||
vt 0.168955 0.811182
|
||||
vt 0.411624 0.811182
|
||||
vt 0.204555 0.462923
|
||||
vt 0.259623 0.457472
|
||||
vt 0.246583 0.468979
|
||||
vt 0.177715 0.361238
|
||||
vt 0.896961 0.990308
|
||||
vt 0.654292 0.811182
|
||||
vt 0.168955 0.990308
|
||||
s 0
|
||||
f 5/1/1 3/2/1 1/3/1
|
||||
f 3/4/2 8/5/2 4/6/2
|
||||
f 7/7/3 6/8/3 8/9/3
|
||||
f 2/10/4 8/11/4 6/12/4
|
||||
f 1/13/5 4/14/5 2/15/5
|
||||
f 5/16/6 2/17/6 6/8/6
|
||||
f 3/18/1 1/13/1 12/19/1
|
||||
f 5/1/1 7/20/1 3/2/1
|
||||
f 3/4/2 7/21/2 8/5/2
|
||||
f 7/7/3 5/16/3 6/8/3
|
||||
f 2/10/4 4/22/4 8/11/4
|
||||
f 1/13/5 3/18/5 4/14/5
|
||||
f 5/16/6 1/23/6 2/17/6
|
||||
f 1/13/5 9/24/5 11/25/5
|
||||
f 12/19/5 10/26/5 3/18/5
|
||||
f 1/13/5 11/25/5 12/19/5
|
BIN
assets/playermodel1.png
Normal file
BIN
assets/playermodel1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 137 KiB |
|
@ -38,7 +38,7 @@ tinyset = "0.4"
|
|||
serde_json = { version = "1.0", optional = true } #only used for `generate_visualizer_data`
|
||||
rand = { version = "0.8", features = ["alloc", "small_rng"]}
|
||||
atomic = "0.6"
|
||||
|
||||
tobj = "4.0"
|
||||
|
||||
[target.'cfg(target_os = "android")'.dependencies]
|
||||
android-activity = "0.6"
|
||||
|
|
40
kubi/shaders/entities.wgsl
Normal file
40
kubi/shaders/entities.wgsl
Normal file
|
@ -0,0 +1,40 @@
|
|||
struct CameraUniform {
|
||||
view_proj: mat4x4<f32>,
|
||||
};
|
||||
|
||||
@group(1) @binding(0)
|
||||
var<uniform> camera: CameraUniform;
|
||||
|
||||
struct VertexInput {
|
||||
@location(0) uv: vec2<f32>,
|
||||
@location(1) position: vec3<f32>,
|
||||
@location(2) normal: vec3<f32>,
|
||||
}
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position) clip_position: vec4<f32>,
|
||||
@location(0) uv: vec2<f32>,
|
||||
@location(1) normal: vec3<f32>,
|
||||
};
|
||||
|
||||
@vertex
|
||||
fn vs_main(
|
||||
in: VertexInput,
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.clip_position = camera.view_proj * vec4<f32>(in.position, 1.0);
|
||||
out.uv = in.uv;
|
||||
out.normal = in.normal;
|
||||
return out;
|
||||
}
|
||||
|
||||
@group(0) @binding(0)
|
||||
var t_diffuse: texture_2d<f32>;
|
||||
|
||||
@group(0) @binding(1)
|
||||
var s_diffuse: sampler;
|
||||
|
||||
@fragment
|
||||
fn fs_main(in: VertexOutput) -> @location(0) vec4<f32> {
|
||||
return textureSample(t_diffuse, s_diffuse, in.uv);
|
||||
}
|
|
@ -1,11 +1,35 @@
|
|||
use std::{io::{BufReader, Read}, path::Path};
|
||||
use std::{io::{BufReader, Read}, path::{Path, PathBuf}};
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use hui::text::FontHandle;
|
||||
use shipyard::{AllStoragesView, NonSendSync, Unique, UniqueView, UniqueViewMut};
|
||||
use kubi_shared::block::BlockTexture;
|
||||
use crate::{filesystem::AssetManager, hui_integration::UiState, rendering::Renderer};
|
||||
use crate::{filesystem::AssetManager, hui_integration::UiState, rendering::{BufferPair, Renderer}};
|
||||
|
||||
mod texture;
|
||||
use texture::load_texture2darray_prefab;
|
||||
//TODO move to rendering module
|
||||
|
||||
mod loader;
|
||||
use loader::{load_texture2darray_prefab, load_texture2d_prefab, load_obj_prefab};
|
||||
|
||||
#[derive(Clone, Copy, Default, Pod, Zeroable)]
|
||||
#[repr(C, packed)]
|
||||
pub struct ModelVertex {
|
||||
pub tex_coords: [f32; 2],
|
||||
pub position: [f32; 3],
|
||||
pub _padding: u32,
|
||||
pub normal: [f32; 3],
|
||||
}
|
||||
|
||||
impl ModelVertex {
|
||||
pub const LAYOUT: wgpu::VertexBufferLayout<'static> = wgpu::VertexBufferLayout {
|
||||
array_stride: std::mem::size_of::<ModelVertex>() as wgpu::BufferAddress,
|
||||
step_mode: wgpu::VertexStepMode::Vertex,
|
||||
attributes: &wgpu::vertex_attr_array![
|
||||
0 => Float32x2,
|
||||
1 => Float32x3,
|
||||
2 => Float32x3,
|
||||
],
|
||||
};
|
||||
}
|
||||
|
||||
pub trait AssetPaths {
|
||||
fn file_name(self) -> &'static str;
|
||||
|
@ -36,10 +60,14 @@ impl AssetPaths for BlockTexture {
|
|||
}
|
||||
|
||||
#[derive(Unique)]
|
||||
pub struct TexturePrefabs {
|
||||
pub struct GpuPrefabs {
|
||||
pub block_diffuse_texture: wgpu::Texture,
|
||||
pub block_diffuse_bind_group_layout: wgpu::BindGroupLayout,
|
||||
pub block_diffuse_bind_group: wgpu::BindGroup,
|
||||
pub player_model_diffuse_texture: wgpu::Texture,
|
||||
pub player_model_diffuse_bind_group_layout: wgpu::BindGroupLayout,
|
||||
pub player_model_diffuse_bind_group: wgpu::BindGroup,
|
||||
pub player_model: BufferPair,
|
||||
}
|
||||
|
||||
#[derive(Unique)]
|
||||
|
@ -110,10 +138,69 @@ pub fn load_prefabs(
|
|||
}
|
||||
]
|
||||
});
|
||||
storages.add_unique_non_send_sync(TexturePrefabs {
|
||||
|
||||
let player_model_diffuse_texture = load_texture2d_prefab(&renderer, &assman, &PathBuf::from("playermodel1.png"));
|
||||
let player_model_diffuse_view = player_model_diffuse_texture.create_view(&wgpu::TextureViewDescriptor {
|
||||
label: Some("player_model_texture_view"),
|
||||
..Default::default()
|
||||
});
|
||||
let player_model_diffuse_sampler = renderer.device().create_sampler(&wgpu::SamplerDescriptor {
|
||||
label: Some("player_model_sampler"),
|
||||
address_mode_u: wgpu::AddressMode::ClampToEdge,
|
||||
address_mode_v: wgpu::AddressMode::ClampToEdge,
|
||||
address_mode_w: wgpu::AddressMode::ClampToEdge,
|
||||
mag_filter: wgpu::FilterMode::Linear,
|
||||
min_filter: wgpu::FilterMode::Linear,
|
||||
mipmap_filter: wgpu::FilterMode::Nearest,
|
||||
..Default::default()
|
||||
});
|
||||
let player_model_diffuse_bind_group_layout = renderer.device()
|
||||
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
label: Some("player_model_bind_group_layout"),
|
||||
entries: &[
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Texture {
|
||||
sample_type: wgpu::TextureSampleType::Float { filterable: true },
|
||||
view_dimension: wgpu::TextureViewDimension::D2,
|
||||
multisampled: false,
|
||||
},
|
||||
count: None,
|
||||
},
|
||||
wgpu::BindGroupLayoutEntry {
|
||||
binding: 1,
|
||||
visibility: wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
|
||||
count: None,
|
||||
}
|
||||
]
|
||||
});
|
||||
let player_model_diffuse_bind_group = renderer.device().create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: Some("player_model_bind_group"),
|
||||
layout: &player_model_diffuse_bind_group_layout,
|
||||
entries: &[
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::TextureView(&player_model_diffuse_view),
|
||||
},
|
||||
wgpu::BindGroupEntry {
|
||||
binding: 1,
|
||||
resource: wgpu::BindingResource::Sampler(&player_model_diffuse_sampler),
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
let player_model = load_obj_prefab(&renderer, &assman, &PathBuf::from("playermodel1.obj"));
|
||||
|
||||
storages.add_unique_non_send_sync(GpuPrefabs {
|
||||
block_diffuse_texture,
|
||||
block_diffuse_bind_group_layout,
|
||||
block_diffuse_bind_group,
|
||||
player_model_diffuse_texture,
|
||||
player_model_diffuse_bind_group_layout,
|
||||
player_model_diffuse_bind_group,
|
||||
player_model,
|
||||
});
|
||||
|
||||
log::info!("Loading the UI stuff...");
|
||||
|
|
164
kubi/src/prefabs/loader.rs
Normal file
164
kubi/src/prefabs/loader.rs
Normal file
|
@ -0,0 +1,164 @@
|
|||
use glam::UVec2;
|
||||
use strum::IntoEnumIterator;
|
||||
use rayon::prelude::*;
|
||||
use wgpu::util::{DeviceExt, TextureDataOrder};
|
||||
use std::{io::{BufReader, Read}, path::{Path, PathBuf}};
|
||||
use crate::{filesystem::AssetManager, prefabs::ModelVertex, rendering::{BufferPair, Renderer}};
|
||||
use super::AssetPaths;
|
||||
|
||||
pub fn load_texture2darray_prefab<T: AssetPaths + IntoEnumIterator>(
|
||||
renderer: &Renderer,
|
||||
assman: &AssetManager,
|
||||
directory: PathBuf,
|
||||
) -> wgpu::Texture {
|
||||
log::info!("started loading {}", directory.as_os_str().to_str().unwrap());
|
||||
|
||||
//Load raw images
|
||||
let tex_files: Vec<&'static str> = T::iter().map(|x| x.file_name()).collect();
|
||||
let raw_images: Vec<(Vec<u8>, UVec2)> = tex_files.par_iter().map(|&file_name| {
|
||||
log::info!("loading texture {}", file_name);
|
||||
|
||||
//Get path to the image and open the file
|
||||
let reader = {
|
||||
let path = directory.join(file_name);
|
||||
BufReader::new(assman.open_asset(&path).expect("Failed to open texture file"))
|
||||
};
|
||||
|
||||
//Parse image data
|
||||
let (image_data, dimensions) = {
|
||||
let image = image::load(
|
||||
reader,
|
||||
image::ImageFormat::Png
|
||||
).unwrap().to_rgba8();
|
||||
let dimensions = image.dimensions();
|
||||
(image.into_raw(), dimensions)
|
||||
};
|
||||
(image_data, UVec2::from(dimensions))
|
||||
}).collect();
|
||||
|
||||
assert!(!raw_images.is_empty(), "no images loaded");
|
||||
//TODO: check same size
|
||||
|
||||
log::info!("done loading texture files, uploading to the gpu");
|
||||
|
||||
let size = raw_images[0].1;
|
||||
let layers = raw_images.len() as u32;
|
||||
|
||||
//Concat data into a single vec
|
||||
let mut data = Vec::with_capacity((size.x * size.y * layers * 4) as usize);
|
||||
for (layer_data, _) in raw_images {
|
||||
data.extend_from_slice(&layer_data);
|
||||
}
|
||||
|
||||
//Upload images to the GPU
|
||||
let label = format!("texture2darray_prefab_{}", directory.as_os_str().to_str().unwrap());
|
||||
let desc = &wgpu::TextureDescriptor {
|
||||
label: Some(&label),
|
||||
size: wgpu::Extent3d {
|
||||
width: size.x,
|
||||
height: size.y,
|
||||
depth_or_array_layers: layers,
|
||||
},
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
view_formats: &[],
|
||||
};
|
||||
|
||||
renderer.device().create_texture_with_data(
|
||||
renderer.queue(),
|
||||
desc,
|
||||
TextureDataOrder::MipMajor,
|
||||
&data
|
||||
)
|
||||
}
|
||||
|
||||
pub fn load_texture2d_prefab(
|
||||
renderer: &Renderer,
|
||||
assman: &AssetManager,
|
||||
path: &Path,
|
||||
) -> wgpu::Texture {
|
||||
let image = image::load(
|
||||
BufReader::new(assman.open_asset(path).expect("Failed to open texture file")),
|
||||
image::ImageFormat::Png
|
||||
).unwrap().to_rgba8();
|
||||
let size = image.dimensions();
|
||||
let data = image.into_raw();
|
||||
|
||||
let label = format!("texture2d_prefab_{}", path.file_name().unwrap().to_str().unwrap());
|
||||
let desc = wgpu::TextureDescriptor {
|
||||
label: Some(&label),
|
||||
size: wgpu::Extent3d {
|
||||
width: size.0,
|
||||
height: size.1,
|
||||
depth_or_array_layers: 1,
|
||||
},
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
view_formats: &[],
|
||||
};
|
||||
|
||||
renderer.device().create_texture_with_data(
|
||||
renderer.queue(),
|
||||
&desc,
|
||||
TextureDataOrder::MipMajor,
|
||||
&data
|
||||
)
|
||||
}
|
||||
|
||||
pub fn load_obj_prefab(
|
||||
renderer: &Renderer,
|
||||
assman: &AssetManager,
|
||||
path: &Path,
|
||||
) -> BufferPair {
|
||||
let mut reader = BufReader::new(
|
||||
assman.open_asset(path).expect("Failed to open texture file")
|
||||
);
|
||||
|
||||
let (model, _) = tobj::load_obj_buf(
|
||||
&mut reader,
|
||||
&tobj::GPU_LOAD_OPTIONS,
|
||||
|_| unimplemented!()
|
||||
).unwrap();
|
||||
|
||||
assert_eq!(model.len(), 1, "only single model supported at the moment, sowwy :3");
|
||||
let mesh = &model[0].mesh;
|
||||
debug_assert!(mesh.normal_indices.is_empty() && mesh.texcoord_indices.is_empty(), "forgor single_index");
|
||||
|
||||
let tex_coords = bytemuck::cast_slice::<f32, [f32; 2]>(&mesh.texcoords);
|
||||
let positions = bytemuck::cast_slice::<f32, [f32; 3]>(&mesh.positions);
|
||||
let normals = bytemuck::cast_slice::<f32, [f32; 3]>(&mesh.normals);
|
||||
|
||||
let vertex_buffer: Vec<_> = (0..positions.len()).map(|i| {
|
||||
ModelVertex {
|
||||
tex_coords: [tex_coords[i][0], 1. - tex_coords[i][1]],
|
||||
position: positions[i],
|
||||
_padding: 0,
|
||||
normal: normals[i],
|
||||
}
|
||||
}).collect();
|
||||
|
||||
let vertex_buffer = renderer.device().create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("obj_vertex_buffer"),
|
||||
contents: bytemuck::cast_slice(&vertex_buffer),
|
||||
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::VERTEX,
|
||||
});
|
||||
|
||||
let index_buffer = renderer.device().create_buffer_init(&wgpu::util::BufferInitDescriptor {
|
||||
label: Some("obj_index_buffer"),
|
||||
contents: bytemuck::cast_slice(&mesh.indices),
|
||||
usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::INDEX,
|
||||
});
|
||||
|
||||
BufferPair {
|
||||
vertex: vertex_buffer,
|
||||
vertex_len: positions.len() as u32,
|
||||
index: index_buffer,
|
||||
index_len: mesh.indices.len() as u32,
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
use glam::UVec2;
|
||||
use strum::IntoEnumIterator;
|
||||
use rayon::prelude::*;
|
||||
use wgpu::util::{DeviceExt, TextureDataOrder};
|
||||
use std::{io::BufReader, path::PathBuf};
|
||||
use crate::{filesystem::AssetManager, rendering::Renderer};
|
||||
use super::AssetPaths;
|
||||
|
||||
pub fn load_texture2darray_prefab<T: AssetPaths + IntoEnumIterator>(
|
||||
renderer: &Renderer,
|
||||
assman: &AssetManager,
|
||||
directory: PathBuf,
|
||||
) -> wgpu::Texture {
|
||||
log::info!("started loading {}", directory.as_os_str().to_str().unwrap());
|
||||
|
||||
//Load raw images
|
||||
let tex_files: Vec<&'static str> = T::iter().map(|x| x.file_name()).collect();
|
||||
let raw_images: Vec<(Vec<u8>, UVec2)> = tex_files.par_iter().map(|&file_name| {
|
||||
log::info!("loading texture {}", file_name);
|
||||
|
||||
//Get path to the image and open the file
|
||||
let reader = {
|
||||
let path = directory.join(file_name);
|
||||
BufReader::new(assman.open_asset(&path).expect("Failed to open texture file"))
|
||||
};
|
||||
|
||||
//Parse image data
|
||||
let (image_data, dimensions) = {
|
||||
let image = image::load(
|
||||
reader,
|
||||
image::ImageFormat::Png
|
||||
).unwrap().to_rgba8();
|
||||
let dimensions = image.dimensions();
|
||||
(image.into_raw(), dimensions)
|
||||
};
|
||||
(image_data, UVec2::from(dimensions))
|
||||
}).collect();
|
||||
|
||||
assert!(!raw_images.is_empty(), "no images loaded");
|
||||
//TODO: check same size
|
||||
|
||||
log::info!("done loading texture files, uploading to the gpu");
|
||||
|
||||
let size = raw_images[0].1;
|
||||
let layers = raw_images.len() as u32;
|
||||
|
||||
//Concat data into a single vec
|
||||
let mut data = Vec::with_capacity((size.x * size.y * layers * 4) as usize);
|
||||
for (layer_data, _) in raw_images {
|
||||
data.extend_from_slice(&layer_data);
|
||||
}
|
||||
|
||||
//Upload images to the GPU
|
||||
let desc = &wgpu::TextureDescriptor {
|
||||
label: Some("block_diffuse_texture"),
|
||||
size: wgpu::Extent3d {
|
||||
width: size.x,
|
||||
height: size.y,
|
||||
depth_or_array_layers: layers,
|
||||
},
|
||||
dimension: wgpu::TextureDimension::D2,
|
||||
format: wgpu::TextureFormat::Rgba8UnormSrgb,
|
||||
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST,
|
||||
mip_level_count: 1,
|
||||
sample_count: 1,
|
||||
view_formats: &[],
|
||||
};
|
||||
|
||||
renderer.device().create_texture_with_data(
|
||||
renderer.queue(),
|
||||
desc,
|
||||
TextureDataOrder::MipMajor,
|
||||
&data
|
||||
)
|
||||
}
|
|
@ -6,6 +6,7 @@ use crate::{events::WindowResizedEvent, hui_integration::kubi_ui_draw, state::is
|
|||
mod renderer;
|
||||
mod primitives;
|
||||
mod selection_box;
|
||||
mod entities;
|
||||
pub use renderer::Renderer;
|
||||
|
||||
pub mod background;
|
||||
|
@ -35,8 +36,9 @@ pub fn init_rendering() -> Workload {
|
|||
(
|
||||
depth::init_depth_texture,
|
||||
camera_uniform::init_camera_uniform_buffer,
|
||||
world::init_world_render_state, //req: depth, camera
|
||||
primitives::init_primitives,
|
||||
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
|
||||
).into_sequential_workload()
|
||||
}
|
||||
|
@ -65,7 +67,6 @@ pub fn render_master(storages: AllStoragesViewMut) {
|
|||
let surface_view = surface_texture.texture.create_view(&wgpu::TextureViewDescriptor::default());
|
||||
|
||||
let mut data = RenderCtx {
|
||||
//renderer: &renderer,
|
||||
encoder: &mut encoder,
|
||||
surface_view: &surface_view,
|
||||
};
|
||||
|
@ -74,8 +75,8 @@ pub fn render_master(storages: AllStoragesViewMut) {
|
|||
if storages.run(is_ingame) {
|
||||
storages.run_with_data(world::draw_world, &mut data);
|
||||
storages.run_with_data(selection_box::draw_selection_box, &mut data);
|
||||
storages.run_with_data(entities::render_entities, &mut data);
|
||||
}
|
||||
|
||||
storages.run_with_data(kubi_ui_draw, &mut data);
|
||||
|
||||
renderer.queue().submit([encoder.finish()]);
|
||||
|
|
|
@ -1,58 +1,69 @@
|
|||
// use shipyard::{NonSendSync, UniqueViewMut, UniqueView, View, IntoIter, IntoWithId};
|
||||
// use glium::{DepthTest, Depth, PolygonMode, BackfaceCullingMode, DrawParameters, Surface, uniform};
|
||||
// use kubi_shared::{entity::Entity, transform::Transform};
|
||||
// use crate::{
|
||||
// prefabs::ColoredShaderPrefab,
|
||||
// camera::Camera,
|
||||
// settings::GameSettings
|
||||
// };
|
||||
// use super::{
|
||||
// RenderTarget,
|
||||
// primitives::cube::CenteredCubePrimitive
|
||||
// };
|
||||
use shipyard::{AllStoragesView, IntoIter, IntoWithId, Unique, UniqueView, View};
|
||||
use kubi_shared::{entity::Entity, transform::Transform};
|
||||
use crate::{
|
||||
camera::Camera, prefabs::GpuPrefabs, settings::GameSettings
|
||||
};
|
||||
|
||||
// // TODO: entity models
|
||||
// pub fn render_entities(
|
||||
// mut target: NonSendSync<UniqueViewMut<RenderTarget>>,
|
||||
// buffers: NonSendSync<UniqueView<CenteredCubePrimitive>>,
|
||||
// program: NonSendSync<UniqueView<ColoredShaderPrefab>>,
|
||||
// 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");
|
||||
use super::{camera_uniform::CameraUniformBuffer, depth::DepthTexture, RenderCtx};
|
||||
|
||||
// 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();
|
||||
mod pipeline;
|
||||
|
||||
// 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 }
|
||||
#[derive(Unique)]
|
||||
pub struct EntitiesRenderState {
|
||||
pub pipeline: wgpu::RenderPipeline,
|
||||
}
|
||||
|
||||
// //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();
|
||||
// }
|
||||
// }
|
||||
pub fn init_entities_render_state(storages: AllStoragesView) {
|
||||
storages.add_unique(EntitiesRenderState {
|
||||
pipeline: storages.run(pipeline::init_entities_pipeline),
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: entity models
|
||||
pub fn render_entities(
|
||||
ctx: &mut RenderCtx,
|
||||
state: UniqueView<EntitiesRenderState>,
|
||||
depth: UniqueView<DepthTexture>,
|
||||
prefabs: UniqueView<GpuPrefabs>,
|
||||
camera_ubo: UniqueView<CameraUniformBuffer>,
|
||||
camera: View<Camera>,
|
||||
settings: UniqueView<GameSettings>,
|
||||
entities: View<Entity>,
|
||||
transform: View<Transform>,
|
||||
) {
|
||||
let mut rpass = ctx.encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
label: Some("rpass_draw_entities"),
|
||||
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: Some(wgpu::RenderPassDepthStencilAttachment {
|
||||
view: &depth.depth_view,
|
||||
depth_ops: Some(wgpu::Operations {
|
||||
load: wgpu::LoadOp::Load,
|
||||
store: wgpu::StoreOp::Store,
|
||||
}),
|
||||
stencil_ops: None,
|
||||
}),
|
||||
..Default::default()
|
||||
});
|
||||
|
||||
rpass.set_pipeline(&state.pipeline);
|
||||
rpass.set_bind_group(0, &prefabs.player_model_diffuse_bind_group, &[]);
|
||||
rpass.set_bind_group(1, &camera_ubo.camera_bind_group, &[]);
|
||||
rpass.set_vertex_buffer(0, prefabs.player_model.vertex.slice(..));
|
||||
rpass.set_index_buffer(prefabs.player_model.index.slice(..), wgpu::IndexFormat::Uint32);
|
||||
rpass.draw_indexed(0..prefabs.player_model.index_len, 0, 0..1);
|
||||
|
||||
// let (camera_id, _camera) = camera.iter().with_id().next().expect("No cameras in the scene");
|
||||
|
||||
// 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 }
|
||||
|
||||
// }
|
||||
}
|
||||
|
|
61
kubi/src/rendering/entities/pipeline.rs
Normal file
61
kubi/src/rendering/entities/pipeline.rs
Normal file
|
@ -0,0 +1,61 @@
|
|||
use shipyard::UniqueView;
|
||||
use wgpu::include_wgsl;
|
||||
use crate::{prefabs::{GpuPrefabs, ModelVertex}, rendering::{camera_uniform::CameraUniformBuffer, Renderer}};
|
||||
|
||||
pub fn init_entities_pipeline(
|
||||
renderer: UniqueView<Renderer>,
|
||||
prefabs: UniqueView<GpuPrefabs>,
|
||||
camera_ubo: UniqueView<CameraUniformBuffer>,
|
||||
) -> wgpu::RenderPipeline {
|
||||
let module = renderer.device().create_shader_module(include_wgsl!("../../../shaders/entities.wgsl"));
|
||||
|
||||
let pipeline_layout = renderer.device().create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
label: Some("entities_pipeline_layout"),
|
||||
bind_group_layouts: &[
|
||||
&prefabs.player_model_diffuse_bind_group_layout,
|
||||
&camera_ubo.camera_bind_group_layout,
|
||||
],
|
||||
push_constant_ranges: &[],
|
||||
});
|
||||
|
||||
renderer.device().create_render_pipeline(&wgpu::RenderPipelineDescriptor {
|
||||
label: Some("entities_pipeline"),
|
||||
layout: Some(&pipeline_layout),
|
||||
vertex: wgpu::VertexState {
|
||||
module: &module,
|
||||
compilation_options: wgpu::PipelineCompilationOptions::default(),
|
||||
entry_point: "vs_main",
|
||||
buffers: &[
|
||||
ModelVertex::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::REPLACE),
|
||||
write_mask: wgpu::ColorWrites::COLOR,
|
||||
})],
|
||||
}),
|
||||
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: Some(wgpu::DepthStencilState {
|
||||
format: wgpu::TextureFormat::Depth32Float,
|
||||
depth_write_enabled: true,
|
||||
depth_compare: wgpu::CompareFunction::Less,
|
||||
bias: wgpu::DepthBiasState::default(),
|
||||
stencil: wgpu::StencilState::default(),
|
||||
}),
|
||||
multisample: wgpu::MultisampleState::default(),
|
||||
multiview: None,
|
||||
})
|
||||
}
|
|
@ -49,7 +49,7 @@ pub fn draw_selection_box(
|
|||
view: &depth.depth_view,
|
||||
depth_ops: Some(wgpu::Operations {
|
||||
load: wgpu::LoadOp::Load,
|
||||
store: wgpu::StoreOp::Discard,
|
||||
store: wgpu::StoreOp::Store,
|
||||
}),
|
||||
stencil_ops: None,
|
||||
}),
|
||||
|
|
|
@ -3,7 +3,7 @@ use shipyard::{AllStoragesView, IntoIter, NonSendSync, Unique, UniqueView, View}
|
|||
use kubi_shared::chunk::CHUNK_SIZE;
|
||||
use crate::{
|
||||
camera::Camera,
|
||||
prefabs::TexturePrefabs,
|
||||
prefabs::GpuPrefabs,
|
||||
world::{ChunkMeshStorage, ChunkStorage},
|
||||
};
|
||||
use super::{camera_uniform::CameraUniformBuffer, depth::DepthTexture, RenderCtx};
|
||||
|
@ -30,7 +30,7 @@ pub fn draw_world(
|
|||
state: UniqueView<WorldRenderState>,
|
||||
camera_ubo: UniqueView<CameraUniformBuffer>,
|
||||
depth: UniqueView<DepthTexture>,
|
||||
textures: UniqueView<TexturePrefabs>,
|
||||
textures: UniqueView<GpuPrefabs>,
|
||||
camera: View<Camera>,
|
||||
chunks: UniqueView<ChunkStorage>,
|
||||
meshes: NonSendSync<UniqueView<ChunkMeshStorage>>,
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use shipyard::UniqueView;
|
||||
use crate::{
|
||||
prefabs::TexturePrefabs,
|
||||
prefabs::GpuPrefabs,
|
||||
rendering::{camera_uniform::CameraUniformBuffer, depth::DepthTexture, world::ChunkVertex, Renderer}
|
||||
};
|
||||
|
||||
pub fn init_world_pipeline(
|
||||
ren: UniqueView<Renderer>,
|
||||
depth: UniqueView<DepthTexture>,
|
||||
textures: UniqueView<TexturePrefabs>,
|
||||
textures: UniqueView<GpuPrefabs>,
|
||||
camera_ubo: UniqueView<CameraUniformBuffer>,
|
||||
) -> wgpu::RenderPipeline {
|
||||
let shader = ren.device().create_shader_module(
|
||||
|
|
Loading…
Reference in a new issue