oxide_engine/camera/
uniform.rs1use bytemuck::{Pod, Zeroable};
4use glam::Mat4;
5use wgpu::{Buffer, BufferDescriptor, BufferUsages, Device};
6
7#[repr(C)]
8#[derive(Copy, Clone, Debug, Pod, Zeroable)]
9pub struct CameraUniform {
10 view_proj: [[f32; 4]; 4],
11 position: [f32; 4],
12}
13
14impl Default for CameraUniform {
15 fn default() -> Self {
16 Self {
17 view_proj: Mat4::IDENTITY.to_cols_array_2d(),
18 position: [0.0, 0.0, 0.0, 1.0],
19 }
20 }
21}
22
23impl CameraUniform {
24 pub fn new() -> Self {
25 Self::default()
26 }
27
28 pub fn update(&mut self, view_proj: Mat4, position: glam::Vec3) {
29 self.view_proj = view_proj.to_cols_array_2d();
30 self.position = [position.x, position.y, position.z, 1.0];
31 }
32}
33
34pub struct CameraBuffer {
35 pub buffer: Buffer,
36 pub bind_group_layout: wgpu::BindGroupLayout,
37 pub bind_group: wgpu::BindGroup,
38}
39
40impl CameraBuffer {
41 pub fn new(device: &Device) -> Self {
42 let buffer = device.create_buffer(&BufferDescriptor {
43 label: Some("Camera Buffer"),
44 size: std::mem::size_of::<CameraUniform>() as wgpu::BufferAddress,
45 usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
46 mapped_at_creation: false,
47 });
48
49 let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
50 label: Some("Camera Bind Group Layout"),
51 entries: &[wgpu::BindGroupLayoutEntry {
52 binding: 0,
53 visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
54 ty: wgpu::BindingType::Buffer {
55 ty: wgpu::BufferBindingType::Uniform,
56 has_dynamic_offset: false,
57 min_binding_size: None,
58 },
59 count: None,
60 }],
61 });
62
63 let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
64 label: Some("Camera Bind Group"),
65 layout: &bind_group_layout,
66 entries: &[wgpu::BindGroupEntry {
67 binding: 0,
68 resource: buffer.as_entire_binding(),
69 }],
70 });
71
72 Self {
73 buffer,
74 bind_group_layout,
75 bind_group,
76 }
77 }
78
79 pub fn update(&self, queue: &wgpu::Queue, uniform: &CameraUniform) {
80 queue.write_buffer(&self.buffer, 0, bytemuck::bytes_of(uniform));
81 }
82}