diff options
| author | Micha White <botahamec@outlook.com> | 2023-02-05 10:28:43 -0500 |
|---|---|---|
| committer | Micha White <botahamec@outlook.com> | 2023-02-05 10:28:43 -0500 |
| commit | 4b789a715cf7b42f5ae282b8218976fd577664be (patch) | |
| tree | 91b17110d2928f56e146e3308cbdd944bbaf5c69 /alligator_render/src/texture.rs | |
| parent | 9fd7d6689d5d90679e4b0c12e463ef4e2f8bf515 (diff) | |
Move texture atlas out of alligator_resources
Diffstat (limited to 'alligator_render/src/texture.rs')
| -rw-r--r-- | alligator_render/src/texture.rs | 85 |
1 files changed, 23 insertions, 62 deletions
diff --git a/alligator_render/src/texture.rs b/alligator_render/src/texture.rs index 2a86501..0afa0af 100644 --- a/alligator_render/src/texture.rs +++ b/alligator_render/src/texture.rs @@ -1,10 +1,9 @@ use std::error::Error; use std::num::NonZeroU32; -use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; -use alligator_resources::texture::TextureManager; -use image::error::DecodingError; -use image::{EncodableLayout, GenericImage, ImageError, RgbaImage}; +use alligator_resources::texture::{LoadError, Rgba16Texture, TextureId, TextureManager}; +use image::{EncodableLayout, GenericImage, RgbaImage}; use texture_packer::TexturePacker; use texture_packer::{ exporter::{ExportResult, ImageExporter}, @@ -12,39 +11,6 @@ use texture_packer::{ }; 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); - -impl TextureId { - #[allow(clippy::new_without_default)] - #[must_use] - pub fn new() -> Self { - Self(NEXT_TEXTURE_ID.fetch_add(1, Ordering::Relaxed)) - } -} - -/// These are the formats supported by the renderer. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] -#[non_exhaustive] -pub enum ImageFormat { - Bmp, - Ico, - Farbfeld, -} - -impl ImageFormat { - const fn format(self) -> image::ImageFormat { - match self { - Self::Bmp => image::ImageFormat::Bmp, - Self::Ico => image::ImageFormat::Ico, - Self::Farbfeld => image::ImageFormat::Farbfeld, - } - } -} - /// The texture did not fit in the texture atlas #[derive(Debug, Error)] #[error("{:?}", .0)] @@ -58,20 +24,11 @@ pub enum TextureError { #[error("{:?}", .0)] TextureTooLarge(#[from] PackError), #[error("{}", .0)] - BadImage(#[from] DecodingError), // TODO don't export this + BadImage(#[from] LoadError), #[error("Unexpected Error (this is a bug in alligator_render): {}", .0)] Unexpected(#[source] Box<dyn Error>), } -impl From<ImageError> for TextureError { - fn from(ie: ImageError) -> Self { - match ie { - ImageError::Decoding(de) => de.into(), - _ => Self::Unexpected(Box::new(ie)), - } - } -} - /// Simpler constructor for a wgpu extent3d const fn extent_3d(width: u32, height: u32) -> wgpu::Extent3d { wgpu::Extent3d { @@ -85,8 +42,8 @@ const fn extent_3d(width: u32, height: u32) -> wgpu::Extent3d { // TODO make this Debug // TODO make these resizable pub struct TextureAtlas { - textures: TextureManager, - packer: TexturePacker<'static, image::RgbaImage, TextureId>, + textures: Arc<TextureManager>, + packer: TexturePacker<'static, Rgba16Texture, TextureId>, diffuse_texture: wgpu::Texture, diffuse_bind_group: wgpu::BindGroup, image: RgbaImage, @@ -97,11 +54,17 @@ pub struct TextureAtlas { macro_rules! texture_info { ($name: ident, $prop: ident, $divisor: ident) => { - pub fn $name(&self, id: TextureId) -> Option<f32> { - let frame = self.texture_frame(id)?; + pub fn $name(&mut self, id: TextureId) -> Result<f32, TextureError> { + let frame = match self.texture_frame(id) { + Some(frame) => frame, + None => { + self.load_texture(id)?; + self.texture_frame(id).unwrap() + } + }; let property = frame.frame.$prop; let value = property as f32 / self.$divisor as f32; - Some(value) + Ok(value) } }; } @@ -112,7 +75,7 @@ impl TextureAtlas { // TODO this is still too large pub fn new( device: &wgpu::Device, - textures: TextureManager, + textures: Arc<TextureManager>, width: u32, height: u32, ) -> (Self, wgpu::BindGroupLayout) { @@ -206,13 +169,8 @@ impl TextureAtlas { /// Load a new subtexture from memory // TODO support RGBA16 - pub fn load_from_memory( - &mut self, - buf: &[u8], - format: ImageFormat, - ) -> Result<TextureId, TextureError> { - let img = image::load_from_memory_with_format(buf, format.format())?.into_rgba8(); - let id = TextureId::new(); + pub fn load_texture(&mut self, id: TextureId) -> Result<TextureId, TextureError> { + let img = self.textures.load_texture(id)?; self.packer.pack_own(id, img).map_err(PackError)?; Ok(id) } @@ -240,8 +198,11 @@ impl TextureAtlas { Ok(()) } - /// Clear the texture atlas - pub fn clear(&mut self) { + /// Clear the texture atlas, and give it a new size + pub fn clear(&mut self, width: u32, height: u32) { + self.changed = true; + self.width = width; + self.height = height; self.packer = TexturePacker::new_skyline(TexturePackerConfig { max_width: self.width, max_height: self.height, |
