use crate::renderer::camera::Camera; use cgmath::{SquareMatrix, Vector3, InnerSpace}; use wgpu::util::DeviceExt; #[repr(C)] #[derive(Default, Debug, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)] pub struct UniformValues { view_inv: [[f32; 4]; 4], proj_inv: [[f32; 4]; 4], cam_pos: [f32; 3], padding: f32, sun_dir: [f32; 3], //padding2: f32, time: f32 } impl UniformValues { pub fn new() -> Self { let sun_vec: Vector3 = (1.0, 1.0, 1.0).into(); let sun_dir: [f32; 3] = sun_vec.normalize().into(); Self { sun_dir, .. Default::default() } } pub fn update(&mut self, camera: &Camera, offset: Vector3, time: f32) { self.view_inv = camera.get_view().invert().unwrap().into(); self.proj_inv = camera.get_projection().invert().unwrap().into(); self.cam_pos = (camera.get_position() + offset).into(); self.time = time; } } pub struct Uniform { pub values: UniformValues, pub buffer: wgpu::Buffer, pub bind_layout: wgpu::BindGroupLayout, pub bind_group: wgpu::BindGroup, } impl Uniform { pub fn new(device: &wgpu::Device) -> Self { // Create values let values = UniformValues::new(); // Create buffer let buffer = device.create_buffer_init( &wgpu::util::BufferInitDescriptor { label: Some("Uniform buffer"), contents: bytemuck::cast_slice(&[values]), usage: wgpu::BufferUsage::UNIFORM | wgpu::BufferUsage::COPY_DST, } ); // Bind layout let buffer_entry = wgpu::BindGroupLayoutEntry { binding: 0, visibility: wgpu::ShaderStage::FRAGMENT, count: None, ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, has_dynamic_offset: false, min_binding_size: None }, }; let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { label: None, entries: &[ wgpu::BindGroupLayoutEntry { binding: 0, ..buffer_entry } ], }); // Bind group let bind_group = device.create_bind_group( &wgpu::BindGroupDescriptor { label: None, layout: &bind_layout, entries: &[ wgpu::BindGroupEntry { binding: 0, resource: buffer.as_entire_binding(), } ], } ); // Done Uniform { buffer, values, bind_layout, bind_group } } }