diff options
Diffstat (limited to 'examples/custom_shader/src/primitive.rs')
-rw-r--r-- | examples/custom_shader/src/primitive.rs | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/examples/custom_shader/src/primitive.rs b/examples/custom_shader/src/primitive.rs new file mode 100644 index 00000000..2201218f --- /dev/null +++ b/examples/custom_shader/src/primitive.rs @@ -0,0 +1,95 @@ +pub mod cube; +pub mod vertex; + +mod buffer; +mod uniforms; + +use crate::camera::Camera; +use crate::pipeline::Pipeline; +use crate::primitive::cube::Cube; +use iced::advanced::graphics::Transformation; +use iced::widget::shader; +use iced::{Color, Rectangle, Size}; + +pub use crate::primitive::vertex::Vertex; +pub use buffer::Buffer; +pub use uniforms::Uniforms; + +/// 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, + ) + } +} |