use crate::prelude::*;
use crate::core::{Context, Color, Uniform, AsUniform, RenderTarget, AsRenderTarget, Point2};
use crate::core::builder::*;
use image::{self, GenericImageView};
use crate::backends::backend;
#[derive(Clone)]
pub struct Texture {
pub(crate) handle : Rc<backend::Texture2d>,
pub(crate) minify : TextureFilter,
pub(crate) magnify : TextureFilter,
pub(crate) wrap : TextureWrap,
pub(crate) dimensions : Point2<u32>,
}
impl Debug for Texture {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_struct("Texture")
.field("minify", &self.minify)
.field("magnify", &self.magnify)
.field("wrap", &self.wrap)
.field("dimensions", &self.dimensions)
.finish()
}
}
impl Texture {
pub fn builder(context: &Context) -> TextureBuilder<'_> {
TextureBuilder::new(context)
}
pub fn new(context: &Context, width: u32, height: u32) -> Self {
Self::builder(context).width(width).height(height).build().unwrap()
}
pub fn from_file(context: &Context, file: &str) -> crate::core::Result<Self> {
Self::builder(context).file(file).build()
}
pub fn filtered(context: &Context, width: u32, height: u32, minify: TextureFilter, magnify: TextureFilter) -> Self {
Self::builder(context).width(width).height(height).minify(minify).magnify(magnify).build().unwrap()
}
pub fn clone_with_options(self: &Self, minify: TextureFilter, magnify: TextureFilter, wrap: TextureWrap) -> Self {
Texture {
handle : self.handle.clone(),
minify : minify,
magnify : magnify,
wrap : wrap,
dimensions : self.dimensions,
}
}
pub fn clear(self: &Self, color: Color) {
self.handle.clear(color);
}
pub fn dimensions(self: &Self) -> Point2<u32> {
self.dimensions
}
pub(crate) fn from_builder(mut builder: TextureBuilder) -> crate::core::Result<Self> {
let mut context = builder.context.lock();
let context = context.deref_mut();
if let Some(filename) = builder.file {
let image = image::open(filename)?;
builder.width = image.dimensions().0;
builder.height = image.dimensions().1;
builder.format = crate::core::TextureFormat::U8U8U8U8;
builder.data = Some(crate::core::RawFrame {
data: crate::core::convert_color(image.into_rgba8()).into_raw(),
width: builder.width,
height: builder.height,
channels: 4,
});
}
let texture = backend::Texture2d::new(context.backend_context.as_ref().unwrap(), builder.width, builder.height, builder.format, builder.data);
Ok(Texture {
handle : Rc::new(texture),
minify : builder.minify,
magnify : builder.magnify,
wrap : builder.wrap,
dimensions : (builder.width, builder.height),
})
}
}
impl AsRenderTarget for Texture {
fn as_render_target(self: &Self) -> RenderTarget {
RenderTarget::texture(self)
}
}
impl AsUniform for Texture {
fn as_uniform(self: &Self) -> Uniform {
Uniform::Texture(self.clone())
}
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum TextureFilter {
Linear,
Nearest,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum TextureWrap {
Repeat,
Mirror,
Clamp,
MirrorClamp,
}
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum TextureFormat {
U8,
U16,
U8U8,
U16U16,
U10U10U10,
U12U12U12,
U16U16U16,
U2U2U2U2,
U4U4U4U4,
U5U5U5U1,
U8U8U8U8,
U10U10U10U2,
U12U12U12U12,
U16U16U16U16,
I16I16I16I16,
F16,
F16F16,
F16F16F16F16,
F32,
F32F32,
F32F32F32F32,
F11F11F10,
}