diff --git a/examples/custom_shader/src/main.rs b/examples/custom_shader/src/main.rs index 2eb1ac4a97..3bfa3a433a 100644 --- a/examples/custom_shader/src/main.rs +++ b/examples/custom_shader/src/main.rs @@ -5,9 +5,7 @@ use scene::Scene; use iced::executor; use iced::time::Instant; use iced::widget::shader::wgpu; -use iced::widget::{ - checkbox, column, container, row, shader, slider, text, vertical_space, -}; +use iced::widget::{checkbox, column, container, row, shader, slider, text}; use iced::window; use iced::{ Alignment, Application, Color, Command, Element, Length, Renderer, @@ -138,21 +136,18 @@ impl Application for IcedCubes { let controls = column![top_controls, bottom_controls,] .spacing(10) + .padding(20) .align_items(Alignment::Center); let shader = shader(&self.scene).width(Length::Fill).height(Length::Fill); - container( - column![shader, controls, vertical_space(20),] - .spacing(40) - .align_items(Alignment::Center), - ) - .width(Length::Fill) - .height(Length::Fill) - .center_x() - .center_y() - .into() + container(column![shader, controls].align_items(Alignment::Center)) + .width(Length::Fill) + .height(Length::Fill) + .center_x() + .center_y() + .into() } fn subscription(&self) -> Subscription { diff --git a/examples/custom_shader/src/scene.rs b/examples/custom_shader/src/scene.rs index 3b291ce225..a35efdd935 100644 --- a/examples/custom_shader/src/scene.rs +++ b/examples/custom_shader/src/scene.rs @@ -133,9 +133,9 @@ impl shader::Primitive for Primitive { format: wgpu::TextureFormat, device: &wgpu::Device, queue: &wgpu::Queue, + _bounds: Rectangle, target_size: Size, _scale_factor: f32, - _transform: shader::Transformation, storage: &mut shader::Storage, ) { if !storage.has::() { @@ -158,9 +158,9 @@ impl shader::Primitive for Primitive { fn render( &self, storage: &shader::Storage, - bounds: Rectangle, target: &wgpu::TextureView, _target_size: Size, + viewport: Rectangle, encoder: &mut wgpu::CommandEncoder, ) { //at this point our pipeline should always be initialized @@ -170,7 +170,7 @@ impl shader::Primitive for Primitive { pipeline.render( target, encoder, - bounds, + viewport, self.cubes.len() as u32, self.show_depth_buffer, ); diff --git a/examples/custom_shader/src/scene/pipeline.rs b/examples/custom_shader/src/scene/pipeline.rs index 94c6c56280..124b421f29 100644 --- a/examples/custom_shader/src/scene/pipeline.rs +++ b/examples/custom_shader/src/scene/pipeline.rs @@ -351,7 +351,7 @@ impl Pipeline { &self, target: &wgpu::TextureView, encoder: &mut wgpu::CommandEncoder, - bounds: Rectangle, + viewport: Rectangle, num_cubes: u32, show_depth: bool, ) { @@ -384,10 +384,10 @@ impl Pipeline { }); pass.set_scissor_rect( - bounds.x, - bounds.y, - bounds.width, - bounds.height, + viewport.x, + viewport.y, + viewport.width, + viewport.height, ); pass.set_pipeline(&self.pipeline); pass.set_bind_group(0, &self.uniform_bind_group, &[]); @@ -397,7 +397,7 @@ impl Pipeline { } if show_depth { - self.depth_pipeline.render(encoder, target, bounds); + self.depth_pipeline.render(encoder, target, viewport); } } } @@ -550,7 +550,7 @@ impl DepthPipeline { &self, encoder: &mut wgpu::CommandEncoder, target: &wgpu::TextureView, - bounds: Rectangle, + viewport: Rectangle, ) { let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { label: Some("cubes.pipeline.depth_pass"), @@ -573,7 +573,12 @@ impl DepthPipeline { occlusion_query_set: None, }); - pass.set_scissor_rect(bounds.x, bounds.y, bounds.width, bounds.height); + pass.set_scissor_rect( + viewport.x, + viewport.y, + viewport.width, + viewport.height, + ); pass.set_pipeline(&self.pipeline); pass.set_bind_group(0, &self.bind_group, &[]); pass.draw(0..6, 0..1); diff --git a/wgpu/src/backend.rs b/wgpu/src/backend.rs index 88caad0606..25134d6869 100644 --- a/wgpu/src/backend.rs +++ b/wgpu/src/backend.rs @@ -192,9 +192,9 @@ impl Backend { format, device, queue, + pipeline.bounds, target_size, scale_factor, - transformation, &mut self.pipeline_storage, ); } @@ -327,17 +327,17 @@ impl Backend { let _ = ManuallyDrop::into_inner(render_pass); for pipeline in &layer.pipelines { - let bounds = (pipeline.bounds * scale_factor).snap(); + let viewport = (pipeline.viewport * scale_factor).snap(); - if bounds.width < 1 || bounds.height < 1 { + if viewport.width < 1 || viewport.height < 1 { continue; } pipeline.primitive.render( &self.pipeline_storage, - bounds, target, target_size, + viewport, encoder, ); } diff --git a/wgpu/src/layer.rs b/wgpu/src/layer.rs index 33aaf67070..98e49f1af7 100644 --- a/wgpu/src/layer.rs +++ b/wgpu/src/layer.rs @@ -1,11 +1,13 @@ //! Organize rendering primitives into a flattened list of layers. mod image; +mod pipeline; mod text; pub mod mesh; pub use image::Image; pub use mesh::Mesh; +pub use pipeline::Pipeline; pub use text::Text; use crate::core; @@ -36,7 +38,7 @@ pub struct Layer<'a> { pub images: Vec, /// The custom pipelines of this [`Layer`]. - pub pipelines: Vec, + pub pipelines: Vec, } impl<'a> Layer<'a> { @@ -314,17 +316,14 @@ impl<'a> Layer<'a> { }, primitive::Custom::Pipeline(pipeline) => { let layer = &mut layers[current_layer]; - - let bounds = Rectangle::new( - Point::new(translation.x, translation.y), - pipeline.bounds.size(), - ); + let bounds = pipeline.bounds + translation; if let Some(clip_bounds) = layer.bounds.intersection(&bounds) { - layer.pipelines.push(primitive::Pipeline { - bounds: clip_bounds, + layer.pipelines.push(Pipeline { + bounds, + viewport: clip_bounds, primitive: pipeline.primitive.clone(), }); } diff --git a/wgpu/src/layer/pipeline.rs b/wgpu/src/layer/pipeline.rs new file mode 100644 index 0000000000..6dfe67503c --- /dev/null +++ b/wgpu/src/layer/pipeline.rs @@ -0,0 +1,17 @@ +use crate::core::Rectangle; +use crate::primitive::pipeline::Primitive; + +use std::sync::Arc; + +#[derive(Clone, Debug)] +/// A custom primitive which can be used to render primitives associated with a custom pipeline. +pub struct Pipeline { + /// The bounds of the [`Pipeline`]. + pub bounds: Rectangle, + + /// The viewport of the [`Pipeline`]. + pub viewport: Rectangle, + + /// The [`Primitive`] to render. + pub primitive: Arc, +} diff --git a/wgpu/src/primitive/pipeline.rs b/wgpu/src/primitive/pipeline.rs index 5dbd6697b6..302e38f68f 100644 --- a/wgpu/src/primitive/pipeline.rs +++ b/wgpu/src/primitive/pipeline.rs @@ -1,6 +1,5 @@ //! Draw primitives using custom pipelines. use crate::core::{Rectangle, Size}; -use crate::graphics::Transformation; use std::any::{Any, TypeId}; use std::collections::HashMap; @@ -41,9 +40,9 @@ pub trait Primitive: Debug + Send + Sync + 'static { format: wgpu::TextureFormat, device: &wgpu::Device, queue: &wgpu::Queue, + bounds: Rectangle, target_size: Size, scale_factor: f32, - transform: Transformation, storage: &mut Storage, ); @@ -51,9 +50,9 @@ pub trait Primitive: Debug + Send + Sync + 'static { fn render( &self, storage: &Storage, - bounds: Rectangle, target: &wgpu::TextureView, target_size: Size, + viewport: Rectangle, encoder: &mut wgpu::CommandEncoder, ); } diff --git a/widget/src/shader.rs b/widget/src/shader.rs index ca140627d7..fe6214db52 100644 --- a/widget/src/shader.rs +++ b/widget/src/shader.rs @@ -17,7 +17,6 @@ use crate::renderer::wgpu::primitive::pipeline; use std::marker::PhantomData; -pub use crate::graphics::Transformation; pub use crate::renderer::wgpu::wgpu; pub use pipeline::{Primitive, Storage};