radiant_rs/core/
texture.rs1use crate::prelude::*;
2use crate::core::{Context, Color, Uniform, AsUniform, RenderTarget, AsRenderTarget, Point2};
3use crate::core::builder::*;
4use image::{self, GenericImageView};
5use crate::backends::backend;
6
7#[derive(Clone)]
13pub struct Texture {
14 pub(crate) handle : Rc<backend::Texture2d>,
15 pub(crate) minify : TextureFilter,
16 pub(crate) magnify : TextureFilter,
17 pub(crate) wrap : TextureWrap,
18 pub(crate) dimensions : Point2<u32>,
19}
20
21impl Debug for Texture {
22 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
23 f.debug_struct("Texture")
24 .field("minify", &self.minify)
25 .field("magnify", &self.magnify)
26 .field("wrap", &self.wrap)
27 .field("dimensions", &self.dimensions)
28 .finish()
29 }
30}
31
32impl Texture {
33 pub fn builder(context: &Context) -> TextureBuilder<'_> {
50 TextureBuilder::new(context)
51 }
52 pub fn new(context: &Context, width: u32, height: u32) -> Self {
55 Self::builder(context).width(width).height(height).build().unwrap()
56 }
57 pub fn from_file(context: &Context, file: &str) -> crate::core::Result<Self> {
59 Self::builder(context).file(file).build()
60 }
61 pub fn filtered(context: &Context, width: u32, height: u32, minify: TextureFilter, magnify: TextureFilter) -> Self {
63 Self::builder(context).width(width).height(height).minify(minify).magnify(magnify).build().unwrap()
64 }
65 pub fn clone_with_options(self: &Self, minify: TextureFilter, magnify: TextureFilter, wrap: TextureWrap) -> Self {
67 Texture {
68 handle : self.handle.clone(),
69 minify : minify,
70 magnify : magnify,
71 wrap : wrap,
72 dimensions : self.dimensions,
73 }
74 }
75 pub fn clear(self: &Self, color: Color) {
77 self.handle.clear(color);
78 }
79 pub fn dimensions(self: &Self) -> Point2<u32> {
81 self.dimensions
82 }
83 pub(crate) fn from_builder(mut builder: TextureBuilder) -> crate::core::Result<Self> {
85 let mut context = builder.context.lock();
86 let context = context.deref_mut();
87 if let Some(filename) = builder.file {
88 let image = image::open(filename)?;
89 builder.width = image.dimensions().0;
90 builder.height = image.dimensions().1;
91 builder.format = crate::core::TextureFormat::U8U8U8U8;
92 builder.data = Some(crate::core::RawFrame {
93 data: crate::core::convert_color(image.into_rgba8()).into_raw(),
94 width: builder.width,
95 height: builder.height,
96 channels: 4,
97 });
98 }
99 let texture = backend::Texture2d::new(context.backend_context.as_ref().unwrap(), builder.width, builder.height, builder.format, builder.data);
100 Ok(Texture {
101 handle : Rc::new(texture),
102 minify : builder.minify,
103 magnify : builder.magnify,
104 wrap : builder.wrap,
105 dimensions : (builder.width, builder.height),
106 })
107 }
108}
109
110impl AsRenderTarget for Texture {
111 fn as_render_target(self: &Self) -> RenderTarget {
112 RenderTarget::texture(self)
113 }
114}
115
116impl AsUniform for Texture {
117 fn as_uniform(self: &Self) -> Uniform {
118 Uniform::Texture(self.clone())
119 }
120}
121
122#[derive(Copy, Clone, Debug, PartialEq)]
124pub enum TextureFilter {
125 Linear,
127 Nearest,
129}
130
131#[derive(Copy, Clone, Debug, PartialEq)]
133pub enum TextureWrap {
134 Repeat,
136 Mirror,
138 Clamp,
140 MirrorClamp,
142}
143
144#[derive(Copy, Clone, Debug, PartialEq)]
148pub enum TextureFormat {
149 U8,
150 U16,
151 U8U8,
152 U16U16,
153 U10U10U10,
154 U12U12U12,
155 U16U16U16,
156 U2U2U2U2,
157 U4U4U4U4,
158 U5U5U5U1,
159 U8U8U8U8,
160 U10U10U10U2,
161 U12U12U12U12,
162 U16U16U16U16,
163 I16I16I16I16,
164 F16,
165 F16F16,
166 F16F16F16F16,
167 F32,
168 F32F32,
169 F32F32F32F32,
170 F11F11F10,
171}