summaryrefslogtreecommitdiff
path: root/src/camera.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/camera.rs')
-rw-r--r--src/camera.rs76
1 files changed, 66 insertions, 10 deletions
diff --git a/src/camera.rs b/src/camera.rs
index 22f9837..65d1d43 100644
--- a/src/camera.rs
+++ b/src/camera.rs
@@ -1,14 +1,18 @@
+use std::mem::size_of;
+
use cgmath::{Matrix4, Vector2};
-#[derive(Clone, Copy, Debug, PartialEq)]
+#[derive(Debug)]
pub struct Camera {
position: (f32, f32),
zoom: f32,
rotation: f32,
inverse_aspect_ratio: f32,
+ buffer: wgpu::Buffer,
+ bind_group: wgpu::BindGroup,
}
-pub(crate) type CameraUniform = [[f32; 4]; 4];
+type CameraUniform = [[f32; 4]; 4];
#[allow(clippy::cast_precision_loss)]
fn inverse_aspect_ratio(width: u32, height: u32) -> f32 {
@@ -17,13 +21,53 @@ fn inverse_aspect_ratio(width: u32, height: u32) -> f32 {
impl Camera {
/// Create a new camera, with a position of (0, 0), and a zoom of 1.0
- pub(crate) fn from_size(width: u32, height: u32) -> Self {
- Self {
- position: (0.0, 0.0),
- zoom: 1.0,
- rotation: 0.0,
- inverse_aspect_ratio: inverse_aspect_ratio(width, height),
- }
+ // TODO this can still be a little smaller
+ pub(crate) fn new(
+ device: &wgpu::Device,
+ width: u32,
+ height: u32,
+ ) -> (Self, wgpu::BindGroupLayout) {
+ let buffer = device.create_buffer(&wgpu::BufferDescriptor {
+ label: Some("Camera Uniform"),
+ size: size_of::<CameraUniform>() as wgpu::BufferAddress,
+ usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
+ mapped_at_creation: false,
+ });
+
+ let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
+ label: Some("Camera Bind Group Layout"),
+ entries: &[wgpu::BindGroupLayoutEntry {
+ binding: 0,
+ visibility: wgpu::ShaderStages::VERTEX,
+ ty: wgpu::BindingType::Buffer {
+ ty: wgpu::BufferBindingType::Uniform,
+ has_dynamic_offset: false,
+ min_binding_size: None,
+ },
+ count: None,
+ }],
+ });
+
+ let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
+ label: Some("Camera Bind Group"),
+ layout: &bind_group_layout,
+ entries: &[wgpu::BindGroupEntry {
+ binding: 0,
+ resource: buffer.as_entire_binding(),
+ }],
+ });
+
+ (
+ Self {
+ position: (0.0, 0.0),
+ zoom: 1.0,
+ rotation: 0.0,
+ inverse_aspect_ratio: inverse_aspect_ratio(width, height),
+ buffer,
+ bind_group,
+ },
+ bind_group_layout,
+ )
}
/// Get the camera's current x position
@@ -89,7 +133,7 @@ impl Camera {
}
#[allow(clippy::wrong_self_convention)]
- pub(crate) fn to_matrix(&mut self) -> CameraUniform {
+ fn to_matrix(&self) -> CameraUniform {
let cos = self.rotation.cos();
let sin = self.rotation.sin();
@@ -120,4 +164,16 @@ impl Camera {
let transform = projection_matrix * view_matrix;
transform.into()
}
+
+ pub(crate) const fn bind_group(&self) -> &wgpu::BindGroup {
+ &self.bind_group
+ }
+
+ pub(crate) fn refresh(&self, queue: &wgpu::Queue) {
+ queue.write_buffer(
+ &self.buffer,
+ 0 as wgpu::BufferAddress,
+ bytemuck::cast_slice(&self.to_matrix()),
+ );
+ }
}