Skip to main content

grafix_toolbox/kit/opengl/utility/image/
tex_to_img.rs

1use {super::*, GL::*};
2
3#[cfg(feature = "adv_fs")]
4mod _ser {
5	use super::{ser::*, *};
6	impl<S: TexSize, F: TexFmt> Serialize for Tex2d<S, F> {
7		fn serialize<SE: Serializer>(&self, s: SE) -> Result<SE::Ok, SE::Error> {
8			ASSERT!(self.param().l == 1, "MIPS NOT IMPL");
9			Image::<S, F>::from(self).serialize(s)
10		}
11	}
12	impl<'de, S: TexSize, F: TexFmt> Deserialize<'de> for Tex2d<S, F> {
13		fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
14			Ok(Image::<S, F>::deserialize(d)?.into())
15		}
16	}
17}
18
19impl<S: TexSize, F: TexFmt> Tex2d<S, F> {
20	pub fn Cut(&self, region: iVec4) -> Tex2d<S, F> {
21		let _s = self.whdl().xy();
22		ASSERT!(region.gt(0).all() && region.zw().sub(region.xy()).ls(_s).all(), "Cutting invalid texture region");
23		let img: Image<_, _> = self.into(); //TODO use glCopyTexSubImage2D, move to texture
24		img.cut(vec4(region)).into()
25	}
26	pub fn Cast<RS: TexSize, RF: TexFmt>(&self, minification: i32) -> Tex2d<RS, RF> {
27		let s = LeakyStatic!(Shader, { [vs_mesh__2d_screen, ps_mesh__2d_screen].pipe(Shader::pure) });
28		let sampl = &Sampler::linear();
29
30		GLSave!(BLEND);
31		GLDisable!(BLEND);
32
33		let out = self.whdl().xy().div(minification).fmax(1).pipe(Fbo::new);
34		let t = self.Bind(sampl);
35		let _ = Uniforms!(s, ("iTex", t));
36		out.bind();
37		Screen::Draw();
38
39		GLRestore!(BLEND);
40		out.tex
41	}
42}
43
44impl<S: TexSize, F: TexFmt, RS, RF> From<&Tex2d<RS, RF>> for Image<S, F> {
45	fn from(tex: &Tex2d<RS, RF>) -> Self {
46		let ((w, h), data) = (uVec2(tex.whdl().xy()), tex.Save::<S, F>(0));
47		Self { w, h, data, s: Dummy }
48	}
49}
50impl<S: TexSize, F: TexFmt, RS, RF> From<Tex2d<RS, RF>> for Image<S, F> {
51	fn from(tex: Tex2d<RS, RF>) -> Self {
52		(&tex).into()
53	}
54}
55
56impl<S: TexSize, F: TexFmt, T: Borrow<Image<S, F>>> From<T> for Tex2d<S, F> {
57	fn from(img: T) -> Self {
58		let img = img.borrow();
59		Tex2d::new((img.w, img.h), &img.data[..])
60	}
61}
62impl<S: TexSize, F: TexFmt> Tex2d<S, F> {
63	pub fn from_type<RS: TexSize, RF: TexFmt>(img: &Image<RS, RF>) -> Self {
64		Tex2d::new_empty((img.w, img.h), 1).tap(|t| t.UpdateCustom::<RS, RF, _>(&img.data[..]))
65	}
66}
67
68impl<S: TexSize, F: TexFmt> From<&[&Cube<S, F>]> for CubeTex<S, F> {
69	fn from(mips: &[&Cube<S, F>]) -> Self {
70		let w = i32(mips[0][0].w);
71		let p = TexParam { w, h: w, d: 1, l: i32(mips.len()) }.validate();
72		CubeTex::new_empty((p.w, p.h), p.l).tap(|t| {
73			mips.iter().enumerate().for_each(|(l, cube)| {
74				cube.iter().enumerate().for_each(|(n, i)| {
75					debug_assert!({
76						let (_w, _h, _) = uVec3(p.dim(l));
77						ASSERT!(_w == i.w && _h == i.h, "Mip size {:?} at level {l}, must be {:?}", (_w, _h), (i.w, i.h));
78						true
79					});
80
81					t.Update((&i.data, l, 0, 0, n));
82				})
83			})
84		})
85	}
86}
87impl<S: TexSize, F: TexFmt> From<&[Cube<S, F>]> for CubeTex<S, F> {
88	fn from(m: &[Cube<S, F>]) -> Self {
89		m.iter().collect_vec().as_slice().into()
90	}
91}
92impl<S: TexSize, F: TexFmt> From<&Cube<S, F>> for CubeTex<S, F> {
93	fn from(m: &Cube<S, F>) -> Self {
94		[m][..].into()
95	}
96}
97type Cube<S, F> = [Image<S, F>; 6];