From 9aafb51e0be1720019db1c3d0a294ce9a42653df Mon Sep 17 00:00:00 2001 From: HampusM Date: Thu, 2 Nov 2023 20:22:33 +0100 Subject: feat(engine): add texturing --- engine/src/texture.rs | 100 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 engine/src/texture.rs (limited to 'engine/src/texture.rs') diff --git a/engine/src/texture.rs b/engine/src/texture.rs new file mode 100644 index 0000000..7874df4 --- /dev/null +++ b/engine/src/texture.rs @@ -0,0 +1,100 @@ +use std::path::Path; + +use image::io::Reader as ImageReader; +use image::{DynamicImage, ImageError}; + +use crate::opengl::texture::Texture as InnerTexture; +use crate::vector::Vec2; + +mod reexports +{ + pub use crate::opengl::texture::{Filtering, Wrapping}; +} + +pub use reexports::*; + +#[derive(Debug)] +pub struct Texture +{ + inner: InnerTexture, +} + +impl Texture +{ + /// 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 + { + let image = ImageReader::open(path) + .map_err(Error::OpenImageFailed)? + .decode() + .map_err(Error::DecodeImageFailed)?; + + if !matches!(image, DynamicImage::ImageRgb8(_)) { + return Err(Error::UnsupportedImageDataKind); + } + + let inner = InnerTexture::new(); + + inner.bind(|texture_curr_bound| { + InnerTexture::generate( + &texture_curr_bound, + &Vec2 { x: image.width(), y: image.height() }, + image.as_bytes(), + ); + }); + + let me = Self { inner }; + + me.set_wrap(Wrapping::Repeat); + me.set_magnifying_filter(Filtering::Linear); + me.set_minifying_filter(Filtering::Nearest); + + Ok(me) + } + + pub fn set_wrap(&self, wrapping: Wrapping) + { + self.inner.bind(|texture_curr_bound| { + InnerTexture::set_wrap(texture_curr_bound, wrapping); + }); + } + + pub fn set_magnifying_filter(&self, filtering: Filtering) + { + self.inner.bind(|texture_curr_bound| { + InnerTexture::set_magnifying_filter(texture_curr_bound, filtering); + }); + } + + pub fn set_minifying_filter(&self, filtering: Filtering) + { + self.inner.bind(|texture_curr_bound| { + InnerTexture::set_minifying_filter(texture_curr_bound, filtering); + }); + } + + pub(crate) fn inner(&self) -> &InnerTexture + { + &self.inner + } +} + +/// Texture error. +#[derive(Debug, thiserror::Error)] +pub enum Error +{ + #[error("Failed to open texture image")] + OpenImageFailed(#[source] std::io::Error), + + #[error("Failed to decode texture image")] + DecodeImageFailed(#[source] ImageError), + + #[error("Unsupported image data kind")] + UnsupportedImageDataKind, +} -- cgit v1.2.3-18-g5258