diff options
author | HampusM <hampus@hampusmat.com> | 2023-11-02 20:22:33 +0100 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2023-11-02 20:22:33 +0100 |
commit | 9aafb51e0be1720019db1c3d0a294ce9a42653df (patch) | |
tree | 40881ff26bff5a928280223d8aced87e1370d63b /engine/src/texture.rs | |
parent | f2c54d47e6b61198520824117339aaa21c32accd (diff) |
feat(engine): add texturing
Diffstat (limited to 'engine/src/texture.rs')
-rw-r--r-- | engine/src/texture.rs | 100 |
1 files changed, 100 insertions, 0 deletions
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<Self, Error> + { + 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, +} |