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)] // Uniforms require uniform alignment. // Since the largest value in this array is a [f32; 2], // all smaller values must be padded. // also, [f32; 3] are aligned as [f32; 4] // (since alignments must be powers of two) pub struct GlobalDataContent { /// Camera position, in game units pub camera_position: [f32; 2], /// Camera zoom value, in game units. /// Second component is ignored. pub camera_zoom: [f32; 2], /// Camera zoom min and max. pub camera_zoom_limits: [f32; 2], /// Size ratio of window, in physical pixels pub window_size: [f32; 2], /// Aspect ratio of window /// Second component is ignored. pub window_aspect: [f32; 2], /// Texture index of starfield sprites /// Second component is ignored. pub starfield_texture: [u32; 2], // Size of (square) starfield tiles, in game units /// Second component is ignored. pub starfield_tile_size: [f32; 2], /// Min and max starfield star size, in game units pub starfield_size_limits: [f32; 2], /// Current game time, in seconds. /// Second component is ignored. pub current_time: [f32; 2], } 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("globaldata 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("globaldata bind group"), }); return Self { buffer, bind_group, bind_group_layout, content: GlobalDataContent::default(), }; } }