darkengine 0.1.0

2D game engine written in Rust
use std::path::Path;
use graphics::Display;
use glium::{backend::Facade, texture::{RawImage2d, Texture2d, UncompressedFloatFormat, MipmapsOption}};
use image;

pub use glium::uniforms::SamplerWrapFunction as TextureWrapFunction;
pub use glium::uniforms::MinifySamplerFilter as TextureMinFilter;
pub use glium::uniforms::MagnifySamplerFilter as TextureMagFilter;

/// A texture.
pub struct Texture {
	texture: Texture2d,
	width: u32,
	height: u32,
	pub(crate) wrap: TextureWrapFunction,
	pub(crate) min: TextureMinFilter,
	pub(crate) mag: TextureMagFilter
}

impl Texture {
	/// Load a texture from a file.
	/// # Example
	/// ```rust,no_run
	/// # #[macro_use]
	/// # extern crate darkengine;
	/// # use darkengine::graphics::Texture;
	/// # fn main() {
	/// # let display: darkengine::graphics::Display = None.unwrap();
	/// let texture = Texture::load(canon_str!("texture.png"), &display).unwrap();
	/// # }
	/// ```
	pub fn load(path: &Path, display: &Display) -> Result<Texture, ()> {
		match image::open(path) {
			Ok(image) => {
				let image = image.to_rgba();
				let dimensions = image.dimensions();
				let image = RawImage2d::from_raw_rgba(image.into_raw(), dimensions);
				let texture = Texture2d::with_format(
					display,
					image,
					UncompressedFloatFormat::U8U8U8U8,
					MipmapsOption::NoMipmap
				).unwrap();
				Ok(Texture {
					texture,
					width: dimensions.0,
					height: dimensions.1,
					wrap: TextureWrapFunction::Repeat,
					min: TextureMinFilter::Nearest,
					mag: TextureMagFilter::Nearest
				})
			},
			Err(_) => Err(())
		}
	}

	/// Load a texture from a byte array.
	/// # Example
	/// ```rust,no_run
	/// # use darkengine::graphics::Texture;
	/// # macro_rules! include_bytes {($e:expr) => {&[]}}
	/// # let display: darkengine::graphics::Display = None.unwrap();
	/// let texture = Texture::load_bytes(include_bytes!("texture.png"), &display).unwrap();
	/// ```
	pub fn load_bytes(bytes: &[u8], display: &Display) -> Result<Texture, ()> {
		match image::load_from_memory(bytes) {
			Ok(image) => {
				let image = image.to_rgba();
				let dimensions = image.dimensions();
				let image = RawImage2d::from_raw_rgba_reversed(&image.into_raw(), dimensions);
				let texture = Texture2d::new(display.get_context(), image).unwrap();
				Ok(Texture {
					texture,
					width: dimensions.0,
					height: dimensions.1,
					wrap: TextureWrapFunction::Repeat,
					min: TextureMinFilter::Nearest,
					mag: TextureMagFilter::Nearest
				})
			},
			Err(_) => Err(())
		}
	}

	/// Set the wrap function.
	pub fn set_wrap_function(&mut self, wrap: TextureWrapFunction) {
		self.wrap = wrap;
	}

	/// The wrap function.
	pub fn wrap_function(&mut self) -> TextureWrapFunction {
		self.wrap
	}

	/// Set the minification filter.
	pub fn set_min_filter(&mut self, min: TextureMinFilter) {
		self.min = min;
	}

	/// The minification filter.
	pub fn min_filter(&mut self) -> TextureMinFilter {
		self.min
	}

	/// Set the magnification filter.
	pub fn set_mag_filter(&mut self, mag: TextureMagFilter) {
		self.mag = mag;
	}

	/// The magnification filter.
	pub fn mag_filter(&mut self) -> TextureMagFilter {
		self.mag
	}

	/// Texture dimensions.
	pub fn size(&self) -> (u32, u32) {
		(self.width, self.height)
	}

	pub(crate) fn new(texture: Texture2d, width: u32, height: u32) -> Texture {
		Texture {
			texture,
			width,
			height,
			wrap: TextureWrapFunction::Repeat,
			min: TextureMinFilter::Nearest,
			mag: TextureMagFilter::Nearest
		}
	}

	pub(crate) fn internal(&self) -> &Texture2d {
		&self.texture
	}
}