From 781ef1f94c4859aeeb852f801b72be095b8ff82b Mon Sep 17 00:00:00 2001 From: Bingus Date: Thu, 14 Sep 2023 13:58:36 -0700 Subject: Added support for custom shader widget for iced_wgpu backend. --- examples/custom_shader/src/primitive.rs | 95 +++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 examples/custom_shader/src/primitive.rs (limited to 'examples/custom_shader/src/primitive.rs') 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, + 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::>(), + uniforms, + show_depth_buffer, + } + } +} + +impl shader::Primitive for Primitive { + fn prepare( + &self, + format: wgpu::TextureFormat, + device: &wgpu::Device, + queue: &wgpu::Queue, + target_size: Size, + _scale_factor: f32, + _transform: Transformation, + storage: &mut shader::Storage, + ) { + if !storage.has::() { + storage.store(Pipeline::new(device, queue, format, target_size)) + } + + let pipeline = storage.get_mut::().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, + target: &wgpu::TextureView, + _target_size: Size, + encoder: &mut wgpu::CommandEncoder, + ) { + //at this point our pipeline should always be initialized + let pipeline = storage.get::().unwrap(); + + //render primitive + pipeline.render( + target, + encoder, + bounds, + self.cubes.len() as u32, + self.show_depth_buffer, + ) + } +} -- cgit