iced_graphics/
mesh.rs

1//! Draw triangles!
2use crate::color;
3use crate::core::{Rectangle, Transformation};
4use crate::gradient;
5
6use bytemuck::{Pod, Zeroable};
7
8/// A low-level primitive to render a mesh of triangles.
9#[derive(Debug, Clone, PartialEq)]
10pub enum Mesh {
11    /// A mesh with a solid color.
12    Solid {
13        /// The vertices and indices of the mesh.
14        buffers: Indexed<SolidVertex2D>,
15
16        /// The [`Transformation`] for the vertices of the [`Mesh`].
17        transformation: Transformation,
18
19        /// The clip bounds of the [`Mesh`].
20        clip_bounds: Rectangle,
21    },
22    /// A mesh with a gradient.
23    Gradient {
24        /// The vertices and indices of the mesh.
25        buffers: Indexed<GradientVertex2D>,
26
27        /// The [`Transformation`] for the vertices of the [`Mesh`].
28        transformation: Transformation,
29
30        /// The clip bounds of the [`Mesh`].
31        clip_bounds: Rectangle,
32    },
33}
34
35impl Mesh {
36    /// Returns the indices of the [`Mesh`].
37    pub fn indices(&self) -> &[u32] {
38        match self {
39            Self::Solid { buffers, .. } => &buffers.indices,
40            Self::Gradient { buffers, .. } => &buffers.indices,
41        }
42    }
43
44    /// Returns the [`Transformation`] of the [`Mesh`].
45    pub fn transformation(&self) -> Transformation {
46        match self {
47            Self::Solid { transformation, .. }
48            | Self::Gradient { transformation, .. } => *transformation,
49        }
50    }
51
52    /// Returns the clip bounds of the [`Mesh`].
53    pub fn clip_bounds(&self) -> Rectangle {
54        match self {
55            Self::Solid {
56                clip_bounds,
57                transformation,
58                ..
59            }
60            | Self::Gradient {
61                clip_bounds,
62                transformation,
63                ..
64            } => *clip_bounds * *transformation,
65        }
66    }
67}
68
69/// A set of vertices and indices representing a list of triangles.
70#[derive(Clone, Debug, PartialEq, Eq)]
71pub struct Indexed<T> {
72    /// The vertices of the mesh
73    pub vertices: Vec<T>,
74
75    /// The list of vertex indices that defines the triangles of the mesh.
76    ///
77    /// Therefore, this list should always have a length that is a multiple of 3.
78    pub indices: Vec<u32>,
79}
80
81/// A two-dimensional vertex with a color.
82#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
83#[repr(C)]
84pub struct SolidVertex2D {
85    /// The vertex position in 2D space.
86    pub position: [f32; 2],
87
88    /// The color of the vertex in __linear__ RGBA.
89    pub color: color::Packed,
90}
91
92/// A vertex which contains 2D position & packed gradient data.
93#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
94#[repr(C)]
95pub struct GradientVertex2D {
96    /// The vertex position in 2D space.
97    pub position: [f32; 2],
98
99    /// The packed vertex data of the gradient.
100    pub gradient: gradient::Packed,
101}
102
103/// The result of counting the attributes of a set of meshes.
104#[derive(Debug, Clone, Copy, Default)]
105pub struct AttributeCount {
106    /// The total amount of solid vertices.
107    pub solid_vertices: usize,
108
109    /// The total amount of solid meshes.
110    pub solids: usize,
111
112    /// The total amount of gradient vertices.
113    pub gradient_vertices: usize,
114
115    /// The total amount of gradient meshes.
116    pub gradients: usize,
117
118    /// The total amount of indices.
119    pub indices: usize,
120}
121
122/// Returns the number of total vertices & total indices of all [`Mesh`]es.
123pub fn attribute_count_of(meshes: &[Mesh]) -> AttributeCount {
124    meshes
125        .iter()
126        .fold(AttributeCount::default(), |mut count, mesh| {
127            match mesh {
128                Mesh::Solid { buffers, .. } => {
129                    count.solids += 1;
130                    count.solid_vertices += buffers.vertices.len();
131                    count.indices += buffers.indices.len();
132                }
133                Mesh::Gradient { buffers, .. } => {
134                    count.gradients += 1;
135                    count.gradient_vertices += buffers.vertices.len();
136                    count.indices += buffers.indices.len();
137                }
138            }
139
140            count
141        })
142}
143
144/// A renderer capable of drawing a [`Mesh`].
145pub trait Renderer {
146    /// Draws the given [`Mesh`].
147    fn draw_mesh(&mut self, mesh: Mesh);
148}