Provide actual bounds to Shader primitives
... and allow for proper translation and scissoring.
This commit is contained in:
parent
100d15f306
commit
ab7dae554c
8 changed files with 54 additions and 40 deletions
|
|
@ -5,9 +5,7 @@ use scene::Scene;
|
||||||
use iced::executor;
|
use iced::executor;
|
||||||
use iced::time::Instant;
|
use iced::time::Instant;
|
||||||
use iced::widget::shader::wgpu;
|
use iced::widget::shader::wgpu;
|
||||||
use iced::widget::{
|
use iced::widget::{checkbox, column, container, row, shader, slider, text};
|
||||||
checkbox, column, container, row, shader, slider, text, vertical_space,
|
|
||||||
};
|
|
||||||
use iced::window;
|
use iced::window;
|
||||||
use iced::{
|
use iced::{
|
||||||
Alignment, Application, Color, Command, Element, Length, Renderer,
|
Alignment, Application, Color, Command, Element, Length, Renderer,
|
||||||
|
|
@ -138,21 +136,18 @@ impl Application for IcedCubes {
|
||||||
|
|
||||||
let controls = column![top_controls, bottom_controls,]
|
let controls = column![top_controls, bottom_controls,]
|
||||||
.spacing(10)
|
.spacing(10)
|
||||||
|
.padding(20)
|
||||||
.align_items(Alignment::Center);
|
.align_items(Alignment::Center);
|
||||||
|
|
||||||
let shader =
|
let shader =
|
||||||
shader(&self.scene).width(Length::Fill).height(Length::Fill);
|
shader(&self.scene).width(Length::Fill).height(Length::Fill);
|
||||||
|
|
||||||
container(
|
container(column![shader, controls].align_items(Alignment::Center))
|
||||||
column![shader, controls, vertical_space(20),]
|
.width(Length::Fill)
|
||||||
.spacing(40)
|
.height(Length::Fill)
|
||||||
.align_items(Alignment::Center),
|
.center_x()
|
||||||
)
|
.center_y()
|
||||||
.width(Length::Fill)
|
.into()
|
||||||
.height(Length::Fill)
|
|
||||||
.center_x()
|
|
||||||
.center_y()
|
|
||||||
.into()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn subscription(&self) -> Subscription<Self::Message> {
|
fn subscription(&self) -> Subscription<Self::Message> {
|
||||||
|
|
|
||||||
|
|
@ -133,9 +133,9 @@ impl shader::Primitive for Primitive {
|
||||||
format: wgpu::TextureFormat,
|
format: wgpu::TextureFormat,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
queue: &wgpu::Queue,
|
queue: &wgpu::Queue,
|
||||||
|
_bounds: Rectangle,
|
||||||
target_size: Size<u32>,
|
target_size: Size<u32>,
|
||||||
_scale_factor: f32,
|
_scale_factor: f32,
|
||||||
_transform: shader::Transformation,
|
|
||||||
storage: &mut shader::Storage,
|
storage: &mut shader::Storage,
|
||||||
) {
|
) {
|
||||||
if !storage.has::<Pipeline>() {
|
if !storage.has::<Pipeline>() {
|
||||||
|
|
@ -158,9 +158,9 @@ impl shader::Primitive for Primitive {
|
||||||
fn render(
|
fn render(
|
||||||
&self,
|
&self,
|
||||||
storage: &shader::Storage,
|
storage: &shader::Storage,
|
||||||
bounds: Rectangle<u32>,
|
|
||||||
target: &wgpu::TextureView,
|
target: &wgpu::TextureView,
|
||||||
_target_size: Size<u32>,
|
_target_size: Size<u32>,
|
||||||
|
viewport: Rectangle<u32>,
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
) {
|
) {
|
||||||
//at this point our pipeline should always be initialized
|
//at this point our pipeline should always be initialized
|
||||||
|
|
@ -170,7 +170,7 @@ impl shader::Primitive for Primitive {
|
||||||
pipeline.render(
|
pipeline.render(
|
||||||
target,
|
target,
|
||||||
encoder,
|
encoder,
|
||||||
bounds,
|
viewport,
|
||||||
self.cubes.len() as u32,
|
self.cubes.len() as u32,
|
||||||
self.show_depth_buffer,
|
self.show_depth_buffer,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -351,7 +351,7 @@ impl Pipeline {
|
||||||
&self,
|
&self,
|
||||||
target: &wgpu::TextureView,
|
target: &wgpu::TextureView,
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
bounds: Rectangle<u32>,
|
viewport: Rectangle<u32>,
|
||||||
num_cubes: u32,
|
num_cubes: u32,
|
||||||
show_depth: bool,
|
show_depth: bool,
|
||||||
) {
|
) {
|
||||||
|
|
@ -384,10 +384,10 @@ impl Pipeline {
|
||||||
});
|
});
|
||||||
|
|
||||||
pass.set_scissor_rect(
|
pass.set_scissor_rect(
|
||||||
bounds.x,
|
viewport.x,
|
||||||
bounds.y,
|
viewport.y,
|
||||||
bounds.width,
|
viewport.width,
|
||||||
bounds.height,
|
viewport.height,
|
||||||
);
|
);
|
||||||
pass.set_pipeline(&self.pipeline);
|
pass.set_pipeline(&self.pipeline);
|
||||||
pass.set_bind_group(0, &self.uniform_bind_group, &[]);
|
pass.set_bind_group(0, &self.uniform_bind_group, &[]);
|
||||||
|
|
@ -397,7 +397,7 @@ impl Pipeline {
|
||||||
}
|
}
|
||||||
|
|
||||||
if show_depth {
|
if show_depth {
|
||||||
self.depth_pipeline.render(encoder, target, bounds);
|
self.depth_pipeline.render(encoder, target, viewport);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -550,7 +550,7 @@ impl DepthPipeline {
|
||||||
&self,
|
&self,
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
target: &wgpu::TextureView,
|
target: &wgpu::TextureView,
|
||||||
bounds: Rectangle<u32>,
|
viewport: Rectangle<u32>,
|
||||||
) {
|
) {
|
||||||
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||||
label: Some("cubes.pipeline.depth_pass"),
|
label: Some("cubes.pipeline.depth_pass"),
|
||||||
|
|
@ -573,7 +573,12 @@ impl DepthPipeline {
|
||||||
occlusion_query_set: None,
|
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_pipeline(&self.pipeline);
|
||||||
pass.set_bind_group(0, &self.bind_group, &[]);
|
pass.set_bind_group(0, &self.bind_group, &[]);
|
||||||
pass.draw(0..6, 0..1);
|
pass.draw(0..6, 0..1);
|
||||||
|
|
|
||||||
|
|
@ -192,9 +192,9 @@ impl Backend {
|
||||||
format,
|
format,
|
||||||
device,
|
device,
|
||||||
queue,
|
queue,
|
||||||
|
pipeline.bounds,
|
||||||
target_size,
|
target_size,
|
||||||
scale_factor,
|
scale_factor,
|
||||||
transformation,
|
|
||||||
&mut self.pipeline_storage,
|
&mut self.pipeline_storage,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -327,17 +327,17 @@ impl Backend {
|
||||||
let _ = ManuallyDrop::into_inner(render_pass);
|
let _ = ManuallyDrop::into_inner(render_pass);
|
||||||
|
|
||||||
for pipeline in &layer.pipelines {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline.primitive.render(
|
pipeline.primitive.render(
|
||||||
&self.pipeline_storage,
|
&self.pipeline_storage,
|
||||||
bounds,
|
|
||||||
target,
|
target,
|
||||||
target_size,
|
target_size,
|
||||||
|
viewport,
|
||||||
encoder,
|
encoder,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
//! Organize rendering primitives into a flattened list of layers.
|
//! Organize rendering primitives into a flattened list of layers.
|
||||||
mod image;
|
mod image;
|
||||||
|
mod pipeline;
|
||||||
mod text;
|
mod text;
|
||||||
|
|
||||||
pub mod mesh;
|
pub mod mesh;
|
||||||
|
|
||||||
pub use image::Image;
|
pub use image::Image;
|
||||||
pub use mesh::Mesh;
|
pub use mesh::Mesh;
|
||||||
|
pub use pipeline::Pipeline;
|
||||||
pub use text::Text;
|
pub use text::Text;
|
||||||
|
|
||||||
use crate::core;
|
use crate::core;
|
||||||
|
|
@ -36,7 +38,7 @@ pub struct Layer<'a> {
|
||||||
pub images: Vec<Image>,
|
pub images: Vec<Image>,
|
||||||
|
|
||||||
/// The custom pipelines of this [`Layer`].
|
/// The custom pipelines of this [`Layer`].
|
||||||
pub pipelines: Vec<primitive::Pipeline>,
|
pub pipelines: Vec<Pipeline>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Layer<'a> {
|
impl<'a> Layer<'a> {
|
||||||
|
|
@ -314,17 +316,14 @@ impl<'a> Layer<'a> {
|
||||||
},
|
},
|
||||||
primitive::Custom::Pipeline(pipeline) => {
|
primitive::Custom::Pipeline(pipeline) => {
|
||||||
let layer = &mut layers[current_layer];
|
let layer = &mut layers[current_layer];
|
||||||
|
let bounds = pipeline.bounds + translation;
|
||||||
let bounds = Rectangle::new(
|
|
||||||
Point::new(translation.x, translation.y),
|
|
||||||
pipeline.bounds.size(),
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(clip_bounds) =
|
if let Some(clip_bounds) =
|
||||||
layer.bounds.intersection(&bounds)
|
layer.bounds.intersection(&bounds)
|
||||||
{
|
{
|
||||||
layer.pipelines.push(primitive::Pipeline {
|
layer.pipelines.push(Pipeline {
|
||||||
bounds: clip_bounds,
|
bounds,
|
||||||
|
viewport: clip_bounds,
|
||||||
primitive: pipeline.primitive.clone(),
|
primitive: pipeline.primitive.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
17
wgpu/src/layer/pipeline.rs
Normal file
17
wgpu/src/layer/pipeline.rs
Normal file
|
|
@ -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>,
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
//! Draw primitives using custom pipelines.
|
//! Draw primitives using custom pipelines.
|
||||||
use crate::core::{Rectangle, Size};
|
use crate::core::{Rectangle, Size};
|
||||||
use crate::graphics::Transformation;
|
|
||||||
|
|
||||||
use std::any::{Any, TypeId};
|
use std::any::{Any, TypeId};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
@ -41,9 +40,9 @@ pub trait Primitive: Debug + Send + Sync + 'static {
|
||||||
format: wgpu::TextureFormat,
|
format: wgpu::TextureFormat,
|
||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
queue: &wgpu::Queue,
|
queue: &wgpu::Queue,
|
||||||
|
bounds: Rectangle,
|
||||||
target_size: Size<u32>,
|
target_size: Size<u32>,
|
||||||
scale_factor: f32,
|
scale_factor: f32,
|
||||||
transform: Transformation,
|
|
||||||
storage: &mut Storage,
|
storage: &mut Storage,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -51,9 +50,9 @@ pub trait Primitive: Debug + Send + Sync + 'static {
|
||||||
fn render(
|
fn render(
|
||||||
&self,
|
&self,
|
||||||
storage: &Storage,
|
storage: &Storage,
|
||||||
bounds: Rectangle<u32>,
|
|
||||||
target: &wgpu::TextureView,
|
target: &wgpu::TextureView,
|
||||||
target_size: Size<u32>,
|
target_size: Size<u32>,
|
||||||
|
viewport: Rectangle<u32>,
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ use crate::renderer::wgpu::primitive::pipeline;
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
pub use crate::graphics::Transformation;
|
|
||||||
pub use crate::renderer::wgpu::wgpu;
|
pub use crate::renderer::wgpu::wgpu;
|
||||||
pub use pipeline::{Primitive, Storage};
|
pub use pipeline::{Primitive, Storage};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue