Improve module hierarchy of custom_shader example

This commit is contained in:
Héctor Ramón Jiménez 2023-11-14 15:48:01 +01:00
parent b1b2467b45
commit 811aa673e9
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
10 changed files with 122 additions and 126 deletions

View file

@ -1,11 +1,6 @@
mod camera;
mod pipeline;
mod primitive;
mod scene;
use crate::camera::Camera;
use crate::pipeline::Pipeline;
use crate::scene::Scene;
use scene::Scene;
use iced::executor;
use iced::time::Instant;

View file

@ -1,97 +0,0 @@
pub mod cube;
pub mod vertex;
mod buffer;
mod uniforms;
pub use buffer::Buffer;
pub use cube::Cube;
pub use uniforms::Uniforms;
pub use vertex::Vertex;
use crate::wgpu;
use crate::Camera;
use crate::Pipeline;
use iced::advanced::graphics::Transformation;
use iced::widget::shader;
use iced::{Color, Rectangle, Size};
/// A collection of `Cube`s that can be rendered.
#[derive(Debug)]
pub struct Primitive {
cubes: Vec<cube::Raw>,
uniforms: Uniforms,
show_depth_buffer: bool,
}
impl Primitive {
pub fn new(
cubes: &[Cube],
camera: &Camera,
bounds: Rectangle,
show_depth_buffer: bool,
light_color: Color,
) -> Self {
let uniforms = Uniforms::new(camera, bounds, light_color);
Self {
cubes: cubes
.iter()
.map(cube::Raw::from_cube)
.collect::<Vec<cube::Raw>>(),
uniforms,
show_depth_buffer,
}
}
}
impl shader::Primitive for Primitive {
fn prepare(
&self,
format: wgpu::TextureFormat,
device: &wgpu::Device,
queue: &wgpu::Queue,
target_size: Size<u32>,
_scale_factor: f32,
_transform: Transformation,
storage: &mut shader::Storage,
) {
if !storage.has::<Pipeline>() {
storage.store(Pipeline::new(device, queue, format, target_size));
}
let pipeline = storage.get_mut::<Pipeline>().unwrap();
//upload data to GPU
pipeline.update(
device,
queue,
target_size,
&self.uniforms,
self.cubes.len(),
&self.cubes,
);
}
fn render(
&self,
storage: &shader::Storage,
bounds: Rectangle<u32>,
target: &wgpu::TextureView,
_target_size: Size<u32>,
encoder: &mut wgpu::CommandEncoder,
) {
//at this point our pipeline should always be initialized
let pipeline = storage.get::<Pipeline>().unwrap();
//render primitive
pipeline.render(
target,
encoder,
bounds,
self.cubes.len() as u32,
self.show_depth_buffer,
);
}
}

View file

@ -1,13 +1,21 @@
use crate::camera::Camera;
use crate::primitive;
use crate::primitive::cube::Cube;
use glam::Vec3;
mod camera;
mod pipeline;
use camera::Camera;
use pipeline::Pipeline;
use crate::wgpu;
use pipeline::cube::{self, Cube};
use iced::mouse;
use iced::time::Duration;
use iced::widget::shader;
use iced::{mouse, Color, Rectangle};
use iced::{Color, Rectangle, Size};
use glam::Vec3;
use rand::Rng;
use std::cmp::Ordering;
use std::iter;
use std::time::Duration;
pub const MAX: u32 = 500;
@ -72,7 +80,7 @@ impl Scene {
impl<Message> shader::Program<Message> for Scene {
type State = ();
type Primitive = primitive::Primitive;
type Primitive = Primitive;
fn draw(
&self,
@ -80,7 +88,7 @@ impl<Message> shader::Program<Message> for Scene {
_cursor: mouse::Cursor,
bounds: Rectangle,
) -> Self::Primitive {
primitive::Primitive::new(
Primitive::new(
&self.cubes,
&self.camera,
bounds,
@ -90,6 +98,85 @@ impl<Message> shader::Program<Message> for Scene {
}
}
/// A collection of `Cube`s that can be rendered.
#[derive(Debug)]
pub struct Primitive {
cubes: Vec<cube::Raw>,
uniforms: pipeline::Uniforms,
show_depth_buffer: bool,
}
impl Primitive {
pub fn new(
cubes: &[Cube],
camera: &Camera,
bounds: Rectangle,
show_depth_buffer: bool,
light_color: Color,
) -> Self {
let uniforms = pipeline::Uniforms::new(camera, bounds, light_color);
Self {
cubes: cubes
.iter()
.map(cube::Raw::from_cube)
.collect::<Vec<cube::Raw>>(),
uniforms,
show_depth_buffer,
}
}
}
impl shader::Primitive for Primitive {
fn prepare(
&self,
format: wgpu::TextureFormat,
device: &wgpu::Device,
queue: &wgpu::Queue,
target_size: Size<u32>,
_scale_factor: f32,
_transform: shader::Transformation,
storage: &mut shader::Storage,
) {
if !storage.has::<Pipeline>() {
storage.store(Pipeline::new(device, queue, format, target_size));
}
let pipeline = storage.get_mut::<Pipeline>().unwrap();
//upload data to GPU
pipeline.update(
device,
queue,
target_size,
&self.uniforms,
self.cubes.len(),
&self.cubes,
);
}
fn render(
&self,
storage: &shader::Storage,
bounds: Rectangle<u32>,
target: &wgpu::TextureView,
_target_size: Size<u32>,
encoder: &mut wgpu::CommandEncoder,
) {
//at this point our pipeline should always be initialized
let pipeline = storage.get::<Pipeline>().unwrap();
//render primitive
pipeline.render(
target,
encoder,
bounds,
self.cubes.len() as u32,
self.show_depth_buffer,
);
}
}
fn rnd_origin() -> Vec3 {
Vec3::new(
rand::thread_rng().gen_range(-4.0..4.0),

View file

@ -1,6 +1,15 @@
use crate::primitive;
use crate::primitive::cube;
use crate::primitive::{Buffer, Uniforms};
pub mod cube;
mod buffer;
mod uniforms;
mod vertex;
pub use cube::Cube;
pub use uniforms::Uniforms;
use buffer::Buffer;
use vertex::Vertex;
use crate::wgpu;
use crate::wgpu::util::DeviceExt;
@ -221,7 +230,7 @@ impl Pipeline {
device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("cubes shader"),
source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(
include_str!("shaders/cubes.wgsl"),
include_str!("../shaders/cubes.wgsl"),
)),
});
@ -232,7 +241,7 @@ impl Pipeline {
vertex: wgpu::VertexState {
module: &shader,
entry_point: "vs_main",
buffers: &[primitive::Vertex::desc(), cube::Raw::desc()],
buffers: &[Vertex::desc(), cube::Raw::desc()],
},
primitive: wgpu::PrimitiveState::default(),
depth_stencil: Some(wgpu::DepthStencilState {
@ -468,7 +477,7 @@ impl DepthPipeline {
device.create_shader_module(wgpu::ShaderModuleDescriptor {
label: Some("cubes.depth_pipeline.shader"),
source: wgpu::ShaderSource::Wgsl(std::borrow::Cow::Borrowed(
include_str!("shaders/depth.wgsl"),
include_str!("../shaders/depth.wgsl"),
)),
});
@ -573,12 +582,12 @@ impl DepthPipeline {
}
fn load_skybox_data() -> Vec<u8> {
let pos_x: &[u8] = include_bytes!("textures/skybox/pos_x.jpg");
let neg_x: &[u8] = include_bytes!("textures/skybox/neg_x.jpg");
let pos_y: &[u8] = include_bytes!("textures/skybox/pos_y.jpg");
let neg_y: &[u8] = include_bytes!("textures/skybox/neg_y.jpg");
let pos_z: &[u8] = include_bytes!("textures/skybox/pos_z.jpg");
let neg_z: &[u8] = include_bytes!("textures/skybox/neg_z.jpg");
let pos_x: &[u8] = include_bytes!("../textures/skybox/pos_x.jpg");
let neg_x: &[u8] = include_bytes!("../textures/skybox/neg_x.jpg");
let pos_y: &[u8] = include_bytes!("../textures/skybox/pos_y.jpg");
let neg_y: &[u8] = include_bytes!("../textures/skybox/neg_y.jpg");
let pos_z: &[u8] = include_bytes!("../textures/skybox/pos_z.jpg");
let neg_z: &[u8] = include_bytes!("../textures/skybox/neg_z.jpg");
let data: [&[u8]; 6] = [pos_x, neg_x, pos_y, neg_y, pos_z, neg_z];
@ -597,7 +606,7 @@ fn load_skybox_data() -> Vec<u8> {
}
fn load_normal_map_data() -> Vec<u8> {
let bytes: &[u8] = include_bytes!("textures/ice_cube_normal_map.png");
let bytes: &[u8] = include_bytes!("../textures/ice_cube_normal_map.png");
image::load_from_memory_with_format(bytes, image::ImageFormat::Png)
.unwrap()

View file

@ -1,4 +1,4 @@
use crate::primitive::Vertex;
use crate::scene::pipeline::Vertex;
use crate::wgpu;
use glam::{vec2, vec3, Vec3};

View file

@ -1,4 +1,5 @@
use crate::camera::Camera;
use crate::scene::Camera;
use iced::{Color, Rectangle};
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]