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}