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, time: f32) { self.view_inv = camera.view_matrix().invert().unwrap().into(); self.proj_inv = camera.proj_matrix().invert().unwrap().into(); self.cam_pos = camera.position.into(); self.time = time; } } pub struct UniformBuffer { pub values: UniformValues, pub buffer: wgpu::Buffer, pub bind_layout: wgpu::BindGroupLayout, pub bind_group: wgpu::BindGroup, } impl UniformBuffer { 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, } ); // Create bind group let bind_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { entries: &[ wgpu::BindGroupLayoutEntry { binding: 0, visibility: wgpu::ShaderStage::FRAGMENT, ty: wgpu::BindingType::Buffer { ty: wgpu::BufferBindingType::Uniform, has_dynamic_offset: false, min_binding_size: None, }, count: None, } ], label: Some("Uniform buffer layout"), }); let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { layout: &bind_layout, entries: &[ wgpu::BindGroupEntry { binding: 0, resource: buffer.as_entire_binding(), } ], label: Some("Uniform buffer group"), }); // Done UniformBuffer { buffer, values, bind_layout, bind_group } } }