summaryrefslogtreecommitdiff
path: root/alligator_render/src
diff options
context:
space:
mode:
Diffstat (limited to 'alligator_render/src')
-rw-r--r--alligator_render/src/lib.rs2
-rw-r--r--alligator_render/src/renderer.rs4
-rw-r--r--alligator_render/src/texture.rs85
3 files changed, 25 insertions, 66 deletions
diff --git a/alligator_render/src/lib.rs b/alligator_render/src/lib.rs
index 5e0aab6..0d76cc8 100644
--- a/alligator_render/src/lib.rs
+++ b/alligator_render/src/lib.rs
@@ -17,7 +17,5 @@ pub use instance::Instance;
pub(crate) use instance::InstanceBuffer;
pub use instance::InstanceId;
pub use renderer::Renderer;
-pub use texture::ImageFormat;
pub(crate) use texture::TextureAtlas;
-pub use texture::TextureId;
pub(crate) use vertex::Vertex;
diff --git a/alligator_render/src/renderer.rs b/alligator_render/src/renderer.rs
index f448119..fdd8c34 100644
--- a/alligator_render/src/renderer.rs
+++ b/alligator_render/src/renderer.rs
@@ -1,5 +1,5 @@
-use std::convert::TryInto;
use std::num::NonZeroU32;
+use std::{convert::TryInto, sync::Arc};
use crate::{
vertex::SQUARE, Camera, Instance, InstanceBuffer, RenderWindowConfig, TextureAtlas, Vertex,
@@ -150,7 +150,7 @@ impl Renderer {
// TODO this function needs to be smaller
pub fn new(
config: &RenderWindowConfig,
- textures: TextureManager,
+ textures: Arc<TextureManager>,
) -> Result<Self, NewRendererError> {
// build the window
let event_loop = EventLoop::new();
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,