summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/camera.rs76
-rw-r--r--src/renderer.rs49
-rw-r--r--src/texture.rs1
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>,