summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/geometry/src/main.rs1
-rw-r--r--wgpu/src/primitive.rs9
-rw-r--r--wgpu/src/renderer.rs36
-rw-r--r--wgpu/src/triangle.rs23
-rw-r--r--wgpu/src/widget/canvas/frame.rs1
5 files changed, 45 insertions, 25 deletions
diff --git a/examples/geometry/src/main.rs b/examples/geometry/src/main.rs
index 63e1bacd..795cac27 100644
--- a/examples/geometry/src/main.rs
+++ b/examples/geometry/src/main.rs
@@ -88,6 +88,7 @@ mod rainbow {
Primitive::Translate {
translation: Vector::new(b.x, b.y),
content: Box::new(Primitive::Mesh2D {
+ size: b.size(),
buffers: Mesh2D {
vertices: vec![
Vertex2D {
diff --git a/wgpu/src/primitive.rs b/wgpu/src/primitive.rs
index e9c0bf46..e73227ef 100644
--- a/wgpu/src/primitive.rs
+++ b/wgpu/src/primitive.rs
@@ -1,5 +1,5 @@
use iced_native::{
- image, svg, Background, Color, Font, HorizontalAlignment, Rectangle,
+ image, svg, Background, Color, Font, HorizontalAlignment, Rectangle, Size,
Vector, VerticalAlignment,
};
@@ -72,7 +72,7 @@ pub enum Primitive {
},
/// A primitive that applies a translation
Translate {
- /// The top-left coordinate of the mesh
+ /// The translation vector
translation: Vector,
/// The primitive to translate
@@ -82,6 +82,11 @@ pub enum Primitive {
///
/// It can be used to render many kinds of geometry freely.
Mesh2D {
+ /// The size of the drawable region of the mesh.
+ ///
+ /// Any geometry that falls out of this region will be clipped.
+ size: Size,
+
/// The vertex and index buffers of the mesh
buffers: triangle::Mesh2D,
},
diff --git a/wgpu/src/renderer.rs b/wgpu/src/renderer.rs
index e93532bc..5c38ce61 100644
--- a/wgpu/src/renderer.rs
+++ b/wgpu/src/renderer.rs
@@ -29,7 +29,7 @@ pub struct Renderer {
struct Layer<'a> {
bounds: Rectangle<u32>,
quads: Vec<Quad>,
- meshes: Vec<(Vector, &'a triangle::Mesh2D)>,
+ meshes: Vec<(Vector, Rectangle<u32>, &'a triangle::Mesh2D)>,
text: Vec<wgpu_glyph::Section<'a>>,
#[cfg(any(feature = "image", feature = "svg"))]
@@ -48,6 +48,12 @@ impl<'a> Layer<'a> {
images: Vec::new(),
}
}
+
+ pub fn intersection(&self, rectangle: Rectangle) -> Option<Rectangle<u32>> {
+ let layer_bounds: Rectangle<f32> = self.bounds.into();
+
+ layer_bounds.intersection(&rectangle).map(Into::into)
+ }
}
impl Renderer {
@@ -214,10 +220,20 @@ impl Renderer {
border_color: border_color.into_linear(),
});
}
- Primitive::Mesh2D { buffers } => {
+ Primitive::Mesh2D { size, buffers } => {
let layer = layers.last_mut().unwrap();
- layer.meshes.push((translation, buffers));
+ // Only draw visible content
+ if let Some(clip_bounds) = layer.intersection(Rectangle::new(
+ Point::new(translation.x, translation.y),
+ *size,
+ )) {
+ layer.meshes.push((
+ translation,
+ clip_bounds.into(),
+ buffers,
+ ));
+ }
}
Primitive::Clip {
bounds,
@@ -226,16 +242,10 @@ impl Renderer {
} => {
let layer = layers.last_mut().unwrap();
- let layer_bounds: Rectangle<f32> = layer.bounds.into();
-
- let clip = Rectangle {
- x: bounds.x + translation.x,
- y: bounds.y + translation.y,
- ..*bounds
- };
-
// Only draw visible content
- if let Some(clip_bounds) = layer_bounds.intersection(&clip) {
+ if let Some(clip_bounds) =
+ layer.intersection(*bounds + translation)
+ {
let clip_layer = Layer::new(clip_bounds.into());
let new_layer = Layer::new(layer.bounds);
@@ -356,8 +366,8 @@ impl Renderer {
target_width,
target_height,
scaled,
+ scale_factor,
&layer.meshes,
- bounds,
);
}
diff --git a/wgpu/src/triangle.rs b/wgpu/src/triangle.rs
index b58cc03c..246dc7ce 100644
--- a/wgpu/src/triangle.rs
+++ b/wgpu/src/triangle.rs
@@ -201,15 +201,15 @@ impl Pipeline {
target_width: u32,
target_height: u32,
transformation: Transformation,
- meshes: &[(Vector, &Mesh2D)],
- bounds: Rectangle<u32>,
+ scale_factor: f32,
+ meshes: &[(Vector, Rectangle<u32>, &Mesh2D)],
) {
// This looks a bit crazy, but we are just counting how many vertices
// and indices we will need to handle.
// TODO: Improve readability
let (total_vertices, total_indices) = meshes
.iter()
- .map(|(_, mesh)| (mesh.vertices.len(), mesh.indices.len()))
+ .map(|(_, _, mesh)| (mesh.vertices.len(), mesh.indices.len()))
.fold((0, 0), |(total_v, total_i), (v, i)| {
(total_v + v, total_i + i)
});
@@ -230,7 +230,7 @@ impl Pipeline {
let mut last_index = 0;
// We upload everything upfront
- for (origin, mesh) in meshes {
+ for (origin, _, mesh) in meshes {
let transform = (transformation
* Transformation::translate(origin.x, origin.y))
.into();
@@ -316,16 +316,19 @@ impl Pipeline {
});
render_pass.set_pipeline(&self.pipeline);
- render_pass.set_scissor_rect(
- bounds.x,
- bounds.y,
- bounds.width,
- bounds.height,
- );
for (i, (vertex_offset, index_offset, indices)) in
offsets.into_iter().enumerate()
{
+ let bounds = meshes[i].1 * scale_factor;
+
+ render_pass.set_scissor_rect(
+ bounds.x,
+ bounds.y,
+ bounds.width,
+ bounds.height,
+ );
+
render_pass.set_bind_group(
0,
&self.constants,
diff --git a/wgpu/src/widget/canvas/frame.rs b/wgpu/src/widget/canvas/frame.rs
index 8623ce4d..1c4a038a 100644
--- a/wgpu/src/widget/canvas/frame.rs
+++ b/wgpu/src/widget/canvas/frame.rs
@@ -267,6 +267,7 @@ impl Frame {
pub fn into_geometry(mut self) -> Geometry {
if !self.buffers.indices.is_empty() {
self.primitives.push(Primitive::Mesh2D {
+ size: self.size,
buffers: triangle::Mesh2D {
vertices: self.buffers.vertices,
indices: self.buffers.indices,