#[repr(C)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] pub struct Globals { pub view_proj: [[f32; 4]; 4], } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum Shape { Polygon, Circle, } pub struct Geometry { pub(crate) vertex_buffer: wgpu::Buffer, pub(crate) index_buffer: wgpu::Buffer, pub(crate) index_count: u32, } pub struct RenderInstance { pub position: cgmath::Vector3, pub rotation: cgmath::Quaternion, pub color: [f32; 3], pub scale: f32, pub shape: Shape, } impl RenderInstance { pub fn to_raw(&self) -> InstanceRaw { let model = cgmath::Matrix4::from_translation(self.position) * cgmath::Matrix4::from(self.rotation) * cgmath::Matrix4::from_scale(self.scale); InstanceRaw { model: model.into(), color: self.color, } } } #[repr(C)] #[derive(Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] pub struct InstanceRaw { model: [[f32; 4]; 4], color: [f32; 3], } impl InstanceRaw { pub(crate) fn desc() -> wgpu::VertexBufferLayout<'static> { wgpu::VertexBufferLayout { array_stride: size_of::() as wgpu::BufferAddress, step_mode: wgpu::VertexStepMode::Instance, attributes: &[ wgpu::VertexAttribute { offset: 0, shader_location: 5, format: wgpu::VertexFormat::Float32x4 }, wgpu::VertexAttribute { offset: 16, shader_location: 6, format: wgpu::VertexFormat::Float32x4 }, wgpu::VertexAttribute { offset: 32, shader_location: 7, format: wgpu::VertexFormat::Float32x4 }, wgpu::VertexAttribute { offset: 48, shader_location: 8, format: wgpu::VertexFormat::Float32x4 }, wgpu::VertexAttribute { offset: 64, shader_location: 9, format: wgpu::VertexFormat::Float32x3 }, ], } } } pub struct SampleCount(pub u32); impl SampleCount { pub fn get(&self) -> u32 { self.0 } } #[repr(C)] #[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)] pub struct Vertex { pub(crate) position: [f32; 3], pub(crate) color: [f32; 3], } impl Vertex { const ATTRIBS: [wgpu::VertexAttribute; 2] = wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x3]; pub(crate) fn desc() -> wgpu::VertexBufferLayout<'static> { wgpu::VertexBufferLayout { array_stride: size_of::() as wgpu::BufferAddress, step_mode: wgpu::VertexStepMode::Vertex, attributes: &Self::ATTRIBS, } } } pub fn create_circle_vertices(segment_count: usize, radius: f32, color: [f32; 3]) -> (Vec, Vec) { let mut vertices = vec![Vertex { position: [0.0, 0.0, 0.0], color }]; let mut indices = vec![]; for i in 0..=segment_count { let theta = (i as f32) / (segment_count as f32) * std::f32::consts::TAU; let x = radius * theta.cos(); let y = radius * theta.sin(); vertices.push(Vertex { position: [x, y, 0.0], color }); } for i in 1..=segment_count { indices.push(0); indices.push(i as u16); indices.push((i % segment_count + 1) as u16); } (vertices, indices) }