Skip to main content

grafix_toolbox/kit/opengl/texture/
format.rs

1use crate::lib::*;
2
3pub trait TexSize: TrivialBound {
4	const TYPE: GLenum;
5	const SIZE: usize;
6}
7macro_rules! impl_size {
8	($t: ident, $s: literal) => {
9		#[derive_as_trivial]
10		pub struct $t;
11		impl TexSize for $t {
12			const TYPE: GLenum = gl::$t;
13			const SIZE: usize = $s;
14		}
15	};
16}
17impl_size!(RED, 1);
18impl_size!(RG, 2);
19impl_size!(RGB, 3);
20impl_size!(RGBA, 4);
21
22pub trait TexFmt: TrivialBound + Cast<u8> {
23	const TYPE: GLenum;
24}
25macro_rules! impl_fmt {
26	($t: ty, $g: ident) => {
27		impl TexFmt for $t {
28			const TYPE: GLenum = gl::$g;
29		}
30	};
31}
32impl_fmt!(i8, BYTE);
33impl_fmt!(u8, UNSIGNED_BYTE);
34impl_fmt!(i16, SHORT);
35impl_fmt!(u16, UNSIGNED_SHORT);
36impl_fmt!(i32, INT);
37impl_fmt!(u32, UNSIGNED_INT);
38impl_fmt!(f16, HALF_FLOAT);
39impl_fmt!(f32, FLOAT);
40
41pub fn get_internal_fmt<S: TexSize, F: TexFmt>() -> GLenum {
42	match S::TYPE {
43		gl::RED => match F::TYPE {
44			gl::BYTE => gl::R8I,
45			gl::UNSIGNED_BYTE => gl::R8UI,
46			gl::SHORT => gl::R16I,
47			gl::UNSIGNED_SHORT => gl::R16UI,
48			gl::INT => gl::R32I,
49			gl::UNSIGNED_INT => gl::R32UI,
50			gl::HALF_FLOAT => gl::R16F,
51			gl::FLOAT => gl::R32F,
52			_ => unreachable!(),
53		},
54		gl::RG => match F::TYPE {
55			gl::BYTE => gl::RG8I,
56			gl::UNSIGNED_BYTE => gl::RG8UI,
57			gl::SHORT => gl::RG16I,
58			gl::UNSIGNED_SHORT => gl::RG16UI,
59			gl::INT => gl::RG32I,
60			gl::UNSIGNED_INT => gl::RG32UI,
61			gl::HALF_FLOAT => gl::RG16F,
62			gl::FLOAT => gl::RG32F,
63			_ => unreachable!(),
64		},
65		gl::RGB => match F::TYPE {
66			gl::BYTE => gl::RGB8I,
67			gl::UNSIGNED_BYTE => gl::RGB8UI,
68			gl::SHORT => gl::RGB16I,
69			gl::UNSIGNED_SHORT => gl::RGB16UI,
70			gl::INT => gl::RGB32I,
71			gl::UNSIGNED_INT => gl::RGB32UI,
72			gl::HALF_FLOAT => gl::RGB16F,
73			gl::FLOAT => gl::RGB32F,
74			_ => unreachable!(),
75		},
76		gl::RGBA => match F::TYPE {
77			gl::BYTE => gl::RGBA8I,
78			gl::UNSIGNED_BYTE => gl::RGBA8UI,
79			gl::SHORT => gl::RGBA16I,
80			gl::UNSIGNED_SHORT => gl::RGBA16UI,
81			gl::INT => gl::RGBA32I,
82			gl::UNSIGNED_INT => gl::RGBA32UI,
83			gl::HALF_FLOAT => gl::RGBA16F,
84			gl::FLOAT => gl::RGBA32F,
85			_ => unreachable!(),
86		},
87		_ => unreachable!(),
88	}
89}
90
91pub fn normalize_internal_fmt(fmt: GLenum) -> GLenum {
92	match fmt {
93		gl::R8I | gl::R8UI => gl::R8,
94		gl::R16I | gl::R16UI => gl::R16,
95
96		gl::RG8I | gl::RG8UI => gl::RG8,
97		gl::RG16I | gl::RG16UI => gl::RG16,
98
99		gl::RGB8I | gl::RGB8UI => gl::RGB8,
100		gl::RGB16I | gl::RGB16UI => gl::RGB16,
101
102		gl::RGBA8I | gl::RGBA8UI => gl::RGBA8,
103		gl::RGBA16I | gl::RGBA16UI => gl::RGBA16,
104
105		f => f,
106	}
107}