diff options
Diffstat (limited to 'alligator_resources/src/texture.rs')
| -rw-r--r-- | alligator_resources/src/texture.rs | 42 |
1 files changed, 33 insertions, 9 deletions
diff --git a/alligator_resources/src/texture.rs b/alligator_resources/src/texture.rs index 79e0e94..4b4baa4 100644 --- a/alligator_resources/src/texture.rs +++ b/alligator_resources/src/texture.rs @@ -20,6 +20,7 @@ impl TextureId { } /// These are the formats supported by the renderer. +// TODO make these feature-enabled #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[non_exhaustive] pub enum ImageFormat { @@ -92,8 +93,8 @@ impl TextureManager { let atlas: Box<[MaybeUninit<u16>]> = Box::new_zeroed_slice((4 * width * height) as _); let atlas = unsafe { atlas.assume_init() }; - let atlas = - Rgba16Texture::from_raw(width, height, atlas).expect("atlas cache is too small"); + let atlas = Rgba16Texture::from_raw(width, height, atlas); + let atlas = atlas.expect("atlas cache is too small"); Self { textures, @@ -104,9 +105,32 @@ impl TextureManager { } } + pub fn load_to_atlas(&mut self, id: TextureId) { + let texture = self.texture(id); + if self.packer.pack_own(id, texture.clone()).is_err() { + let texture = self.texture(id); + self.resize_atlas(self.width + texture.width(), self.height + texture.height()); + + let texture = self.texture(id); + self.packer + .pack_own(id, texture.clone()) + .expect("packer is still too small after resizing"); + } + } + /// Resize the texture atlas pub fn resize_atlas(&mut self, width: u32, height: u32) { - self.packer = packer(width, height); + let old_packer = &self.packer; + let mut new_packer = packer(width, height); + + for id in old_packer.get_frames().keys() { + let texture = self.texture(*id).clone(); + new_packer + .pack_own(*id, texture) + .expect("resized packer is too small to hold subtextures"); + } + + self.packer = new_packer; } /// Clear the texture atlas @@ -120,7 +144,6 @@ impl TextureManager { /// /// This returns `Expected(DecodingError)` if the given buffer was invalid /// for the given format. - #[allow(clippy::missing_panics_doc)] pub fn load_from_memory( &mut self, buf: &[u8], @@ -134,6 +157,7 @@ impl TextureManager { let width = texture.width(); let height = texture.height(); let buf = texture.into_raw().into_boxed_slice(); + // TODO this expect can be removed by using unexpect let texture = ImageBuffer::from_raw(width, height, buf).expect("image buffer is too small"); self.textures.insert(id, texture); @@ -155,11 +179,11 @@ impl TextureManager { &self.atlas } - fn texture(&self, id: TextureId) -> Option<&Rgba16Texture> { - self.textures.get(&id) + fn texture(&self, id: TextureId) -> &Rgba16Texture { + self.textures.get(&id).expect("invalid TextureId") } - /// Get the subtexture + /// Get the subtexture in the texture atlas fn subtexture(&self, id: TextureId) -> Option<&Frame<TextureId>> { self.packer.get_frame(&id) } @@ -184,7 +208,7 @@ impl TextureManager { #[must_use] #[allow(clippy::cast_precision_loss)] pub fn texture_width(&self, id: TextureId) -> f32 { - let width = self.texture(id).expect("invalid TextureId").width(); + let width = self.texture(id).width(); width as f32 / self.width as f32 } @@ -192,7 +216,7 @@ impl TextureManager { #[must_use] #[allow(clippy::cast_precision_loss)] pub fn texture_height(&self, id: TextureId) -> f32 { - let height = self.texture(id).expect("invalid TextureId").height(); + let height = self.texture(id).height(); height as f32 / self.height as f32 } } |
