diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/camera.rs | 76 | ||||
| -rw-r--r-- | src/renderer.rs | 49 | ||||
| -rw-r--r-- | src/texture.rs | 1 |
3 files changed, 70 insertions, 56 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()), + ); + } } diff --git a/src/renderer.rs b/src/renderer.rs index 2c26836..215dda8 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -1,7 +1,6 @@ use std::{convert::TryInto, mem::size_of, num::NonZeroU32}; use crate::{ - camera::CameraUniform, instance::InstanceId, texture::{TextureError, TextureId}, vertex::SQUARE, @@ -57,8 +56,6 @@ pub struct Renderer { instance_buffer_size: usize, instances: Vec<Instance>, camera: Camera, - camera_buffer: wgpu::Buffer, - camera_bind_group: wgpu::BindGroup, textures: WgpuTextures, window: Window, } @@ -194,37 +191,7 @@ impl Renderer { // create the camera let width = window.inner_size().width; let height = window.inner_size().height; - let camera = Camera::from_size(width, height); - let camera_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 camera_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 camera_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - label: Some("Camera Bind Group"), - layout: &camera_bind_group_layout, - entries: &[wgpu::BindGroupEntry { - binding: 0, - resource: camera_buffer.as_entire_binding(), - }], - }); + let (camera, camera_bind_group_layout) = Camera::new(&device, width, height); // the vertex buffer used for rendering squares let square_vertices = SQUARE @@ -273,8 +240,6 @@ impl Renderer { instance_buffer_size, instances, camera, - camera_buffer, - camera_bind_group, textures, window, }) @@ -396,14 +361,6 @@ impl Renderer { ); } - fn refresh_camera_buffer(&mut self) { - self.queue.write_buffer( - &self.camera_buffer, - 0 as wgpu::BufferAddress, - bytemuck::cast_slice(&self.camera.to_matrix()), - ); - } - /// Renders a new frame to the window /// /// # Errors @@ -433,7 +390,7 @@ impl Renderer { .try_into() .expect("expected less than 3 billion instances"); - self.refresh_camera_buffer(); + self.camera.refresh(&self.queue); self.textures.fill_textures(&self.queue); { @@ -451,7 +408,7 @@ impl Renderer { }); render_pass.set_pipeline(&self.render_pipeline); - render_pass.set_bind_group(0, &self.camera_bind_group, &[]); + render_pass.set_bind_group(0, self.camera.bind_group(), &[]); render_pass.set_bind_group(1, self.textures.bind_group(), &[]); render_pass.set_vertex_buffer(0, self.square_vertex_buffer.slice(..)); render_pass.set_vertex_buffer(1, self.instance_buffer.slice(..)); diff --git a/src/texture.rs b/src/texture.rs index 456f230..457fea8 100644 --- a/src/texture.rs +++ b/src/texture.rs @@ -62,6 +62,7 @@ impl From<ImageError> for TextureError { // TODO make this Debug // TODO make these resizable +// TODO this could probably be moved into WgpuTextures pub struct TextureAtlases<'a> { packer: MultiTexturePacker<'a, image::RgbaImage, TextureId>, images: Vec<RgbaImage>, |
