Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide actual bounds to Shader primitives #2149

Merged
merged 1 commit into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 8 additions & 13 deletions examples/custom_shader/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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<Self::Message> {
Expand Down
6 changes: 3 additions & 3 deletions examples/custom_shader/src/scene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ impl shader::Primitive for Primitive {
format: wgpu::TextureFormat,
device: &wgpu::Device,
queue: &wgpu::Queue,
_bounds: Rectangle,
target_size: Size<u32>,
_scale_factor: f32,
_transform: shader::Transformation,
storage: &mut shader::Storage,
) {
if !storage.has::<Pipeline>() {
Expand All @@ -158,9 +158,9 @@ impl shader::Primitive for Primitive {
fn render(
&self,
storage: &shader::Storage,
bounds: Rectangle<u32>,
target: &wgpu::TextureView,
_target_size: Size<u32>,
viewport: Rectangle<u32>,
encoder: &mut wgpu::CommandEncoder,
) {
//at this point our pipeline should always be initialized
Expand All @@ -170,7 +170,7 @@ impl shader::Primitive for Primitive {
pipeline.render(
target,
encoder,
bounds,
viewport,
self.cubes.len() as u32,
self.show_depth_buffer,
);
Expand Down
21 changes: 13 additions & 8 deletions examples/custom_shader/src/scene/pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ impl Pipeline {
&self,
target: &wgpu::TextureView,
encoder: &mut wgpu::CommandEncoder,
bounds: Rectangle<u32>,
viewport: Rectangle<u32>,
num_cubes: u32,
show_depth: bool,
) {
Expand Down Expand Up @@ -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, &[]);
Expand All @@ -397,7 +397,7 @@ impl Pipeline {
}

if show_depth {
self.depth_pipeline.render(encoder, target, bounds);
self.depth_pipeline.render(encoder, target, viewport);
}
}
}
Expand Down Expand Up @@ -550,7 +550,7 @@ impl DepthPipeline {
&self,
encoder: &mut wgpu::CommandEncoder,
target: &wgpu::TextureView,
bounds: Rectangle<u32>,
viewport: Rectangle<u32>,
) {
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
label: Some("cubes.pipeline.depth_pass"),
Expand All @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions wgpu/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,9 +192,9 @@ impl Backend {
format,
device,
queue,
pipeline.bounds,
target_size,
scale_factor,
transformation,
&mut self.pipeline_storage,
);
}
Expand Down Expand Up @@ -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,
);
}
Expand Down
15 changes: 7 additions & 8 deletions wgpu/src/layer.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -36,7 +38,7 @@ pub struct Layer<'a> {
pub images: Vec<Image>,

/// The custom pipelines of this [`Layer`].
pub pipelines: Vec<primitive::Pipeline>,
pub pipelines: Vec<Pipeline>,
}

impl<'a> Layer<'a> {
Expand Down Expand Up @@ -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(),
});
}
Expand Down
17 changes: 17 additions & 0 deletions wgpu/src/layer/pipeline.rs
Original file line number Diff line number Diff line change
@@ -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<dyn Primitive>,
}
5 changes: 2 additions & 3 deletions wgpu/src/primitive/pipeline.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -41,19 +40,19 @@ pub trait Primitive: Debug + Send + Sync + 'static {
format: wgpu::TextureFormat,
device: &wgpu::Device,
queue: &wgpu::Queue,
bounds: Rectangle,
target_size: Size<u32>,
scale_factor: f32,
transform: Transformation,
storage: &mut Storage,
);

/// Renders the [`Primitive`].
fn render(
&self,
storage: &Storage,
bounds: Rectangle<u32>,
target: &wgpu::TextureView,
target_size: Size<u32>,
viewport: Rectangle<u32>,
encoder: &mut wgpu::CommandEncoder,
);
}
Expand Down
1 change: 0 additions & 1 deletion widget/src/shader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
Loading