1use crate::color;
3use crate::core::{Rectangle, Transformation};
4use crate::gradient;
5
6use bytemuck::{Pod, Zeroable};
7
8#[derive(Debug, Clone, PartialEq)]
10pub enum Mesh {
11 Solid {
13 buffers: Indexed<SolidVertex2D>,
15
16 transformation: Transformation,
18
19 clip_bounds: Rectangle,
21 },
22 Gradient {
24 buffers: Indexed<GradientVertex2D>,
26
27 transformation: Transformation,
29
30 clip_bounds: Rectangle,
32 },
33}
34
35impl Mesh {
36 pub fn indices(&self) -> &[u32] {
38 match self {
39 Self::Solid { buffers, .. } => &buffers.indices,
40 Self::Gradient { buffers, .. } => &buffers.indices,
41 }
42 }
43
44 pub fn transformation(&self) -> Transformation {
46 match self {
47 Self::Solid { transformation, .. }
48 | Self::Gradient { transformation, .. } => *transformation,
49 }
50 }
51
52 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#[derive(Clone, Debug, PartialEq, Eq)]
71pub struct Indexed<T> {
72 pub vertices: Vec<T>,
74
75 pub indices: Vec<u32>,
79}
80
81#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
83#[repr(C)]
84pub struct SolidVertex2D {
85 pub position: [f32; 2],
87
88 pub color: color::Packed,
90}
91
92#[derive(Copy, Clone, Debug, PartialEq, Zeroable, Pod)]
94#[repr(C)]
95pub struct GradientVertex2D {
96 pub position: [f32; 2],
98
99 pub gradient: gradient::Packed,
101}
102
103#[derive(Debug, Clone, Copy, Default)]
105pub struct AttributeCount {
106 pub solid_vertices: usize,
108
109 pub solids: usize,
111
112 pub gradient_vertices: usize,
114
115 pub gradients: usize,
117
118 pub indices: usize,
120}
121
122pub 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
144pub trait Renderer {
146 fn draw_mesh(&mut self, mesh: Mesh);
148}