ailloli_ui_render_wgpu/
vertices.rs

1//! GPU vertex formats for solid rects, textured quads, rounded rects, and borders.
2
3/// Solid-color triangle vertex (position + RGBA).
4///
5/// # Examples
6///
7/// ```
8/// use ailloli_ui_render_wgpu::vertices::Vertex;
9/// let vertex = Vertex { pos: [0.0, 1.0], color: [1.0, 0.0, 0.0, 1.0] };
10/// assert_eq!(vertex.color[3], 1.0);
11/// ```
12#[repr(C)]
13#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
14pub struct Vertex {
15    /// Position in normalized device coordinates.
16    pub pos: [f32; 2],
17    /// Linear RGBA color consumed by the solid shader.
18    pub color: [f32; 4],
19}
20
21impl Vertex {
22    /// Shader attributes at locations 0 and 1.
23    ///
24    /// # Examples
25    ///
26    /// ```
27    /// use ailloli_ui_render_wgpu::vertices::Vertex;
28    /// assert_eq!(Vertex::ATTRS.len(), 2);
29    /// ```
30    pub const ATTRS: [wgpu::VertexAttribute; 2] =
31        wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x4];
32
33    /// Returns the packed per-vertex buffer layout.
34    ///
35    /// # Examples
36    ///
37    /// ```
38    /// use ailloli_ui_render_wgpu::vertices::Vertex;
39    /// assert_eq!(Vertex::desc().array_stride as usize, std::mem::size_of::<Vertex>());
40    /// ```
41    pub fn desc() -> wgpu::VertexBufferLayout<'static> {
42        wgpu::VertexBufferLayout {
43            array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
44            step_mode: wgpu::VertexStepMode::Vertex,
45            attributes: &Self::ATTRS,
46        }
47    }
48}
49
50/// Stroked polyline vertex (NDC position, physical-pixel position, RGBA).
51///
52/// # Examples
53///
54/// ```
55/// use ailloli_ui_render_wgpu::vertices::StrokeVertex;
56/// let vertex = StrokeVertex { pos: [0.0; 2], pos_px: [10.0, 20.0], color: [1.0; 4] };
57/// assert_eq!(vertex.pos_px, [10.0, 20.0]);
58/// ```
59#[repr(C)]
60#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
61pub struct StrokeVertex {
62    /// Position in normalized device coordinates.
63    pub pos: [f32; 2],
64    /// Matching physical-pixel position for shader edge calculations.
65    pub pos_px: [f32; 2],
66    /// Linear RGBA stroke color.
67    pub color: [f32; 4],
68}
69
70impl StrokeVertex {
71    /// Shader attributes at locations 0 through 2.
72    ///
73    /// # Examples
74    ///
75    /// ```
76    /// use ailloli_ui_render_wgpu::vertices::StrokeVertex;
77    /// assert_eq!(StrokeVertex::ATTRS.len(), 3);
78    /// ```
79    pub const ATTRS: [wgpu::VertexAttribute; 3] =
80        wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2, 2 => Float32x4];
81
82    /// Returns the packed per-vertex buffer layout.
83    ///
84    /// # Examples
85    ///
86    /// ```
87    /// use ailloli_ui_render_wgpu::vertices::StrokeVertex;
88    /// assert_eq!(StrokeVertex::desc().array_stride as usize, std::mem::size_of::<StrokeVertex>());
89    /// ```
90    pub fn desc() -> wgpu::VertexBufferLayout<'static> {
91        wgpu::VertexBufferLayout {
92            array_stride: std::mem::size_of::<StrokeVertex>() as wgpu::BufferAddress,
93            step_mode: wgpu::VertexStepMode::Vertex,
94            attributes: &Self::ATTRS,
95        }
96    }
97}
98
99/// Rounded-border SDF vertex (position, UV, color, size, radius, width).
100///
101/// # Examples
102///
103/// ```
104/// use ailloli_ui_render_wgpu::vertices::BorderRRectVertex;
105/// let vertex = BorderRRectVertex { pos: [0.0; 2], uv: [0.0; 2], color: [1.0; 4],
106///     size_px: [20.0, 10.0], radius_px: 3.0, width_px: 1.0 };
107/// assert_eq!(vertex.width_px, 1.0);
108/// ```
109#[repr(C)]
110#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
111pub struct BorderRRectVertex {
112    /// Position in normalized device coordinates.
113    pub pos: [f32; 2],
114    /// Unit-quad coordinate used by the signed-distance shader.
115    pub uv: [f32; 2],
116    /// Linear RGBA border color.
117    pub color: [f32; 4],
118    /// Outer rectangle size in physical pixels.
119    pub size_px: [f32; 2],
120    /// Corner radius in physical pixels.
121    pub radius_px: f32,
122    /// Border width in physical pixels.
123    pub width_px: f32,
124}
125
126impl BorderRRectVertex {
127    /// Shader attributes at locations 0 through 5.
128    ///
129    /// # Examples
130    ///
131    /// ```
132    /// use ailloli_ui_render_wgpu::vertices::BorderRRectVertex;
133    /// assert_eq!(BorderRRectVertex::ATTRS.len(), 6);
134    /// ```
135    pub const ATTRS: [wgpu::VertexAttribute; 6] = wgpu::vertex_attr_array![
136        0 => Float32x2,
137        1 => Float32x2,
138        2 => Float32x4,
139        3 => Float32x2,
140        4 => Float32,
141        5 => Float32
142    ];
143
144    /// Returns the packed per-vertex buffer layout.
145    ///
146    /// # Examples
147    ///
148    /// ```
149    /// use ailloli_ui_render_wgpu::vertices::BorderRRectVertex;
150    /// assert_eq!(BorderRRectVertex::desc().array_stride as usize,
151    ///     std::mem::size_of::<BorderRRectVertex>());
152    /// ```
153    pub fn desc() -> wgpu::VertexBufferLayout<'static> {
154        wgpu::VertexBufferLayout {
155            array_stride: std::mem::size_of::<BorderRRectVertex>() as wgpu::BufferAddress,
156            step_mode: wgpu::VertexStepMode::Vertex,
157            attributes: &Self::ATTRS,
158        }
159    }
160}
161
162/// Box-shadow SDF vertex (position, UV, color, paint rect, shadow shape, radius, blur).
163///
164/// # Examples
165///
166/// ```
167/// use ailloli_ui_render_wgpu::vertices::BoxShadowVertex;
168/// let vertex = BoxShadowVertex { pos: [0.0; 2], uv: [0.0; 2], color: [0.0; 4],
169///     paint_size_px: [10.0; 2], shape_offset_px: [1.0; 2], shape_size_px: [8.0; 2],
170///     radius_px: 2.0, blur_px: 4.0 };
171/// assert_eq!(vertex.blur_px, 4.0);
172/// ```
173#[repr(C)]
174#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
175pub struct BoxShadowVertex {
176    /// Position in normalized device coordinates.
177    pub pos: [f32; 2],
178    /// Unit-quad coordinate across the shadow paint bounds.
179    pub uv: [f32; 2],
180    /// Linear premultiplied-style RGBA shadow color expected by the shader.
181    pub color: [f32; 4],
182    /// Paint-quad size in physical pixels.
183    pub paint_size_px: [f32; 2],
184    /// Shadow shape offset within the paint quad, in physical pixels.
185    pub shape_offset_px: [f32; 2],
186    /// Unblurred shadow shape size in physical pixels.
187    pub shape_size_px: [f32; 2],
188    /// Shape corner radius in physical pixels.
189    pub radius_px: f32,
190    /// Blur radius in physical pixels.
191    pub blur_px: f32,
192}
193
194impl BoxShadowVertex {
195    /// Shader attributes at locations 0 through 7.
196    ///
197    /// # Examples
198    ///
199    /// ```
200    /// use ailloli_ui_render_wgpu::vertices::BoxShadowVertex;
201    /// assert_eq!(BoxShadowVertex::ATTRS.len(), 8);
202    /// ```
203    pub const ATTRS: [wgpu::VertexAttribute; 8] = wgpu::vertex_attr_array![
204        0 => Float32x2,
205        1 => Float32x2,
206        2 => Float32x4,
207        3 => Float32x2,
208        4 => Float32x2,
209        5 => Float32x2,
210        6 => Float32,
211        7 => Float32
212    ];
213
214    /// Returns the packed per-vertex buffer layout.
215    ///
216    /// # Examples
217    ///
218    /// ```
219    /// use ailloli_ui_render_wgpu::vertices::BoxShadowVertex;
220    /// assert_eq!(BoxShadowVertex::desc().array_stride as usize,
221    ///     std::mem::size_of::<BoxShadowVertex>());
222    /// ```
223    pub fn desc() -> wgpu::VertexBufferLayout<'static> {
224        wgpu::VertexBufferLayout {
225            array_stride: std::mem::size_of::<BoxShadowVertex>() as wgpu::BufferAddress,
226            step_mode: wgpu::VertexStepMode::Vertex,
227            attributes: &Self::ATTRS,
228        }
229    }
230}
231
232/// Circular progress SDF vertex (position, UV, colors, size, thickness, fraction, start angle).
233///
234/// # Examples
235///
236/// ```
237/// use ailloli_ui_render_wgpu::vertices::RingProgressVertex;
238/// let vertex = RingProgressVertex { pos: [0.0; 2], uv: [0.0; 2], track_color: [0.0; 4],
239///     fill_color: [1.0; 4], size_px: [24.0; 2], thickness_px: 2.0,
240///     fraction: 0.5, start_angle: 0.0 };
241/// assert_eq!(vertex.fraction, 0.5);
242/// ```
243#[repr(C)]
244#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
245pub struct RingProgressVertex {
246    /// Position in normalized device coordinates.
247    pub pos: [f32; 2],
248    /// Unit-quad coordinate used for ring distance evaluation.
249    pub uv: [f32; 2],
250    /// Linear RGBA track color.
251    pub track_color: [f32; 4],
252    /// Linear RGBA filled-arc color.
253    pub fill_color: [f32; 4],
254    /// Ring bounding-box size in physical pixels.
255    pub size_px: [f32; 2],
256    /// Ring thickness in physical pixels.
257    pub thickness_px: f32,
258    /// Filled proportion, normally clamped to `[0, 1]` by the builder.
259    pub fraction: f32,
260    /// Arc start angle in radians.
261    pub start_angle: f32,
262}
263
264impl RingProgressVertex {
265    /// Shader attributes at locations 0 through 7.
266    ///
267    /// # Examples
268    ///
269    /// ```
270    /// use ailloli_ui_render_wgpu::vertices::RingProgressVertex;
271    /// assert_eq!(RingProgressVertex::ATTRS.len(), 8);
272    /// ```
273    pub const ATTRS: [wgpu::VertexAttribute; 8] = wgpu::vertex_attr_array![
274        0 => Float32x2,
275        1 => Float32x2,
276        2 => Float32x4,
277        3 => Float32x4,
278        4 => Float32x2,
279        5 => Float32,
280        6 => Float32,
281        7 => Float32
282    ];
283
284    /// Returns the packed per-vertex buffer layout.
285    ///
286    /// # Examples
287    ///
288    /// ```
289    /// use ailloli_ui_render_wgpu::vertices::RingProgressVertex;
290    /// assert_eq!(RingProgressVertex::desc().array_stride as usize,
291    ///     std::mem::size_of::<RingProgressVertex>());
292    /// ```
293    pub fn desc() -> wgpu::VertexBufferLayout<'static> {
294        wgpu::VertexBufferLayout {
295            array_stride: std::mem::size_of::<RingProgressVertex>() as wgpu::BufferAddress,
296            step_mode: wgpu::VertexStepMode::Vertex,
297            attributes: &Self::ATTRS,
298        }
299    }
300}
301
302/// Textured quad vertex (position + UV + tint).
303///
304/// # Examples
305///
306/// ```
307/// use ailloli_ui_render_wgpu::vertices::TexVertex;
308/// let vertex = TexVertex { pos: [0.0; 2], uv: [1.0, 0.0], tint: [1.0; 4] };
309/// assert_eq!(vertex.uv, [1.0, 0.0]);
310/// ```
311#[repr(C)]
312#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
313pub struct TexVertex {
314    /// Position in normalized device coordinates.
315    pub pos: [f32; 2],
316    /// Texture coordinate, conventionally in `[0, 1]`.
317    pub uv: [f32; 2],
318    /// Linear RGBA multiplier applied to the sampled texture.
319    pub tint: [f32; 4],
320}
321
322impl TexVertex {
323    /// Shader attributes at locations 0 through 2.
324    ///
325    /// # Examples
326    ///
327    /// ```
328    /// use ailloli_ui_render_wgpu::vertices::TexVertex;
329    /// assert_eq!(TexVertex::ATTRS.len(), 3);
330    /// ```
331    pub const ATTRS: [wgpu::VertexAttribute; 3] =
332        wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x2, 2 => Float32x4];
333
334    /// Returns the packed per-vertex buffer layout.
335    ///
336    /// # Examples
337    ///
338    /// ```
339    /// use ailloli_ui_render_wgpu::vertices::TexVertex;
340    /// assert_eq!(TexVertex::desc().array_stride as usize, std::mem::size_of::<TexVertex>());
341    /// ```
342    pub fn desc() -> wgpu::VertexBufferLayout<'static> {
343        wgpu::VertexBufferLayout {
344            array_stride: std::mem::size_of::<TexVertex>() as wgpu::BufferAddress,
345            step_mode: wgpu::VertexStepMode::Vertex,
346            attributes: &Self::ATTRS,
347        }
348    }
349}
350
351/// Rounded-rect SDF vertex (position, UV, color, size, radius).
352///
353/// # Examples
354///
355/// ```
356/// use ailloli_ui_render_wgpu::vertices::RRectVertex;
357/// let vertex = RRectVertex { pos: [0.0; 2], uv: [0.5; 2], color: [1.0; 4],
358///     size_px: [12.0, 8.0], radius_px: 2.0 };
359/// assert_eq!(vertex.radius_px, 2.0);
360/// ```
361#[repr(C)]
362#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
363pub struct RRectVertex {
364    /// Position in normalized device coordinates.
365    pub pos: [f32; 2],
366    /// Unit-quad coordinate used by the signed-distance shader.
367    pub uv: [f32; 2],
368    /// Linear RGBA fill color.
369    pub color: [f32; 4],
370    /// Rectangle size in physical pixels.
371    pub size_px: [f32; 2],
372    /// Corner radius in physical pixels.
373    pub radius_px: f32,
374}
375
376impl RRectVertex {
377    /// Shader attributes at locations 0 through 4.
378    ///
379    /// # Examples
380    ///
381    /// ```
382    /// use ailloli_ui_render_wgpu::vertices::RRectVertex;
383    /// assert_eq!(RRectVertex::ATTRS.len(), 5);
384    /// ```
385    pub const ATTRS: [wgpu::VertexAttribute; 5] = wgpu::vertex_attr_array![
386        0 => Float32x2,
387        1 => Float32x2,
388        2 => Float32x4,
389        3 => Float32x2,
390        4 => Float32
391    ];
392
393    /// Returns the packed per-vertex buffer layout.
394    ///
395    /// # Examples
396    ///
397    /// ```
398    /// use ailloli_ui_render_wgpu::vertices::RRectVertex;
399    /// assert_eq!(RRectVertex::desc().array_stride as usize,
400    ///     std::mem::size_of::<RRectVertex>());
401    /// ```
402    pub fn desc() -> wgpu::VertexBufferLayout<'static> {
403        wgpu::VertexBufferLayout {
404            array_stride: std::mem::size_of::<RRectVertex>() as wgpu::BufferAddress,
405            step_mode: wgpu::VertexStepMode::Vertex,
406            attributes: &Self::ATTRS,
407        }
408    }
409}