1use serde::{Deserialize, Serialize};
7
8#[allow(non_camel_case_types)]
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Default)]
14#[repr(i32)]
15pub enum TextureFormat {
16 Alpha8 = 1,
18 ARGB4444 = 2,
19 RGB24 = 3,
20 RGBA32 = 4,
21 ARGB32 = 5,
22 RGB565 = 7,
23 R16 = 9,
24
25 DXT1 = 10,
27 DXT5 = 12,
28 RGBA4444 = 13,
29 BGRA32 = 14,
30
31 RHalf = 15,
33 RGHalf = 16,
34 RGBAHalf = 17,
35 RFloat = 18,
36 RGFloat = 19,
37 RGBAFloat = 20,
38
39 YUY2 = 21,
41 RGB9e5Float = 22,
42
43 BC6H = 24,
45 BC7 = 25,
46 BC4 = 26,
47 BC5 = 27,
48
49 DXT1Crunched = 28,
51 DXT5Crunched = 29,
52
53 PVRTC_RGB2 = 30,
55 PVRTC_RGBA2 = 31,
56 PVRTC_RGB4 = 32,
57 PVRTC_RGBA4 = 33,
58 ETC_RGB4 = 34,
59
60 EAC_R = 41,
62 EAC_R_SIGNED = 42,
63 EAC_RG = 43,
64 EAC_RG_SIGNED = 44,
65 ETC2_RGB = 45,
66 ETC2_RGBA1 = 46,
67 ETC2_RGBA8 = 47,
68
69 ASTC_RGB_4x4 = 48,
71 ASTC_RGB_5x5 = 49,
72 ASTC_RGB_6x6 = 50,
73 ASTC_RGB_8x8 = 51,
74 ASTC_RGB_10x10 = 52,
75 ASTC_RGB_12x12 = 53,
76 ASTC_RGBA_4x4 = 54,
77 ASTC_RGBA_5x5 = 55,
78 ASTC_RGBA_6x6 = 56,
79 ASTC_RGBA_8x8 = 57,
80 ASTC_RGBA_10x10 = 58,
81 ASTC_RGBA_12x12 = 59,
82
83 ETC_RGB4Crunched = 64,
85 ETC2_RGBA8Crunched = 65,
86
87 #[default]
89 Unknown = -1,
90}
91
92impl From<i32> for TextureFormat {
93 fn from(value: i32) -> Self {
94 match value {
95 1 => TextureFormat::Alpha8,
96 2 => TextureFormat::ARGB4444,
97 3 => TextureFormat::RGB24,
98 4 => TextureFormat::RGBA32,
99 5 => TextureFormat::ARGB32,
100 7 => TextureFormat::RGB565,
101 9 => TextureFormat::R16,
102 10 => TextureFormat::DXT1,
103 12 => TextureFormat::DXT5,
104 13 => TextureFormat::RGBA4444,
105 14 => TextureFormat::BGRA32,
106 15 => TextureFormat::RHalf,
107 16 => TextureFormat::RGHalf,
108 17 => TextureFormat::RGBAHalf,
109 18 => TextureFormat::RFloat,
110 19 => TextureFormat::RGFloat,
111 20 => TextureFormat::RGBAFloat,
112 21 => TextureFormat::YUY2,
113 22 => TextureFormat::RGB9e5Float,
114 24 => TextureFormat::BC6H,
115 25 => TextureFormat::BC7,
116 26 => TextureFormat::BC4,
117 27 => TextureFormat::BC5,
118 28 => TextureFormat::DXT1Crunched,
119 29 => TextureFormat::DXT5Crunched,
120 30 => TextureFormat::PVRTC_RGB2,
121 31 => TextureFormat::PVRTC_RGBA2,
122 32 => TextureFormat::PVRTC_RGB4,
123 33 => TextureFormat::PVRTC_RGBA4,
124 34 => TextureFormat::ETC_RGB4,
125 41 => TextureFormat::EAC_R,
126 42 => TextureFormat::EAC_R_SIGNED,
127 43 => TextureFormat::EAC_RG,
128 44 => TextureFormat::EAC_RG_SIGNED,
129 45 => TextureFormat::ETC2_RGB,
130 46 => TextureFormat::ETC2_RGBA1,
131 47 => TextureFormat::ETC2_RGBA8,
132 48 => TextureFormat::ASTC_RGB_4x4,
133 49 => TextureFormat::ASTC_RGB_5x5,
134 50 => TextureFormat::ASTC_RGB_6x6,
135 51 => TextureFormat::ASTC_RGB_8x8,
136 52 => TextureFormat::ASTC_RGB_10x10,
137 53 => TextureFormat::ASTC_RGB_12x12,
138 54 => TextureFormat::ASTC_RGBA_4x4,
139 55 => TextureFormat::ASTC_RGBA_5x5,
140 56 => TextureFormat::ASTC_RGBA_6x6,
141 57 => TextureFormat::ASTC_RGBA_8x8,
142 58 => TextureFormat::ASTC_RGBA_10x10,
143 59 => TextureFormat::ASTC_RGBA_12x12,
144 64 => TextureFormat::ETC_RGB4Crunched,
145 65 => TextureFormat::ETC2_RGBA8Crunched,
146 _ => TextureFormat::Unknown,
147 }
148 }
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize)]
153pub struct TextureFormatInfo {
154 pub name: String,
155 pub bits_per_pixel: u32,
156 pub block_size: (u32, u32), pub compressed: bool,
158 pub has_alpha: bool,
159 pub supported: bool,
160}
161
162impl Default for TextureFormatInfo {
163 fn default() -> Self {
164 Self {
165 name: "Unknown".to_string(),
166 bits_per_pixel: 0,
167 block_size: (1, 1),
168 compressed: false,
169 has_alpha: false,
170 supported: false,
171 }
172 }
173}
174
175impl TextureFormat {
176 pub fn info(&self) -> TextureFormatInfo {
178 match self {
179 TextureFormat::Alpha8 => TextureFormatInfo {
180 name: "Alpha8".to_string(),
181 bits_per_pixel: 8,
182 block_size: (1, 1),
183 compressed: false,
184 has_alpha: true,
185 supported: true,
186 },
187 TextureFormat::RGB24 => TextureFormatInfo {
188 name: "RGB24".to_string(),
189 bits_per_pixel: 24,
190 block_size: (1, 1),
191 compressed: false,
192 has_alpha: false,
193 supported: true,
194 },
195 TextureFormat::RGBA32 => TextureFormatInfo {
196 name: "RGBA32".to_string(),
197 bits_per_pixel: 32,
198 block_size: (1, 1),
199 compressed: false,
200 has_alpha: true,
201 supported: true,
202 },
203 TextureFormat::ARGB32 => TextureFormatInfo {
204 name: "ARGB32".to_string(),
205 bits_per_pixel: 32,
206 block_size: (1, 1),
207 compressed: false,
208 has_alpha: true,
209 supported: true,
210 },
211 TextureFormat::BGRA32 => TextureFormatInfo {
212 name: "BGRA32".to_string(),
213 bits_per_pixel: 32,
214 block_size: (1, 1),
215 compressed: false,
216 has_alpha: true,
217 supported: true,
218 },
219 TextureFormat::RGBA4444 => TextureFormatInfo {
220 name: "RGBA4444".to_string(),
221 bits_per_pixel: 16,
222 block_size: (1, 1),
223 compressed: false,
224 has_alpha: true,
225 supported: true,
226 },
227 TextureFormat::ARGB4444 => TextureFormatInfo {
228 name: "ARGB4444".to_string(),
229 bits_per_pixel: 16,
230 block_size: (1, 1),
231 compressed: false,
232 has_alpha: true,
233 supported: true,
234 },
235 TextureFormat::RGB565 => TextureFormatInfo {
236 name: "RGB565".to_string(),
237 bits_per_pixel: 16,
238 block_size: (1, 1),
239 compressed: false,
240 has_alpha: false,
241 supported: true,
242 },
243 TextureFormat::DXT1 => TextureFormatInfo {
244 name: "DXT1".to_string(),
245 bits_per_pixel: 4,
246 block_size: (4, 4),
247 compressed: true,
248 has_alpha: false,
249 supported: true,
250 },
251 TextureFormat::DXT5 => TextureFormatInfo {
252 name: "DXT5".to_string(),
253 bits_per_pixel: 8,
254 block_size: (4, 4),
255 compressed: true,
256 has_alpha: true,
257 supported: true,
258 },
259 TextureFormat::ETC2_RGB => TextureFormatInfo {
260 name: "ETC2_RGB".to_string(),
261 bits_per_pixel: 4,
262 block_size: (4, 4),
263 compressed: true,
264 has_alpha: false,
265 supported: true,
266 },
267 TextureFormat::ETC2_RGBA8 => TextureFormatInfo {
268 name: "ETC2_RGBA8".to_string(),
269 bits_per_pixel: 8,
270 block_size: (4, 4),
271 compressed: true,
272 has_alpha: true,
273 supported: true,
274 },
275 TextureFormat::ASTC_RGBA_4x4 => TextureFormatInfo {
276 name: "ASTC_RGBA_4x4".to_string(),
277 bits_per_pixel: 8,
278 block_size: (4, 4),
279 compressed: true,
280 has_alpha: true,
281 supported: true,
282 },
283 _ => TextureFormatInfo::default(),
284 }
285 }
286
287 pub fn is_supported(&self) -> bool {
289 self.info().supported
290 }
291
292 pub fn calculate_data_size(&self, width: u32, height: u32) -> u32 {
294 let info = self.info();
295 if info.compressed {
296 let blocks_x = width.div_ceil(info.block_size.0);
297 let blocks_y = height.div_ceil(info.block_size.1);
298 let bytes_per_block = match self {
300 TextureFormat::DXT1 => 8,
301 TextureFormat::DXT5 => 16,
302 TextureFormat::BC7 => 16,
303 TextureFormat::ETC2_RGB => 8,
304 TextureFormat::ETC2_RGBA8 => 16,
305 TextureFormat::ASTC_RGBA_4x4 => 16,
306 _ => info.bits_per_pixel / 8,
307 };
308 blocks_x * blocks_y * bytes_per_block
309 } else {
310 width * height * (info.bits_per_pixel / 8)
311 }
312 }
313
314 pub fn is_crunch_compressed(&self) -> bool {
316 matches!(
317 self,
318 TextureFormat::DXT1Crunched
319 | TextureFormat::DXT5Crunched
320 | TextureFormat::ETC_RGB4Crunched
321 | TextureFormat::ETC2_RGBA8Crunched
322 )
323 }
324
325 pub fn is_basic_format(&self) -> bool {
327 matches!(
328 self,
329 TextureFormat::Alpha8
330 | TextureFormat::RGB24
331 | TextureFormat::RGBA32
332 | TextureFormat::ARGB32
333 | TextureFormat::BGRA32
334 | TextureFormat::RGBA4444
335 | TextureFormat::ARGB4444
336 | TextureFormat::RGB565
337 | TextureFormat::R16
338 )
339 }
340
341 pub fn is_compressed_format(&self) -> bool {
343 matches!(
344 self,
345 TextureFormat::DXT1
346 | TextureFormat::DXT5
347 | TextureFormat::BC4
348 | TextureFormat::BC5
349 | TextureFormat::BC6H
350 | TextureFormat::BC7
351 )
352 }
353
354 pub fn is_mobile_format(&self) -> bool {
356 matches!(
357 self,
358 TextureFormat::PVRTC_RGB2
359 | TextureFormat::PVRTC_RGBA2
360 | TextureFormat::PVRTC_RGB4
361 | TextureFormat::PVRTC_RGBA4
362 | TextureFormat::ETC_RGB4
363 | TextureFormat::ETC2_RGB
364 | TextureFormat::ETC2_RGBA1
365 | TextureFormat::ETC2_RGBA8
366 | TextureFormat::EAC_R
367 | TextureFormat::EAC_R_SIGNED
368 | TextureFormat::EAC_RG
369 | TextureFormat::EAC_RG_SIGNED
370 | TextureFormat::ASTC_RGB_4x4
371 | TextureFormat::ASTC_RGB_5x5
372 | TextureFormat::ASTC_RGB_6x6
373 | TextureFormat::ASTC_RGB_8x8
374 | TextureFormat::ASTC_RGB_10x10
375 | TextureFormat::ASTC_RGB_12x12
376 | TextureFormat::ASTC_RGBA_4x4
377 | TextureFormat::ASTC_RGBA_5x5
378 | TextureFormat::ASTC_RGBA_6x6
379 | TextureFormat::ASTC_RGBA_8x8
380 | TextureFormat::ASTC_RGBA_10x10
381 | TextureFormat::ASTC_RGBA_12x12
382 )
383 }
384}