diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/camera.rs | 19 | ||||
| -rw-r--r-- | src/config.rs | 3 | ||||
| -rw-r--r-- | src/instance.rs | 15 | ||||
| -rw-r--r-- | src/renderer.rs | 3 | ||||
| -rw-r--r-- | src/texture.rs | 14 | ||||
| -rw-r--r-- | src/vertex.rs | 12 |
6 files changed, 45 insertions, 21 deletions
diff --git a/src/camera.rs b/src/camera.rs index e77da40..ecece90 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -19,21 +19,6 @@ fn inverse_aspect_ratio(width: u32, height: u32) -> f32 { (height as f32) / (width as f32) } -fn create_bind_group( - device: &wgpu::Device, - buffer: &wgpu::Buffer, - layout: &wgpu::BindGroupLayout, -) -> wgpu::BindGroup { - device.create_bind_group(&wgpu::BindGroupDescriptor { - label: Some("Camera Bind Group"), - layout, - entries: &[wgpu::BindGroupEntry { - binding: 0, - resource: buffer.as_entire_binding(), - }], - }) -} - impl Camera { /// Create a new camera, with a position of (0, 0), and a zoom of 1.0 pub(crate) fn new( @@ -150,6 +135,8 @@ impl Camera { self.inverse_aspect_ratio = inverse_aspect_ratio(width, height); } + /// Create a matrix that can be multiplied by any vector to transform it + /// according to the current camera #[allow(clippy::wrong_self_convention)] fn to_matrix(&self) -> CameraUniform { let cos = self.rotation.cos(); @@ -183,10 +170,12 @@ impl Camera { transform.into() } + /// Get the bind group for the camera pub(crate) const fn bind_group(&self) -> &wgpu::BindGroup { &self.bind_group } + /// Refresh the camera buffer for the next frame #[profiling::function] pub(crate) fn refresh(&self, queue: &wgpu::Queue) { queue.write_buffer( diff --git a/src/config.rs b/src/config.rs index 9376049..c73c357 100644 --- a/src/config.rs +++ b/src/config.rs @@ -86,6 +86,7 @@ impl<'a> Default for RenderWindowConfig<'a> { } impl<'a> RenderWindowConfig<'a> { + /// Based on the vsync settings, choose a presentation mode pub(crate) fn present_mode( vsync: bool, supported_modes: &[wgpu::PresentMode], @@ -101,6 +102,7 @@ impl<'a> RenderWindowConfig<'a> { } } + /// Pick an alpha mode fn alpha_mode(supported_modes: &[wgpu::CompositeAlphaMode]) -> wgpu::CompositeAlphaMode { if supported_modes.contains(&wgpu::CompositeAlphaMode::PostMultiplied) { wgpu::CompositeAlphaMode::PostMultiplied @@ -180,6 +182,7 @@ impl<'a> RenderWindowConfig<'a> { } } + /// Get the power preference pub(crate) const fn power_preference(&self) -> wgpu::PowerPreference { if self.low_power { wgpu::PowerPreference::LowPower diff --git a/src/instance.rs b/src/instance.rs index 2bff797..2d1808f 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -2,9 +2,11 @@ use std::mem::size_of; use bytemuck::{Pod, Zeroable}; +/// The ID for an instance #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] pub struct InstanceId(usize); +/// A sprite, that can be used by the alligator shader #[repr(C)] #[derive(Copy, Clone, Debug, PartialEq, Pod, Zeroable)] pub struct Instance { @@ -59,6 +61,7 @@ impl Instance { } } +/// A buffer of sprites, for both CPU and GPU memory pub struct InstanceBuffer { instances: Vec<Instance>, instance_buffer: wgpu::Buffer, @@ -75,6 +78,7 @@ fn create_buffer(device: &wgpu::Device, instances: &Vec<Instance>) -> wgpu::Buff } impl InstanceBuffer { + /// Create a new buffer with the given capacity pub(crate) fn new(device: &wgpu::Device, capacity: usize) -> Self { let instances = Vec::with_capacity(capacity); let instance_buffer_size = instances.capacity(); @@ -87,6 +91,7 @@ impl InstanceBuffer { } } + /// The number of sprites pub fn len(&self) -> u32 { self.instances .len() @@ -94,41 +99,51 @@ impl InstanceBuffer { .expect("expected less than 3 billion instances") } + /// Returns `true` if there are no sprites pub fn is_empty(&self) -> bool { self.instances.is_empty() } + /// The capacity of the buffer pub const fn buffer_size(&self) -> usize { self.instance_buffer_size } + /// Get a slice containing the entire buffer pub(crate) fn buffer_slice(&self) -> wgpu::BufferSlice { self.instance_buffer.slice(..) } + /// Add a new sprite. The new sprite's `InstanceId` is returned. This ID + /// becomes invalid if the buffer is cleared. pub fn push_instance(&mut self, instance: Instance) -> InstanceId { let index = self.instances.len(); self.instances.push(instance); InstanceId(index) } + /// Get a specific instance pub fn get_instance(&self, id: InstanceId) -> Option<&Instance> { self.instances.get(id.0) } + /// Get a mutable reference to a specific sprite pub fn get_instance_mut(&mut self, id: InstanceId) -> Option<&mut Instance> { self.instances.get_mut(id.0) } + /// Clear the instance buffer. This invalidates all `InstanceId`'s pub fn clear(&mut self) { self.instances.clear(); } + /// Increase the capacity of the buffer fn expand_buffer(&mut self, device: &wgpu::Device) { self.instance_buffer_size = self.instances.capacity(); self.instance_buffer = create_buffer(device, &self.instances); } + /// Fill the GPU buffer with the sprites in the CPU buffer. #[profiling::function] pub(crate) fn fill_buffer(&mut self, device: &wgpu::Device, queue: &wgpu::Queue) { if self.instances.len() > self.instance_buffer_size { diff --git a/src/renderer.rs b/src/renderer.rs index e97b0fd..4768615 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -230,6 +230,7 @@ impl Renderer { }) } + /// Reconfigure the surface fn reconfigure(&mut self) { self.surface.configure(&self.device, &self.surface_config); } @@ -286,10 +287,12 @@ impl Renderer { &mut self.camera } + /// Get a reference to the texture atlas pub const fn textures(&self) -> &TextureAtlas { &self.textures } + /// Get a mutable reference to the texture atlas pub fn textures_mut(&mut self) -> &mut TextureAtlas { &mut self.textures } diff --git a/src/texture.rs b/src/texture.rs index 3b998a8..ee9ff26 100644 --- a/src/texture.rs +++ b/src/texture.rs @@ -13,6 +13,7 @@ use thiserror::Error; static NEXT_TEXTURE_ID: AtomicUsize = AtomicUsize::new(0); +/// The unique ID for a subtexture #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub struct TextureId(usize); @@ -23,7 +24,9 @@ impl TextureId { } } +/// These are the formats supported by the renderer. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[non_exhaustive] pub enum ImageFormat { Bmp, Ico, @@ -40,10 +43,12 @@ impl ImageFormat { } } +/// The texture did not fit in the texture atlas #[derive(Debug, Error)] #[error("{:?}", .0)] pub struct PackError(PackErrorInternal); +// TODO this can be removed when a new texture packer is made type PackErrorInternal = impl std::fmt::Debug; #[derive(Error, Debug)] @@ -73,6 +78,7 @@ impl From<ImageError> for TextureError { } } +/// Simpler constructor for a wgpu extent3d const fn extent_3d(width: u32, height: u32) -> wgpu::Extent3d { wgpu::Extent3d { width, @@ -81,6 +87,7 @@ const fn extent_3d(width: u32, height: u32) -> wgpu::Extent3d { } } +/// A texture atlas, usable by the renderer // TODO make this Debug // TODO make these resizable pub struct TextureAtlas { @@ -190,10 +197,12 @@ impl TextureAtlas { ) } + /// get the bind group for the texture pub(crate) const fn bind_group(&self) -> &wgpu::BindGroup { &self.diffuse_bind_group } + /// Load a new subtexture from memory // TODO support RGBA16 pub fn load_from_memory( &mut self, @@ -204,12 +213,14 @@ impl TextureAtlas { Ok(self.pack_rgba8(img)?) } + /// Add a new subtexture pub fn pack_rgba8(&mut self, img: RgbaImage) -> Result<TextureId, PackError> { let id = TextureId::new(); self.packer.pack_own(id, img).map_err(PackError)?; Ok(id) } + /// Get the frame for s particular subtexture fn texture_frame(&self, id: TextureId) -> Option<&texture_packer::Frame<TextureId>> { self.packer.get_frame(&id) } @@ -219,6 +230,7 @@ impl TextureAtlas { texture_info!(texture_x, x, width); texture_info!(texture_y, y, height); + /// Fill the cached image fn fill_image(&mut self) -> ExportResult<()> { let atlas = { profiling::scope!("export atlas"); @@ -231,6 +243,7 @@ impl TextureAtlas { Ok(()) } + /// Clear the texture atlas pub fn clear(&mut self) { self.packer = TexturePacker::new_skyline(TexturePackerConfig { max_width: self.width, @@ -239,6 +252,7 @@ impl TextureAtlas { }); } + /// Fill the GPU texture atlas #[profiling::function] pub fn fill_textures(&mut self, queue: &wgpu::Queue) { // saves time if nothing changed since the last time we did this diff --git a/src/vertex.rs b/src/vertex.rs index a24a601..570eec4 100644 --- a/src/vertex.rs +++ b/src/vertex.rs @@ -12,6 +12,7 @@ pub const SQUARE: [Vertex; 6] = [ Vertex::new(0.5, -0.5), ]; +/// A vertex that is usable by the alligator shader #[repr(C)] #[derive(Copy, Clone, Debug, PartialEq, Pod, Zeroable)] pub struct Vertex { @@ -19,16 +20,15 @@ pub struct Vertex { } impl Vertex { - const fn new(x: f32, y: f32) -> Self { - Self { position: [x, y] } - } -} - -impl Vertex { // whenever this is updated, please also update `sprite.wgsl` pub(crate) const ATTRIBUTES: [wgpu::VertexAttribute; 1] = wgpu::vertex_attr_array![0 => Float32x2]; + /// Create a new vertex + const fn new(x: f32, y: f32) -> Self { + Self { position: [x, y] } + } + pub(crate) const fn desc<'a>() -> wgpu::VertexBufferLayout<'a> { wgpu::VertexBufferLayout { array_stride: size_of::<Self>() as wgpu::BufferAddress, |
