Skip to main content

shape_viz_core/renderer/
vertex.rs

1//! Vertex data structures for GPU rendering
2
3use crate::error::{ChartError, Result};
4use crate::theme::Color;
5use bytemuck::{Pod, Zeroable};
6
7/// Vertex data for GPU rendering
8#[repr(C)]
9#[derive(Copy, Clone, Debug, Pod, Zeroable)]
10pub struct Vertex {
11    pub position: [f32; 2],
12    pub color: [f32; 4],
13}
14
15impl Vertex {
16    pub fn new(position: [f32; 2], color: Color) -> Self {
17        Self {
18            position,
19            color: color.to_array(),
20        }
21    }
22
23    /// Vertex buffer layout description for WGPU
24    pub fn desc() -> wgpu::VertexBufferLayout<'static> {
25        wgpu::VertexBufferLayout {
26            array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
27            step_mode: wgpu::VertexStepMode::Vertex,
28            attributes: &[
29                // Position
30                wgpu::VertexAttribute {
31                    offset: 0,
32                    shader_location: 0,
33                    format: wgpu::VertexFormat::Float32x2,
34                },
35                // Color
36                wgpu::VertexAttribute {
37                    offset: std::mem::size_of::<[f32; 2]>() as wgpu::BufferAddress,
38                    shader_location: 1,
39                    format: wgpu::VertexFormat::Float32x4,
40                },
41            ],
42        }
43    }
44}
45
46/// GPU buffer for storing vertex data
47#[derive(Debug)]
48pub struct VertexBuffer {
49    buffer: wgpu::Buffer,
50    pub(super) vertex_count: u32,
51    pub(super) capacity: u32,
52}
53
54impl VertexBuffer {
55    /// Create a new vertex buffer with the given capacity
56    pub fn new(device: &wgpu::Device, capacity: u32) -> Self {
57        let buffer = device.create_buffer(&wgpu::BufferDescriptor {
58            label: Some("Vertex Buffer"),
59            size: (capacity as u64) * std::mem::size_of::<Vertex>() as u64,
60            usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
61            mapped_at_creation: false,
62        });
63
64        Self {
65            buffer,
66            vertex_count: 0,
67            capacity,
68        }
69    }
70
71    /// Update the buffer with new vertex data
72    pub fn update(&mut self, queue: &wgpu::Queue, vertices: &[Vertex]) -> Result<()> {
73        if vertices.len() as u32 > self.capacity {
74            return Err(ChartError::BufferCreation(format!(
75                "Vertex count {} exceeds buffer capacity {}",
76                vertices.len(),
77                self.capacity
78            )));
79        }
80
81        queue.write_buffer(&self.buffer, 0, bytemuck::cast_slice(vertices));
82        self.vertex_count = vertices.len() as u32;
83        Ok(())
84    }
85
86    /// Get the buffer slice for rendering
87    pub fn slice(&self) -> wgpu::BufferSlice<'_> {
88        self.buffer.slice(..)
89    }
90
91    /// Get the number of vertices in the buffer
92    pub fn vertex_count(&self) -> u32 {
93        self.vertex_count
94    }
95}