1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
use crate::uses::*;
pub trait TexSize: TrivialBound {
const TYPE: GLenum;
const SIZE: i32;
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct RED;
impl TexSize for RED {
const TYPE: GLenum = gl::RED;
const SIZE: i32 = 1;
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct RG;
impl TexSize for RG {
const TYPE: GLenum = gl::RG;
const SIZE: i32 = 2;
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct RGB;
impl TexSize for RGB {
const TYPE: GLenum = gl::RGB;
const SIZE: i32 = 3;
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct RGBA;
impl TexSize for RGBA {
const TYPE: GLenum = gl::RGBA;
const SIZE: i32 = 4;
}
pub trait TexFmt: TrivialBound {
const TYPE: GLenum;
const ZERO: Self;
}
impl TexFmt for i8 {
const TYPE: GLenum = gl::BYTE;
const ZERO: Self = 0;
}
impl TexFmt for u8 {
const TYPE: GLenum = gl::UNSIGNED_BYTE;
const ZERO: Self = 0;
}
impl TexFmt for i16 {
const TYPE: GLenum = gl::SHORT;
const ZERO: Self = 0;
}
impl TexFmt for u16 {
const TYPE: GLenum = gl::UNSIGNED_SHORT;
const ZERO: Self = 0;
}
impl TexFmt for i32 {
const TYPE: GLenum = gl::INT;
const ZERO: Self = 0;
}
impl TexFmt for u32 {
const TYPE: GLenum = gl::UNSIGNED_INT;
const ZERO: Self = 0;
}
impl TexFmt for f16 {
const TYPE: GLenum = gl::HALF_FLOAT;
const ZERO: Self = f16::from_bits(0);
}
impl TexFmt for f32 {
const TYPE: GLenum = gl::FLOAT;
const ZERO: Self = 0.;
}
pub fn get_internal_fmt<S: TexSize, F: TexFmt>() -> GLenum {
match S::TYPE {
gl::RED => match F::TYPE {
gl::BYTE => gl::R8I,
gl::UNSIGNED_BYTE => gl::R8UI,
gl::SHORT => gl::R16I,
gl::UNSIGNED_SHORT => gl::R16UI,
gl::INT => gl::R32I,
gl::UNSIGNED_INT => gl::R32UI,
gl::HALF_FLOAT => gl::R16F,
gl::FLOAT => gl::R32F,
_ => unreachable!(),
},
gl::RG => match F::TYPE {
gl::BYTE => gl::RG8I,
gl::UNSIGNED_BYTE => gl::RG8UI,
gl::SHORT => gl::RG16I,
gl::UNSIGNED_SHORT => gl::RG16UI,
gl::INT => gl::RG32I,
gl::UNSIGNED_INT => gl::RG32UI,
gl::HALF_FLOAT => gl::RG16F,
gl::FLOAT => gl::RG32F,
_ => unreachable!(),
},
gl::RGB => match F::TYPE {
gl::BYTE => gl::RGB8I,
gl::UNSIGNED_BYTE => gl::RGB8UI,
gl::SHORT => gl::RGB16I,
gl::UNSIGNED_SHORT => gl::RGB16UI,
gl::INT => gl::RGB32I,
gl::UNSIGNED_INT => gl::RGB32UI,
gl::HALF_FLOAT => gl::RGB16F,
gl::FLOAT => gl::RGB32F,
_ => unreachable!(),
},
gl::RGBA => match F::TYPE {
gl::BYTE => gl::RGBA8I,
gl::UNSIGNED_BYTE => gl::RGBA8UI,
gl::SHORT => gl::RGBA16I,
gl::UNSIGNED_SHORT => gl::RGBA16UI,
gl::INT => gl::RGBA32I,
gl::UNSIGNED_INT => gl::RGBA32UI,
gl::HALF_FLOAT => gl::RGBA16F,
gl::FLOAT => gl::RGBA32F,
_ => unreachable!(),
},
_ => unreachable!(),
}
}
pub fn normalize_internal_fmt(fmt: GLenum) -> GLenum {
match fmt {
gl::R8I | gl::R8UI => gl::R8,
gl::R16I | gl::R16UI => gl::R16,
gl::RG8I | gl::RG8UI => gl::RG8,
gl::RG16I | gl::RG16UI => gl::RG16,
gl::RGB8I | gl::RGB8UI => gl::RGB8,
gl::RGB16I | gl::RGB16UI => gl::RGB16,
gl::RGBA8I | gl::RGBA8UI => gl::RGBA8,
gl::RGBA16I | gl::RGBA16UI => gl::RGBA16,
f => f,
}
}