Skip to content

Commit

Permalink
Decouple Mesh primitives from main Primitive type
Browse files Browse the repository at this point in the history
  • Loading branch information
hecrj committed Jun 29, 2023
1 parent 2128472 commit fa5650c
Show file tree
Hide file tree
Showing 15 changed files with 248 additions and 205 deletions.
27 changes: 13 additions & 14 deletions examples/geometry/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
//! arbitrary low-level geometry.
mod rainbow {
use iced::advanced::graphics::color;
use iced::advanced::graphics::primitive::{ColoredVertex2D, Primitive};
use iced::advanced::layout::{self, Layout};
use iced::advanced::renderer;
use iced::advanced::widget::{self, Widget};
Expand Down Expand Up @@ -45,7 +44,7 @@ mod rainbow {
cursor: mouse::Cursor,
_viewport: &Rectangle,
) {
use iced::advanced::graphics::primitive::Mesh2D;
use iced::advanced::graphics::mesh::{self, Mesh, SolidVertex2D};
use iced::advanced::Renderer as _;

let bounds = layout.bounds();
Expand Down Expand Up @@ -77,43 +76,43 @@ mod rainbow {
let posn_bl = [0.0, bounds.height];
let posn_l = [0.0, bounds.height / 2.0];

let mesh = Primitive::SolidMesh {
let mesh = Mesh::Solid {
size: bounds.size(),
buffers: Mesh2D {
buffers: mesh::Indexed {
vertices: vec![
ColoredVertex2D {
SolidVertex2D {
position: posn_center,
color: color::pack([1.0, 1.0, 1.0, 1.0]),
},
ColoredVertex2D {
SolidVertex2D {
position: posn_tl,
color: color::pack(color_r),
},
ColoredVertex2D {
SolidVertex2D {
position: posn_t,
color: color::pack(color_o),
},
ColoredVertex2D {
SolidVertex2D {
position: posn_tr,
color: color::pack(color_y),
},
ColoredVertex2D {
SolidVertex2D {
position: posn_r,
color: color::pack(color_g),
},
ColoredVertex2D {
SolidVertex2D {
position: posn_br,
color: color::pack(color_gb),
},
ColoredVertex2D {
SolidVertex2D {
position: posn_b,
color: color::pack(color_b),
},
ColoredVertex2D {
SolidVertex2D {
position: posn_bl,
color: color::pack(color_i),
},
ColoredVertex2D {
SolidVertex2D {
position: posn_l,
color: color::pack(color_v),
},
Expand All @@ -134,7 +133,7 @@ mod rainbow {
renderer.with_translation(
Vector::new(bounds.x, bounds.y),
|renderer| {
renderer.draw_with_wgpu(mesh);
renderer.draw_mesh(mesh);
},
);
}
Expand Down
3 changes: 0 additions & 3 deletions graphics/src/damage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,6 @@ impl<T: Damage> Damage for Primitive<T> {
| Self::Image { bounds, .. }
| Self::Svg { bounds, .. } => bounds.expand(1.0),
Self::Clip { bounds, .. } => bounds.expand(1.0),
Self::SolidMesh { size, .. } | Self::GradientMesh { size, .. } => {
Rectangle::with_size(*size)
}
Self::Group { primitives } => primitives
.iter()
.map(Self::bounds)
Expand Down
3 changes: 2 additions & 1 deletion graphics/src/gradient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::color;
use crate::core::gradient::ColorStop;
use crate::core::{self, Color, Point, Rectangle};

use bytemuck::{Pod, Zeroable};
use half::f16;
use std::cmp::Ordering;

Expand Down Expand Up @@ -135,7 +136,7 @@ impl Linear {
}

/// Packed [`Gradient`] data for use in shader code.
#[derive(Debug, Copy, Clone, PartialEq)]
#[derive(Debug, Copy, Clone, PartialEq, Zeroable, Pod)]
#[repr(C)]
pub struct Packed {
// 8 colors, each channel = 16 bit float, 2 colors packed into 1 u32
Expand Down
2 changes: 2 additions & 0 deletions graphics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub mod color;
pub mod compositor;
pub mod damage;
pub mod gradient;
pub mod mesh;
pub mod primitive;
pub mod renderer;

Expand All @@ -46,6 +47,7 @@ pub use compositor::Compositor;
pub use damage::Damage;
pub use error::Error;
pub use gradient::Gradient;
pub use mesh::Mesh;
pub use primitive::Primitive;
pub use renderer::Renderer;
pub use transformation::Transformation;
Expand Down
75 changes: 75 additions & 0 deletions graphics/src/mesh.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
use crate::color;
use crate::core::{Rectangle, Size};
use crate::gradient;
use crate::Damage;

use bytemuck::{Pod, Zeroable};

/// A low-level primitive to render a mesh of triangles.
#[derive(Debug, Clone, PartialEq)]
pub enum Mesh {
/// A mesh with a solid color.
Solid {
/// The vertices and indices of the mesh.
buffers: Indexed<SolidVertex2D>,

/// The size of the drawable region of the mesh.
///
/// Any geometry that falls out of this region will be clipped.
size: Size,
},
/// A mesh with a gradient.
Gradient {
/// The vertices and indices of the mesh.
buffers: Indexed<GradientVertex2D>,

/// The size of the drawable region of the mesh.
///
/// Any geometry that falls out of this region will be clipped.
size: Size,
},
}

impl Damage for Mesh {
fn bounds(&self) -> Rectangle {
match self {
Self::Solid { size, .. } | Self::Gradient { size, .. } => {
Rectangle::with_size(*size)
}
}
}
}

/// A set of [`Vertex2D`] and indices representing a list of triangles.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Indexed<T> {
/// The vertices of the mesh
pub vertices: Vec<T>,

/// The list of vertex indices that defines the triangles of the mesh.
///
/// Therefore, this list should always have a length that is a multiple of 3.
pub indices: Vec<u32>,
}

/// A two-dimensional vertex with a color.
#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
#[repr(C)]
pub struct SolidVertex2D {
/// The vertex position in 2D space.
pub position: [f32; 2],

/// The color of the vertex in __linear__ RGBA.
pub color: color::Packed,
}

/// A vertex which contains 2D position & packed gradient data.
#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
#[repr(C)]
pub struct GradientVertex2D {
/// The vertex position in 2D space.
pub position: [f32; 2],

/// The packed vertex data of the gradient.
pub gradient: gradient::Packed,
}
69 changes: 1 addition & 68 deletions graphics/src/primitive.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
//! Draw using different graphical primitives.
use crate::color;
use crate::core::alignment;
use crate::core::image;
use crate::core::svg;
use crate::core::text;
use crate::core::{Background, Color, Font, Rectangle, Size, Vector};
use crate::gradient;
use crate::core::{Background, Color, Font, Rectangle, Vector};

use bytemuck::{Pod, Zeroable};
use std::sync::Arc;

/// A rendering primitive.
Expand Down Expand Up @@ -65,30 +62,6 @@ pub enum Primitive<T> {
/// The bounds of the viewport
bounds: Rectangle,
},
/// A low-level primitive to render a mesh of triangles with a solid color.
///
/// It can be used to render many kinds of geometry freely.
SolidMesh {
/// The vertices and indices of the mesh.
buffers: Mesh2D<ColoredVertex2D>,

/// The size of the drawable region of the mesh.
///
/// Any geometry that falls out of this region will be clipped.
size: Size,
},
/// A low-level primitive to render a mesh of triangles with a gradient.
///
/// It can be used to render many kinds of geometry freely.
GradientMesh {
/// The vertices and indices of the mesh.
buffers: Mesh2D<GradientVertex2D>,

/// The size of the drawable region of the mesh.
///
/// Any geometry that falls out of this region will be clipped.
size: Size,
},
/// A group of primitives
Group {
/// The primitives of the group
Expand Down Expand Up @@ -143,43 +116,3 @@ impl<T> Primitive<T> {
}
}
}

/// A set of [`Vertex2D`] and indices representing a list of triangles.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Mesh2D<T> {
/// The vertices of the mesh
pub vertices: Vec<T>,

/// The list of vertex indices that defines the triangles of the mesh.
///
/// Therefore, this list should always have a length that is a multiple of 3.
pub indices: Vec<u32>,
}

/// A two-dimensional vertex with a color.
#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
#[repr(C)]
pub struct ColoredVertex2D {
/// The vertex position in 2D space.
pub position: [f32; 2],

/// The color of the vertex in __linear__ RGBA.
pub color: color::Packed,
}

/// A vertex which contains 2D position & packed gradient data.
#[derive(Copy, Clone, Debug, PartialEq)]
#[repr(C)]
pub struct GradientVertex2D {
/// The vertex position in 2D space.
pub position: [f32; 2],

/// The packed vertex data of the gradient.
pub gradient: gradient::Packed,
}

#[allow(unsafe_code)]
unsafe impl Zeroable for GradientVertex2D {}

#[allow(unsafe_code)]
unsafe impl Pod for GradientVertex2D {}
1 change: 1 addition & 0 deletions renderer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ web-colors = ["iced_wgpu?/web-colors"]
[dependencies]
raw-window-handle = "0.5"
thiserror = "1"
log = "0.4"

[dependencies.iced_graphics]
version = "0.8"
Expand Down
16 changes: 12 additions & 4 deletions renderer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ pub use geometry::Geometry;
use crate::core::renderer;
use crate::core::text::{self, Text};
use crate::core::{Background, Font, Point, Rectangle, Size, Vector};
use crate::graphics::Mesh;

use std::borrow::Cow;

Expand All @@ -40,10 +41,17 @@ macro_rules! delegate {
}

impl<T> Renderer<T> {
#[cfg(feature = "wgpu")]
pub fn draw_with_wgpu(&mut self, primitive: iced_wgpu::Primitive) {
if let Self::Wgpu(renderer) = self {
renderer.draw_primitive(primitive);
pub fn draw_mesh(&mut self, mesh: Mesh) {
match self {
Self::TinySkia(_) => {
log::warn!("Unsupported mesh primitive: {:?}", mesh)
}
#[cfg(feature = "wgpu")]
Self::Wgpu(renderer) => {
renderer.draw_primitive(iced_wgpu::Primitive::Custom(
iced_wgpu::primitive::Custom::Mesh(mesh),
));
}
}
}
}
Expand Down
8 changes: 0 additions & 8 deletions tiny_skia/src/backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,14 +595,6 @@ impl Backend {
translation,
);
}
Primitive::SolidMesh { .. } | Primitive::GradientMesh { .. } => {
// Not supported!
// TODO: Draw a placeholder (?)
log::warn!(
"Unsupported primitive in `iced_tiny_skia`: {:?}",
primitive
);
}
}
}
}
Expand Down
Loading

0 comments on commit fa5650c

Please sign in to comment.