use bytemuck; use std::mem; use wgpu; pub struct GlobalData { pub buffer: wgpu::Buffer, pub bind_group: wgpu::BindGroup, pub bind_group_layout: wgpu::BindGroupLayout, pub content: GlobalDataContent, } #[repr(C)] #[derive(Debug, Copy, Clone, Default, bytemuck::Pod, bytemuck::Zeroable)] pub struct GlobalDataContent { /// Camera position, in game units pub camera_position: [f32; 2], /// Camera zoom value, in game units pub camera_zoom: f32, /// Aspect ratio of window (width / height) pub window_aspect: f32, /// Texture index of starfield sprites pub starfield_texture: u32, // Size of (square) starfield tile, in game units pub starfield_tile_size: f32, pub padding: [f32; 3], } impl GlobalDataContent { const SIZE: u64 = mem::size_of::() as wgpu::BufferAddress; } impl GlobalData { pub fn new(device: &wgpu::Device) -> Self { let buffer = device.create_buffer(&wgpu::BufferDescriptor { label: None, size: GlobalDataContent::SIZE, usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, mapped_at_creation: false, }); let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { entries: &[wgpu::BindGroupLayoutEntry { binding: 0, visibility: wgpu::ShaderStages::VERTEX_FRAGMENT, ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, has_dynamic_offset: false, min_binding_size: None, }, count: None, }], label: Some("camera_bind_group_layout"), }); let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &bind_group_layout, entries: &[wgpu::BindGroupEntry { binding: 0, resource: buffer.as_entire_binding(), }], label: Some("camera_bind_group"), }); return Self { buffer, bind_group, bind_group_layout, content: GlobalDataContent::default(), }; } }