summaryrefslogtreecommitdiff
path: root/engine
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2025-01-22 18:00:03 +0100
committerHampusM <hampus@hampusmat.com>2025-01-22 18:00:03 +0100
commitf5b3b11ad449a60322bca096de010a35ba2b30c8 (patch)
tree890d22e5470435359bf66ce4bd21c52ea778dd2d /engine
parent912ce3cc3890c698793691caa13c29df0723e16f (diff)
feat(engine): add texture & texture properties builders
Diffstat (limited to 'engine')
-rw-r--r--engine/src/texture.rs152
1 files changed, 107 insertions, 45 deletions
diff --git a/engine/src/texture.rs b/engine/src/texture.rs
index 16c1941..4a4fe86 100644
--- a/engine/src/texture.rs
+++ b/engine/src/texture.rs
@@ -8,6 +8,7 @@ use image::{DynamicImage, ImageError, Rgb, RgbImage};
use crate::color::Color;
use crate::data_types::dimens::Dimens;
use crate::opengl::texture::PixelDataFormat;
+use crate::util::builder;
static NEXT_ID: AtomicU32 = AtomicU32::new(0);
@@ -30,62 +31,26 @@ pub struct Texture
impl Texture
{
+ pub fn builder() -> Builder
+ {
+ Builder::default()
+ }
+
/// Opens a texture image.
///
/// # Errors
/// Will return `Err` if:
/// - Opening the image fails
/// - The image data is not 8-bit/color RGB
- #[allow(clippy::new_without_default)]
pub fn open(path: &Path) -> Result<Self, Error>
{
- let image = ImageReader::open(path)
- .map_err(Error::OpenImageFailed)?
- .decode()
- .map_err(Error::DecodeImageFailed)?;
-
- let pixel_data_format = match &image {
- DynamicImage::ImageRgb8(_) => PixelDataFormat::Rgb8,
- DynamicImage::ImageRgba8(_) => PixelDataFormat::Rgba8,
- _ => {
- return Err(Error::UnsupportedImageDataKind);
- }
- };
-
- let dimensions = Dimens {
- width: image.width(),
- height: image.height(),
- };
-
- let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
-
- Ok(Self {
- id: Id::new(id),
- image,
- pixel_data_format,
- dimensions,
- properties: Properties::default(),
- })
+ Self::builder().open(path)
}
#[must_use]
pub fn new_from_color(dimensions: &Dimens<u32>, color: &Color<u8>) -> Self
{
- let image = RgbImage::from_pixel(
- dimensions.width,
- dimensions.height,
- Rgb([color.red, color.green, color.blue]),
- );
-
- let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
-
- Self {
- id: Id::new(id),
- image: image.into(),
- pixel_data_format: PixelDataFormat::Rgb8,
- dimensions: *dimensions,
- properties: Properties::default(),
- }
+ Self::builder().build_with_single_color(dimensions, color)
}
#[must_use]
@@ -132,6 +97,84 @@ impl Drop for Texture
}
}
+/// Texture builder.
+#[derive(Debug, Default, Clone)]
+pub struct Builder
+{
+ properties: Properties,
+}
+
+impl Builder
+{
+ pub fn properties(mut self, properties: Properties) -> Self
+ {
+ self.properties = properties;
+ self
+ }
+
+ /// Opens a image as a texture.
+ ///
+ /// # Errors
+ /// Will return `Err` if:
+ /// - Opening the image fails
+ /// - Decoding the image fails
+ /// - The image data is in a unsupported format
+ pub fn open(&self, path: &(impl AsRef<Path> + ?Sized)) -> Result<Texture, Error>
+ {
+ let image = ImageReader::open(path)
+ .map_err(Error::OpenImageFailed)?
+ .decode()
+ .map_err(Error::DecodeImageFailed)?;
+
+ let pixel_data_format = match &image {
+ DynamicImage::ImageRgb8(_) => PixelDataFormat::Rgb8,
+ DynamicImage::ImageRgba8(_) => PixelDataFormat::Rgba8,
+ _ => {
+ return Err(Error::UnsupportedImageDataFormat);
+ }
+ };
+
+ let dimensions = Dimens {
+ width: image.width(),
+ height: image.height(),
+ };
+
+ let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
+
+ Ok(Texture {
+ id: Id::new(id),
+ image,
+ pixel_data_format,
+ dimensions,
+ properties: self.properties.clone(),
+ })
+ }
+
+ #[must_use]
+ pub fn build_with_single_color(
+ &self,
+ dimensions: &Dimens<u32>,
+ color: &Color<u8>,
+ ) -> Texture
+ {
+ let image = RgbImage::from_pixel(
+ dimensions.width,
+ dimensions.height,
+ Rgb([color.red, color.green, color.blue]),
+ );
+
+ let id = NEXT_ID.fetch_add(1, Ordering::Relaxed);
+
+ Texture {
+ id: Id::new(id),
+ image: image.into(),
+ pixel_data_format: PixelDataFormat::Rgb8,
+ dimensions: *dimensions,
+ properties: self.properties.clone(),
+ }
+ }
+}
+
/// Texture error.
#[derive(Debug, thiserror::Error)]
pub enum Error
@@ -142,11 +185,13 @@ pub enum Error
#[error("Failed to decode texture image")]
DecodeImageFailed(#[source] ImageError),
- #[error("Unsupported image data kind")]
- UnsupportedImageDataKind,
+ #[error("Unsupported image data format")]
+ UnsupportedImageDataFormat,
}
+builder! {
/// Texture properties
+#[builder(name = PropertiesBuilder, derives=(Debug, Clone))]
#[derive(Debug, Clone)]
#[non_exhaustive]
pub struct Properties
@@ -155,6 +200,15 @@ pub struct Properties
pub magnifying_filter: Filtering,
pub minifying_filter: Filtering,
}
+}
+
+impl Properties
+{
+ pub fn builder() -> PropertiesBuilder
+ {
+ PropertiesBuilder::default()
+ }
+}
impl Default for Properties
{
@@ -168,6 +222,14 @@ impl Default for Properties
}
}
+impl Default for PropertiesBuilder
+{
+ fn default() -> Self
+ {
+ Properties::default().into()
+ }
+}
+
/// Texture ID.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Id