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}