three_d/core/
data_type.rs

1use crate::context::UniformLocation;
2use crate::core::*;
3
4pub enum UniformType {
5    Value,
6    Vec2,
7    Vec3,
8    Vec4,
9    Mat2,
10    Mat3,
11    Mat4,
12}
13
14pub trait PrimitiveDataType: DataType + Copy + Default {
15    fn send_uniform_with_type(
16        context: &Context,
17        location: &UniformLocation,
18        data: &[Self],
19        type_: UniformType,
20    );
21    fn internal_format_with_size(size: u32) -> u32;
22}
23
24impl PrimitiveDataType for u8 {
25    fn internal_format_with_size(size: u32) -> u32 {
26        match size {
27            1 => crate::context::R8,
28            2 => crate::context::RG8,
29            3 => crate::context::RGB8,
30            4 => crate::context::RGBA8,
31            _ => unreachable!(),
32        }
33    }
34
35    fn send_uniform_with_type(
36        context: &Context,
37        location: &UniformLocation,
38        data: &[Self],
39        type_: UniformType,
40    ) {
41        let data = data.iter().map(|v| *v as u32).collect::<Vec<_>>();
42        u32::send_uniform_with_type(context, location, &data, type_)
43    }
44}
45impl PrimitiveDataType for u16 {
46    fn internal_format_with_size(size: u32) -> u32 {
47        match size {
48            1 => crate::context::R16UI,
49            2 => crate::context::RG16UI,
50            3 => crate::context::RGB16UI,
51            4 => crate::context::RGBA16UI,
52            _ => unreachable!(),
53        }
54    }
55
56    fn send_uniform_with_type(
57        context: &Context,
58        location: &UniformLocation,
59        data: &[Self],
60        type_: UniformType,
61    ) {
62        let data = data.iter().map(|v| *v as u32).collect::<Vec<_>>();
63        u32::send_uniform_with_type(context, location, &data, type_)
64    }
65}
66impl PrimitiveDataType for u32 {
67    fn internal_format_with_size(size: u32) -> u32 {
68        match size {
69            1 => crate::context::R32UI,
70            2 => crate::context::RG32UI,
71            3 => crate::context::RGB32UI,
72            4 => crate::context::RGBA32UI,
73            _ => unreachable!(),
74        }
75    }
76
77    fn send_uniform_with_type(
78        context: &Context,
79        location: &UniformLocation,
80        data: &[Self],
81        type_: UniformType,
82    ) {
83        unsafe {
84            match type_ {
85                UniformType::Value => context.uniform_1_u32_slice(Some(location), data),
86                UniformType::Vec2 => context.uniform_2_u32_slice(Some(location), data),
87                UniformType::Vec3 => context.uniform_3_u32_slice(Some(location), data),
88                UniformType::Vec4 => context.uniform_4_u32_slice(Some(location), data),
89                _ => unimplemented!(),
90            }
91        }
92    }
93}
94impl PrimitiveDataType for i8 {
95    fn internal_format_with_size(size: u32) -> u32 {
96        match size {
97            1 => crate::context::R8I,
98            2 => crate::context::RG8I,
99            3 => crate::context::RGB8I,
100            4 => crate::context::RGBA8I,
101            _ => unreachable!(),
102        }
103    }
104
105    fn send_uniform_with_type(
106        context: &Context,
107        location: &UniformLocation,
108        data: &[Self],
109        type_: UniformType,
110    ) {
111        let data = data.iter().map(|v| *v as i32).collect::<Vec<_>>();
112        i32::send_uniform_with_type(context, location, &data, type_)
113    }
114}
115impl PrimitiveDataType for i16 {
116    fn internal_format_with_size(size: u32) -> u32 {
117        match size {
118            1 => crate::context::R16I,
119            2 => crate::context::RG16I,
120            3 => crate::context::RGB16I,
121            4 => crate::context::RGBA16I,
122            _ => unreachable!(),
123        }
124    }
125
126    fn send_uniform_with_type(
127        context: &Context,
128        location: &UniformLocation,
129        data: &[Self],
130        type_: UniformType,
131    ) {
132        let data = data.iter().map(|v| *v as i32).collect::<Vec<_>>();
133        i32::send_uniform_with_type(context, location, &data, type_)
134    }
135}
136impl PrimitiveDataType for i32 {
137    fn internal_format_with_size(size: u32) -> u32 {
138        match size {
139            1 => crate::context::R32I,
140            2 => crate::context::RG32I,
141            3 => crate::context::RGB32I,
142            4 => crate::context::RGBA32I,
143            _ => unreachable!(),
144        }
145    }
146
147    fn send_uniform_with_type(
148        context: &Context,
149        location: &UniformLocation,
150        data: &[Self],
151        type_: UniformType,
152    ) {
153        unsafe {
154            match type_ {
155                UniformType::Value => context.uniform_1_i32_slice(Some(location), data),
156                UniformType::Vec2 => context.uniform_2_i32_slice(Some(location), data),
157                UniformType::Vec3 => context.uniform_3_i32_slice(Some(location), data),
158                UniformType::Vec4 => context.uniform_4_i32_slice(Some(location), data),
159                _ => unimplemented!(),
160            }
161        }
162    }
163}
164impl PrimitiveDataType for f16 {
165    fn internal_format_with_size(size: u32) -> u32 {
166        match size {
167            1 => crate::context::R16F,
168            2 => crate::context::RG16F,
169            3 => crate::context::RGB16F,
170            4 => crate::context::RGBA16F,
171            _ => unreachable!(),
172        }
173    }
174
175    fn send_uniform_with_type(
176        context: &Context,
177        location: &UniformLocation,
178        data: &[Self],
179        type_: UniformType,
180    ) {
181        let data = data.iter().map(|v| v.to_f32()).collect::<Vec<_>>();
182        f32::send_uniform_with_type(context, location, &data, type_)
183    }
184}
185impl PrimitiveDataType for f32 {
186    fn internal_format_with_size(size: u32) -> u32 {
187        match size {
188            1 => crate::context::R32F,
189            2 => crate::context::RG32F,
190            3 => crate::context::RGB32F,
191            4 => crate::context::RGBA32F,
192            _ => unreachable!(),
193        }
194    }
195
196    fn send_uniform_with_type(
197        context: &Context,
198        location: &UniformLocation,
199        data: &[Self],
200        type_: UniformType,
201    ) {
202        unsafe {
203            match type_ {
204                UniformType::Value => context.uniform_1_f32_slice(Some(location), data),
205                UniformType::Vec2 => context.uniform_2_f32_slice(Some(location), data),
206                UniformType::Vec3 => context.uniform_3_f32_slice(Some(location), data),
207                UniformType::Vec4 => context.uniform_4_f32_slice(Some(location), data),
208                UniformType::Mat2 => {
209                    context.uniform_matrix_2_f32_slice(Some(location), false, data)
210                }
211                UniformType::Mat3 => {
212                    context.uniform_matrix_3_f32_slice(Some(location), false, data)
213                }
214                UniformType::Mat4 => {
215                    context.uniform_matrix_4_f32_slice(Some(location), false, data)
216                }
217            }
218        }
219    }
220}
221
222pub trait DataType: std::fmt::Debug + Clone {
223    fn internal_format() -> u32;
224    fn data_type() -> u32;
225    fn size() -> u32;
226    fn normalized() -> bool {
227        false
228    }
229    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]);
230}
231
232impl<T: DataType + ?Sized> DataType for &T {
233    fn internal_format() -> u32 {
234        T::internal_format()
235    }
236    fn data_type() -> u32 {
237        T::data_type()
238    }
239    fn size() -> u32 {
240        T::size()
241    }
242    fn normalized() -> bool {
243        T::normalized()
244    }
245
246    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
247        T::send_uniform(
248            context,
249            location,
250            &data.iter().map(|v| (*v).clone()).collect::<Vec<_>>(),
251        )
252    }
253}
254
255impl DataType for u8 {
256    fn internal_format() -> u32 {
257        Self::internal_format_with_size(1)
258    }
259
260    fn data_type() -> u32 {
261        crate::context::UNSIGNED_BYTE
262    }
263
264    fn size() -> u32 {
265        1
266    }
267
268    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
269        Self::send_uniform_with_type(context, location, data, UniformType::Value)
270    }
271}
272
273impl DataType for u16 {
274    fn internal_format() -> u32 {
275        Self::internal_format_with_size(1)
276    }
277    fn data_type() -> u32 {
278        crate::context::UNSIGNED_SHORT
279    }
280
281    fn size() -> u32 {
282        1
283    }
284
285    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
286        Self::send_uniform_with_type(context, location, data, UniformType::Value)
287    }
288}
289
290impl DataType for u32 {
291    fn internal_format() -> u32 {
292        Self::internal_format_with_size(1)
293    }
294
295    fn data_type() -> u32 {
296        crate::context::UNSIGNED_INT
297    }
298
299    fn size() -> u32 {
300        1
301    }
302
303    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
304        Self::send_uniform_with_type(context, location, data, UniformType::Value)
305    }
306}
307
308impl DataType for i8 {
309    fn internal_format() -> u32 {
310        Self::internal_format_with_size(1)
311    }
312
313    fn data_type() -> u32 {
314        crate::context::BYTE
315    }
316
317    fn size() -> u32 {
318        1
319    }
320
321    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
322        Self::send_uniform_with_type(context, location, data, UniformType::Value)
323    }
324}
325
326impl DataType for i16 {
327    fn internal_format() -> u32 {
328        Self::internal_format_with_size(1)
329    }
330
331    fn data_type() -> u32 {
332        crate::context::SHORT
333    }
334
335    fn size() -> u32 {
336        1
337    }
338
339    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
340        Self::send_uniform_with_type(context, location, data, UniformType::Value)
341    }
342}
343
344impl DataType for i32 {
345    fn internal_format() -> u32 {
346        Self::internal_format_with_size(1)
347    }
348
349    fn data_type() -> u32 {
350        crate::context::INT
351    }
352
353    fn size() -> u32 {
354        1
355    }
356
357    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
358        Self::send_uniform_with_type(context, location, data, UniformType::Value)
359    }
360}
361
362impl DataType for f16 {
363    fn internal_format() -> u32 {
364        Self::internal_format_with_size(1)
365    }
366    fn data_type() -> u32 {
367        crate::context::HALF_FLOAT
368    }
369
370    fn size() -> u32 {
371        1
372    }
373
374    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
375        Self::send_uniform_with_type(context, location, data, UniformType::Value)
376    }
377}
378
379impl DataType for f32 {
380    fn internal_format() -> u32 {
381        Self::internal_format_with_size(1)
382    }
383
384    fn data_type() -> u32 {
385        crate::context::FLOAT
386    }
387
388    fn size() -> u32 {
389        1
390    }
391
392    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
393        Self::send_uniform_with_type(context, location, data, UniformType::Value)
394    }
395}
396
397impl<T: PrimitiveDataType> DataType for Vector2<T> {
398    fn internal_format() -> u32 {
399        T::internal_format_with_size(Self::size())
400    }
401
402    fn data_type() -> u32 {
403        T::data_type()
404    }
405
406    fn size() -> u32 {
407        2
408    }
409
410    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
411        let data = data.iter().flat_map(|v| [v.x, v.y]).collect::<Vec<_>>();
412        T::send_uniform_with_type(context, location, &data, UniformType::Vec2)
413    }
414}
415
416impl<T: PrimitiveDataType> DataType for [T; 2] {
417    fn internal_format() -> u32 {
418        T::internal_format_with_size(Self::size())
419    }
420
421    fn data_type() -> u32 {
422        T::data_type()
423    }
424
425    fn size() -> u32 {
426        2
427    }
428
429    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
430        let data = data.iter().flatten().copied().collect::<Vec<_>>();
431        T::send_uniform_with_type(context, location, &data, UniformType::Vec2)
432    }
433}
434
435impl<T: PrimitiveDataType> DataType for Vector3<T> {
436    fn internal_format() -> u32 {
437        T::internal_format_with_size(Self::size())
438    }
439    fn data_type() -> u32 {
440        T::data_type()
441    }
442
443    fn size() -> u32 {
444        3
445    }
446
447    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
448        let data = data
449            .iter()
450            .flat_map(|v| [v.x, v.y, v.z])
451            .collect::<Vec<_>>();
452        T::send_uniform_with_type(context, location, &data, UniformType::Vec3)
453    }
454}
455
456impl<T: PrimitiveDataType> DataType for [T; 3] {
457    fn internal_format() -> u32 {
458        T::internal_format_with_size(Self::size())
459    }
460    fn data_type() -> u32 {
461        T::data_type()
462    }
463
464    fn size() -> u32 {
465        3
466    }
467
468    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
469        let data = data.iter().flatten().copied().collect::<Vec<_>>();
470        T::send_uniform_with_type(context, location, &data, UniformType::Vec3)
471    }
472}
473
474impl<T: PrimitiveDataType> DataType for Vector4<T> {
475    fn internal_format() -> u32 {
476        T::internal_format_with_size(Self::size())
477    }
478
479    fn data_type() -> u32 {
480        T::data_type()
481    }
482
483    fn size() -> u32 {
484        4
485    }
486
487    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
488        let data = data
489            .iter()
490            .flat_map(|v| [v.x, v.y, v.z, v.w])
491            .collect::<Vec<_>>();
492        T::send_uniform_with_type(context, location, &data, UniformType::Vec4)
493    }
494}
495
496impl<T: PrimitiveDataType> DataType for [T; 4] {
497    fn internal_format() -> u32 {
498        T::internal_format_with_size(Self::size())
499    }
500
501    fn data_type() -> u32 {
502        T::data_type()
503    }
504
505    fn size() -> u32 {
506        4
507    }
508
509    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
510        let data = data.iter().flatten().copied().collect::<Vec<_>>();
511        T::send_uniform_with_type(context, location, &data, UniformType::Vec4)
512    }
513}
514
515impl<T: PrimitiveDataType> DataType for Quaternion<T> {
516    fn internal_format() -> u32 {
517        T::internal_format_with_size(Self::size())
518    }
519
520    fn data_type() -> u32 {
521        T::data_type()
522    }
523
524    fn size() -> u32 {
525        4
526    }
527
528    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
529        let data = data
530            .iter()
531            .flat_map(|v| [v.v.x, v.v.y, v.v.z, v.s])
532            .collect::<Vec<_>>();
533        T::send_uniform_with_type(context, location, &data, UniformType::Vec4)
534    }
535}
536
537impl<T: PrimitiveDataType> DataType for Matrix2<T> {
538    fn internal_format() -> u32 {
539        T::internal_format_with_size(Self::size())
540    }
541
542    fn data_type() -> u32 {
543        T::data_type()
544    }
545
546    fn size() -> u32 {
547        4
548    }
549
550    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
551        let data = data
552            .iter()
553            .flat_map(|v| [v.x.x, v.x.y, v.y.x, v.y.y])
554            .collect::<Vec<_>>();
555        T::send_uniform_with_type(context, location, &data, UniformType::Mat2)
556    }
557}
558
559impl<T: PrimitiveDataType> DataType for Matrix3<T> {
560    fn internal_format() -> u32 {
561        T::internal_format_with_size(Self::size())
562    }
563
564    fn data_type() -> u32 {
565        T::data_type()
566    }
567
568    fn size() -> u32 {
569        9
570    }
571
572    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
573        let data = data
574            .iter()
575            .flat_map(|v| {
576                [
577                    v.x.x, v.x.y, v.x.z, v.y.x, v.y.y, v.y.z, v.z.x, v.z.y, v.z.z,
578                ]
579            })
580            .collect::<Vec<_>>();
581        T::send_uniform_with_type(context, location, &data, UniformType::Mat3)
582    }
583}
584
585impl<T: PrimitiveDataType> DataType for Matrix4<T> {
586    fn internal_format() -> u32 {
587        T::internal_format_with_size(Self::size())
588    }
589
590    fn data_type() -> u32 {
591        T::data_type()
592    }
593
594    fn size() -> u32 {
595        16
596    }
597
598    fn send_uniform(context: &Context, location: &UniformLocation, data: &[Self]) {
599        let data = data
600            .iter()
601            .flat_map(|v| {
602                [
603                    v.x.x, v.x.y, v.x.z, v.x.w, v.y.x, v.y.y, v.y.z, v.y.w, v.z.x, v.z.y, v.z.z,
604                    v.z.w, v.w.x, v.w.y, v.w.z, v.w.w,
605                ]
606            })
607            .collect::<Vec<_>>();
608        T::send_uniform_with_type(context, location, &data, UniformType::Mat4)
609    }
610}
611
612pub trait DepthDataType {
613    fn internal_format() -> u32;
614}
615
616impl DepthDataType for f16 {
617    fn internal_format() -> u32 {
618        crate::context::DEPTH_COMPONENT16
619    }
620}
621impl DepthDataType for f24 {
622    fn internal_format() -> u32 {
623        crate::context::DEPTH_COMPONENT24
624    }
625}
626impl DepthDataType for f32 {
627    fn internal_format() -> u32 {
628        crate::context::DEPTH_COMPONENT32F
629    }
630}