1use std::fmt;
2
3use gltf_v1_derive::Validate;
4use indexmap::IndexMap;
5use serde::{Deserialize, Serialize, de, ser::SerializeSeq};
6
7use crate::{
8 Path, Program, Root, extensions,
9 validation::{Error, USize64},
10};
11
12use super::{common::StringIndex, node::Node, validation::Checked};
13
14pub const BYTE: u32 = 5120;
15pub const UNSIGNED_BYTE: u32 = 5121;
16pub const SHORT: u32 = 5122;
17pub const UNSIGNED_SHORT: u32 = 5123;
18pub const INT: u32 = 5124;
19pub const UNSIGNED_INT: u32 = 5125;
20pub const FLOAT: u32 = 5126;
21pub const FLOAT_VEC2: u32 = 35664;
22pub const FLOAT_VEC3: u32 = 35665;
23pub const FLOAT_VEC4: u32 = 35666;
24pub const INT_VEC2: u32 = 35667;
25pub const INT_VEC3: u32 = 35668;
26pub const INT_VEC4: u32 = 35669;
27pub const BOOL: u32 = 35670;
28pub const BOOL_VEC2: u32 = 35671;
29pub const BOOL_VEC3: u32 = 35672;
30pub const BOOL_VEC4: u32 = 35673;
31pub const FLOAT_MAT2: u32 = 35674;
32pub const FLOAT_MAT3: u32 = 35675;
33pub const FLOAT_MAT4: u32 = 35676;
34pub const SAMPLER_2D: u32 = 35678;
35
36#[derive(Clone, Debug, Copy, Default)]
37pub enum ParameterType {
38 Byte,
39 UnsignedByte,
40 Short,
41 UnsignedShort,
42 Int,
43 UnsignedInt,
44 #[default]
45 Float,
46 FloatVec2,
47 FloatVec3,
48 FloatVec4,
49 IntVec2,
50 IntVec3,
51 IntVec4,
52 Bool,
53 BoolVec2,
54 BoolVec3,
55 BoolVec4,
56 FloatMat2,
57 FloatMat3,
58 FloatMat4,
59 Sampler2d,
60}
61
62impl ParameterType {
63 pub const VALID_PARAMETER_TYPES: &[u32] = &[
64 BYTE,
65 UNSIGNED_BYTE,
66 SHORT,
67 UNSIGNED_SHORT,
68 INT,
69 UNSIGNED_INT,
70 FLOAT,
71 FLOAT_VEC2,
72 FLOAT_VEC3,
73 FLOAT_VEC4,
74 INT_VEC2,
75 INT_VEC3,
76 INT_VEC4,
77 BOOL,
78 BOOL_VEC2,
79 BOOL_VEC3,
80 BOOL_VEC4,
81 FLOAT_MAT2,
82 FLOAT_MAT3,
83 FLOAT_MAT4,
84 SAMPLER_2D,
85 ];
86}
87
88impl TryFrom<u32> for ParameterType {
89 type Error = ();
90
91 fn try_from(value: u32) -> Result<Self, Self::Error> {
92 match value {
93 BYTE => Ok(ParameterType::Byte),
94 UNSIGNED_BYTE => Ok(ParameterType::UnsignedByte),
95 SHORT => Ok(ParameterType::Short),
96 UNSIGNED_SHORT => Ok(ParameterType::UnsignedShort),
97 INT => Ok(ParameterType::Int),
98 UNSIGNED_INT => Ok(ParameterType::UnsignedInt),
99 FLOAT => Ok(ParameterType::Float),
100 FLOAT_VEC2 => Ok(ParameterType::FloatVec2),
101 FLOAT_VEC3 => Ok(ParameterType::FloatVec3),
102 FLOAT_VEC4 => Ok(ParameterType::FloatVec4),
103 INT_VEC2 => Ok(ParameterType::IntVec2),
104 INT_VEC3 => Ok(ParameterType::IntVec3),
105 INT_VEC4 => Ok(ParameterType::IntVec4),
106 BOOL => Ok(ParameterType::Bool),
107 BOOL_VEC2 => Ok(ParameterType::BoolVec2),
108 BOOL_VEC3 => Ok(ParameterType::BoolVec3),
109 BOOL_VEC4 => Ok(ParameterType::BoolVec4),
110 FLOAT_MAT2 => Ok(ParameterType::FloatMat2),
111 FLOAT_MAT3 => Ok(ParameterType::FloatMat3),
112 FLOAT_MAT4 => Ok(ParameterType::FloatMat4),
113 SAMPLER_2D => Ok(ParameterType::Sampler2d),
114 _ => Err(()),
115 }
116 }
117}
118
119impl From<ParameterType> for u32 {
120 fn from(value: ParameterType) -> Self {
121 match value {
122 ParameterType::Byte => BYTE,
123 ParameterType::UnsignedByte => UNSIGNED_BYTE,
124 ParameterType::Short => SHORT,
125 ParameterType::UnsignedShort => UNSIGNED_SHORT,
126 ParameterType::Int => INT,
127 ParameterType::UnsignedInt => UNSIGNED_INT,
128 ParameterType::Float => FLOAT,
129 ParameterType::FloatVec2 => FLOAT_VEC2,
130 ParameterType::FloatVec3 => FLOAT_VEC3,
131 ParameterType::FloatVec4 => FLOAT_VEC4,
132 ParameterType::IntVec2 => INT_VEC2,
133 ParameterType::IntVec3 => INT_VEC3,
134 ParameterType::IntVec4 => INT_VEC4,
135 ParameterType::Bool => BOOL,
136 ParameterType::BoolVec2 => BOOL_VEC2,
137 ParameterType::BoolVec3 => BOOL_VEC3,
138 ParameterType::BoolVec4 => BOOL_VEC4,
139 ParameterType::FloatMat2 => FLOAT_MAT2,
140 ParameterType::FloatMat3 => FLOAT_MAT3,
141 ParameterType::FloatMat4 => FLOAT_MAT4,
142 ParameterType::Sampler2d => SAMPLER_2D,
143 }
144 }
145}
146
147impl Serialize for ParameterType {
148 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
149 where
150 S: serde::Serializer,
151 {
152 serializer.serialize_u32((*self).into())
153 }
154}
155
156impl<'de> Deserialize<'de> for Checked<ParameterType> {
157 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
158 where
159 D: serde::Deserializer<'de>,
160 {
161 struct Visitor;
162 impl serde::de::Visitor<'_> for Visitor {
163 type Value = Checked<ParameterType>;
164
165 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
166 write!(f, "any of: {:?}", ParameterType::VALID_PARAMETER_TYPES)
167 }
168
169 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
170 where
171 E: de::Error,
172 {
173 Ok((value as u32)
174 .try_into()
175 .map(Checked::Valid)
176 .unwrap_or(Checked::Invalid))
177 }
178 }
179 deserializer.deserialize_u32(Visitor)
180 }
181}
182
183#[derive(Clone, Debug)]
184pub enum ParameterValue {
185 Number(f32),
186 Boolean(bool),
187 String(String),
188 NumberArray(Vec<f32>),
189 BoolArray(Vec<bool>),
190 StringArray(Vec<String>),
191}
192
193impl Serialize for ParameterValue {
194 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
195 where
196 S: serde::Serializer,
197 {
198 match self {
199 ParameterValue::Number(value) => serializer.serialize_f32(*value),
200 ParameterValue::Boolean(value) => serializer.serialize_bool(*value),
201 ParameterValue::String(value) => serializer.serialize_str(value),
202 ParameterValue::NumberArray(value) => {
203 let mut seq = serializer.serialize_seq(Some(value.len()))?;
204 for v in value {
205 seq.serialize_element(v)?;
206 }
207 seq.end()
208 }
209 ParameterValue::BoolArray(value) => {
210 let mut seq = serializer.serialize_seq(Some(value.len()))?;
211 for v in value {
212 seq.serialize_element(v)?;
213 }
214 seq.end()
215 }
216 ParameterValue::StringArray(value) => {
217 let mut seq = serializer.serialize_seq(Some(value.len()))?;
218 for v in value {
219 seq.serialize_element(v)?;
220 }
221 seq.end()
222 }
223 }
224 }
225}
226
227impl<'de> Deserialize<'de> for Checked<ParameterValue> {
228 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
229 where
230 D: serde::Deserializer<'de>,
231 {
232 struct ParameterValueVisitor;
233
234 impl<'de> serde::de::Visitor<'de> for ParameterValueVisitor {
235 type Value = Checked<ParameterValue>;
236
237 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
238 formatter.write_str("a number, boolean, string, or array of these types")
239 }
240
241 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
242 where
243 E: de::Error,
244 {
245 Ok(Checked::Valid(ParameterValue::Number(value as f32)))
246 }
247
248 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
249 where
250 E: de::Error,
251 {
252 Ok(Checked::Valid(ParameterValue::Number(value as f32)))
253 }
254
255 fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
256 where
257 E: de::Error,
258 {
259 Ok(Checked::Valid(ParameterValue::Number(value as f32)))
260 }
261
262 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
263 where
264 E: de::Error,
265 {
266 Ok(Checked::Valid(ParameterValue::Boolean(value)))
267 }
268
269 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
270 where
271 E: de::Error,
272 {
273 Ok(Checked::Valid(ParameterValue::String(value.to_string())))
274 }
275
276 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
277 where
278 A: serde::de::SeqAccess<'de>,
279 {
280 if let Some(first) = seq.next_element::<f64>()? {
282 let mut vec = vec![first as f32];
283 while let Some(val) = seq.next_element::<f64>()? {
284 vec.push(val as f32);
285 }
286 return Ok(Checked::Valid(ParameterValue::NumberArray(vec)));
287 }
288
289 if let Some(first) = seq.next_element::<bool>()? {
291 let mut vec = vec![first];
292 while let Some(val) = seq.next_element()? {
293 vec.push(val);
294 }
295 return Ok(Checked::Valid(ParameterValue::BoolArray(vec)));
296 }
297
298 if let Some(first) = seq.next_element::<String>()? {
300 let mut vec = vec![first];
301 while let Some(val) = seq.next_element()? {
302 vec.push(val);
303 }
304 return Ok(Checked::Valid(ParameterValue::StringArray(vec)));
305 }
306
307 Ok(Checked::Invalid)
308 }
309 }
310
311 deserializer.deserialize_any(ParameterValueVisitor)
312 }
313}
314
315pub const BLEND: u32 = 3042;
316pub const CULL_FACE: u32 = 2884;
317pub const DEPTH_TEST: u32 = 2929;
318pub const POLYGON_OFFSET_FILL: u32 = 32823;
319pub const SAMPLE_ALPHA_TO_COVERAGE: u32 = 32926;
320pub const SCISSOR_TEST: u32 = 3089;
321
322#[derive(Clone, Debug, PartialEq, Eq, Copy)]
323pub enum WebGLState {
324 Blend,
325 CullFace,
326 DepthTest,
327 PolygonOffsetFill,
328 SampleAlphaToCoverage,
329 ScissorTest,
330}
331
332impl WebGLState {
333 pub const VALID_WEB_GL_STATES: &[u32] = &[
334 BLEND,
335 CULL_FACE,
336 DEPTH_TEST,
337 POLYGON_OFFSET_FILL,
338 SAMPLE_ALPHA_TO_COVERAGE,
339 SCISSOR_TEST,
340 ];
341}
342
343impl From<WebGLState> for u32 {
344 fn from(value: WebGLState) -> Self {
345 match value {
346 WebGLState::Blend => BLEND,
347 WebGLState::CullFace => CULL_FACE,
348 WebGLState::DepthTest => DEPTH_TEST,
349 WebGLState::PolygonOffsetFill => POLYGON_OFFSET_FILL,
350 WebGLState::SampleAlphaToCoverage => SAMPLE_ALPHA_TO_COVERAGE,
351 WebGLState::ScissorTest => SCISSOR_TEST,
352 }
353 }
354}
355
356impl TryFrom<u32> for WebGLState {
357 type Error = ();
358
359 fn try_from(value: u32) -> Result<Self, Self::Error> {
360 match value {
361 BLEND => Ok(WebGLState::Blend),
362 CULL_FACE => Ok(WebGLState::CullFace),
363 DEPTH_TEST => Ok(WebGLState::DepthTest),
364 POLYGON_OFFSET_FILL => Ok(WebGLState::PolygonOffsetFill),
365 SAMPLE_ALPHA_TO_COVERAGE => Ok(WebGLState::SampleAlphaToCoverage),
366 SCISSOR_TEST => Ok(WebGLState::ScissorTest),
367 _ => Err(()),
368 }
369 }
370}
371
372impl Serialize for WebGLState {
373 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
374 where
375 S: serde::Serializer,
376 {
377 serializer.serialize_u32((*self).into())
378 }
379}
380
381impl<'de> Deserialize<'de> for Checked<WebGLState> {
382 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
383 where
384 D: serde::Deserializer<'de>,
385 {
386 struct Visitor;
387 impl serde::de::Visitor<'_> for Visitor {
388 type Value = Checked<WebGLState>;
389
390 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
391 write!(f, "any of: {:?}", WebGLState::VALID_WEB_GL_STATES)
392 }
393
394 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
395 where
396 E: de::Error,
397 {
398 Ok((value as u32)
399 .try_into()
400 .map(Checked::Valid)
401 .unwrap_or(Checked::Invalid))
402 }
403 }
404 deserializer.deserialize_u32(Visitor)
405 }
406}
407
408#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate, Default)]
409pub struct TechniqueParameter {
410 #[serde(skip_serializing_if = "Option::is_none")]
411 pub count: Option<USize64>,
412 #[serde(skip_serializing_if = "Option::is_none")]
413 pub node: Option<StringIndex<Node>>,
414 #[serde(rename = "type")]
415 pub type_: Checked<ParameterType>,
416 #[serde(skip_serializing_if = "Option::is_none")]
417 pub semantic: Option<String>,
418 #[serde(skip_serializing_if = "Option::is_none")]
419 pub value: Option<Checked<ParameterValue>>,
420}
421
422pub const FUNC_ADD: u32 = 32774;
423pub const FUNC_SUBTRACT: u32 = 32778;
424pub const FUNC_REVERSE_SUBTRACT: u32 = 32779;
425
426#[derive(Clone, Debug, PartialEq, Eq, Copy)]
427pub enum BlendEquationSeparate {
428 FuncAdd,
429 FuncSubtract,
430 FuncReverseSubtract,
431}
432
433impl BlendEquationSeparate {
434 pub const VALID_BLEND_EQUATION_SEPARATES: &[u32] =
435 &[FUNC_ADD, FUNC_SUBTRACT, FUNC_REVERSE_SUBTRACT];
436}
437
438impl From<BlendEquationSeparate> for u32 {
439 fn from(value: BlendEquationSeparate) -> Self {
440 match value {
441 BlendEquationSeparate::FuncAdd => FUNC_ADD,
442 BlendEquationSeparate::FuncSubtract => FUNC_SUBTRACT,
443 BlendEquationSeparate::FuncReverseSubtract => FUNC_REVERSE_SUBTRACT,
444 }
445 }
446}
447
448impl TryFrom<u32> for BlendEquationSeparate {
449 type Error = ();
450
451 fn try_from(value: u32) -> Result<Self, Self::Error> {
452 match value {
453 FUNC_ADD => Ok(BlendEquationSeparate::FuncAdd),
454 FUNC_SUBTRACT => Ok(BlendEquationSeparate::FuncSubtract),
455 FUNC_REVERSE_SUBTRACT => Ok(BlendEquationSeparate::FuncReverseSubtract),
456 _ => Err(()),
457 }
458 }
459}
460
461impl Serialize for BlendEquationSeparate {
462 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
463 where
464 S: serde::Serializer,
465 {
466 serializer.serialize_u32((*self).into())
467 }
468}
469
470impl<'de> Deserialize<'de> for Checked<BlendEquationSeparate> {
471 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
472 where
473 D: serde::Deserializer<'de>,
474 {
475 struct Visitor;
476 impl serde::de::Visitor<'_> for Visitor {
477 type Value = Checked<BlendEquationSeparate>;
478
479 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
480 write!(
481 f,
482 "any of: {:?}",
483 BlendEquationSeparate::VALID_BLEND_EQUATION_SEPARATES
484 )
485 }
486
487 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
488 where
489 E: de::Error,
490 {
491 Ok((value as u32)
492 .try_into()
493 .map(Checked::Valid)
494 .unwrap_or(Checked::Invalid))
495 }
496 }
497 deserializer.deserialize_u32(Visitor)
498 }
499}
500
501pub const ZERO: u32 = 0;
502pub const ONE: u32 = 1;
503pub const SRC_COLOR: u32 = 768;
504pub const ONE_MINUS_SRC_COLOR: u32 = 769;
505pub const DST_COLOR: u32 = 774;
506pub const ONE_MINUS_DST_COLOR: u32 = 775;
507pub const SRC_ALPHA: u32 = 770;
508pub const ONE_MINUS_SRC_ALPHA: u32 = 771;
509pub const DST_ALPHA: u32 = 772;
510pub const ONE_MINUS_DST_ALPHA: u32 = 773;
511pub const CONSTANT_COLOR: u32 = 32769;
512pub const ONE_MINUS_CONSTANT_COLOR: u32 = 32770;
513pub const CONSTANT_ALPHA: u32 = 32771;
514pub const ONE_MINUS_CONSTANT_ALPHA: u32 = 32772;
515pub const SRC_ALPHA_SATURATE: u32 = 776;
516
517#[derive(Clone, Debug, PartialEq, Eq, Copy)]
518pub enum BlendFuncSeparate {
519 Zero,
520 One,
521 SrcColor,
522 OneMinusSrcColor,
523 DstColor,
524 OneMinusDstColor,
525 SrcAlpha,
526 OneMinusSrcAlpha,
527 DstAlpha,
528 OneMinusDstAlpha,
529 ConstantColor,
530 OneMinusConstantColor,
531 ConstantAlpha,
532 OneMinusConstantAlpha,
533 SrcAlphaSaturate,
534}
535
536impl BlendFuncSeparate {
537 pub const VALID_BLEND_FUNC_SEPARATES: &[u32] = &[
538 ZERO,
539 ONE,
540 SRC_COLOR,
541 ONE_MINUS_SRC_COLOR,
542 DST_COLOR,
543 ONE_MINUS_DST_COLOR,
544 SRC_ALPHA,
545 ONE_MINUS_SRC_ALPHA,
546 DST_ALPHA,
547 ONE_MINUS_DST_ALPHA,
548 CONSTANT_COLOR,
549 ONE_MINUS_CONSTANT_COLOR,
550 CONSTANT_ALPHA,
551 ONE_MINUS_CONSTANT_ALPHA,
552 SRC_ALPHA_SATURATE,
553 ];
554}
555
556impl From<BlendFuncSeparate> for u32 {
557 fn from(value: BlendFuncSeparate) -> Self {
558 match value {
559 BlendFuncSeparate::Zero => ZERO,
560 BlendFuncSeparate::One => ONE,
561 BlendFuncSeparate::SrcColor => SRC_COLOR,
562 BlendFuncSeparate::OneMinusSrcColor => ONE_MINUS_SRC_COLOR,
563 BlendFuncSeparate::DstColor => DST_COLOR,
564 BlendFuncSeparate::OneMinusDstColor => ONE_MINUS_DST_COLOR,
565 BlendFuncSeparate::SrcAlpha => SRC_ALPHA,
566 BlendFuncSeparate::OneMinusSrcAlpha => ONE_MINUS_SRC_ALPHA,
567 BlendFuncSeparate::DstAlpha => DST_ALPHA,
568 BlendFuncSeparate::OneMinusDstAlpha => ONE_MINUS_DST_ALPHA,
569 BlendFuncSeparate::ConstantColor => CONSTANT_COLOR,
570 BlendFuncSeparate::OneMinusConstantColor => ONE_MINUS_CONSTANT_COLOR,
571 BlendFuncSeparate::ConstantAlpha => CONSTANT_ALPHA,
572 BlendFuncSeparate::OneMinusConstantAlpha => ONE_MINUS_CONSTANT_ALPHA,
573 BlendFuncSeparate::SrcAlphaSaturate => SRC_ALPHA_SATURATE,
574 }
575 }
576}
577
578impl TryFrom<u32> for BlendFuncSeparate {
579 type Error = ();
580
581 fn try_from(value: u32) -> Result<Self, Self::Error> {
582 match value {
583 ZERO => Ok(BlendFuncSeparate::Zero),
584 ONE => Ok(BlendFuncSeparate::One),
585 SRC_COLOR => Ok(BlendFuncSeparate::SrcColor),
586 ONE_MINUS_SRC_COLOR => Ok(BlendFuncSeparate::OneMinusSrcColor),
587 DST_COLOR => Ok(BlendFuncSeparate::DstColor),
588 ONE_MINUS_DST_COLOR => Ok(BlendFuncSeparate::OneMinusDstColor),
589 SRC_ALPHA => Ok(BlendFuncSeparate::SrcAlpha),
590 ONE_MINUS_SRC_ALPHA => Ok(BlendFuncSeparate::OneMinusSrcAlpha),
591 DST_ALPHA => Ok(BlendFuncSeparate::DstAlpha),
592 ONE_MINUS_DST_ALPHA => Ok(BlendFuncSeparate::OneMinusDstAlpha),
593 CONSTANT_COLOR => Ok(BlendFuncSeparate::ConstantColor),
594 ONE_MINUS_CONSTANT_COLOR => Ok(BlendFuncSeparate::OneMinusConstantColor),
595 CONSTANT_ALPHA => Ok(BlendFuncSeparate::ConstantAlpha),
596 ONE_MINUS_CONSTANT_ALPHA => Ok(BlendFuncSeparate::OneMinusConstantAlpha),
597 SRC_ALPHA_SATURATE => Ok(BlendFuncSeparate::SrcAlphaSaturate),
598 _ => Err(()),
599 }
600 }
601}
602
603impl Serialize for BlendFuncSeparate {
604 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
605 where
606 S: serde::Serializer,
607 {
608 serializer.serialize_u32((*self).into())
609 }
610}
611
612impl<'de> Deserialize<'de> for Checked<BlendFuncSeparate> {
613 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
614 where
615 D: serde::Deserializer<'de>,
616 {
617 struct Visitor;
618 impl serde::de::Visitor<'_> for Visitor {
619 type Value = Checked<BlendFuncSeparate>;
620
621 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
622 write!(
623 f,
624 "any of: {:?}",
625 BlendFuncSeparate::VALID_BLEND_FUNC_SEPARATES
626 )
627 }
628
629 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
630 where
631 E: de::Error,
632 {
633 Ok((value as u32)
634 .try_into()
635 .map(Checked::Valid)
636 .unwrap_or(Checked::Invalid))
637 }
638 }
639 deserializer.deserialize_u32(Visitor)
640 }
641}
642
643pub const FRONT: u32 = 1028;
644pub const BACK: u32 = 1029;
645pub const FRONT_AND_BACK: u32 = 1032;
646
647#[derive(Clone, Debug, PartialEq, Eq, Copy)]
648pub enum CullFace {
649 Front,
650 Back,
651 FrontAndBack,
652}
653
654impl CullFace {
655 pub const VALID_CULL_FACES: &[u32] = &[FRONT, BACK, FRONT_AND_BACK];
656}
657
658impl From<CullFace> for u32 {
659 fn from(value: CullFace) -> Self {
660 match value {
661 CullFace::Front => FRONT,
662 CullFace::Back => BACK,
663 CullFace::FrontAndBack => FRONT_AND_BACK,
664 }
665 }
666}
667
668impl TryFrom<u32> for CullFace {
669 type Error = ();
670
671 fn try_from(value: u32) -> Result<Self, Self::Error> {
672 match value {
673 FRONT => Ok(CullFace::Front),
674 BACK => Ok(CullFace::Back),
675 FRONT_AND_BACK => Ok(CullFace::FrontAndBack),
676 _ => Err(()),
677 }
678 }
679}
680
681impl Serialize for CullFace {
682 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
683 where
684 S: serde::Serializer,
685 {
686 serializer.serialize_u32((*self).into())
687 }
688}
689
690impl<'de> Deserialize<'de> for Checked<CullFace> {
691 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
692 where
693 D: serde::Deserializer<'de>,
694 {
695 struct Visitor;
696 impl serde::de::Visitor<'_> for Visitor {
697 type Value = Checked<CullFace>;
698
699 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
700 write!(f, "any of: {:?}", CullFace::VALID_CULL_FACES)
701 }
702
703 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
704 where
705 E: de::Error,
706 {
707 Ok((value as u32)
708 .try_into()
709 .map(Checked::Valid)
710 .unwrap_or(Checked::Invalid))
711 }
712 }
713 deserializer.deserialize_u32(Visitor)
714 }
715}
716
717pub const NEVER: u32 = 512;
718pub const LESS: u32 = 513;
719pub const LEQUAL: u32 = 515;
720pub const EQUAL: u32 = 514;
721pub const GREATER: u32 = 516;
722pub const NOTEQUAL: u32 = 517;
723pub const GEQUAL: u32 = 518;
724pub const ALWAYS: u32 = 519;
725
726#[derive(Clone, Debug, PartialEq, Eq, Copy)]
727pub enum DepthFunc {
728 Never,
729 Less,
730 LEqual,
731 Equal,
732 Greater,
733 NotEqual,
734 GEqual,
735 Always,
736}
737
738impl DepthFunc {
739 pub const VALID_DEPTH_FUNCS: &[u32] = &[
740 NEVER, LESS, LEQUAL, EQUAL, GREATER, NOTEQUAL, GEQUAL, ALWAYS,
741 ];
742}
743
744impl From<DepthFunc> for u32 {
745 fn from(value: DepthFunc) -> Self {
746 match value {
747 DepthFunc::Never => NEVER,
748 DepthFunc::Less => LESS,
749 DepthFunc::LEqual => LEQUAL,
750 DepthFunc::Equal => EQUAL,
751 DepthFunc::Greater => GREATER,
752 DepthFunc::NotEqual => NOTEQUAL,
753 DepthFunc::GEqual => GEQUAL,
754 DepthFunc::Always => ALWAYS,
755 }
756 }
757}
758
759impl TryFrom<u32> for DepthFunc {
760 type Error = ();
761
762 fn try_from(value: u32) -> Result<Self, Self::Error> {
763 match value {
764 NEVER => Ok(DepthFunc::Never),
765 LESS => Ok(DepthFunc::Less),
766 LEQUAL => Ok(DepthFunc::LEqual),
767 EQUAL => Ok(DepthFunc::Equal),
768 GREATER => Ok(DepthFunc::Greater),
769 NOTEQUAL => Ok(DepthFunc::NotEqual),
770 GEQUAL => Ok(DepthFunc::GEqual),
771 ALWAYS => Ok(DepthFunc::Always),
772 _ => Err(()),
773 }
774 }
775}
776
777impl Serialize for DepthFunc {
778 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
779 where
780 S: serde::Serializer,
781 {
782 serializer.serialize_u32((*self).into())
783 }
784}
785
786impl<'de> Deserialize<'de> for Checked<DepthFunc> {
787 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
788 where
789 D: serde::Deserializer<'de>,
790 {
791 struct Visitor;
792 impl serde::de::Visitor<'_> for Visitor {
793 type Value = Checked<DepthFunc>;
794
795 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
796 write!(f, "any of: {:?}", DepthFunc::VALID_DEPTH_FUNCS)
797 }
798
799 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
800 where
801 E: de::Error,
802 {
803 Ok((value as u32)
804 .try_into()
805 .map(Checked::Valid)
806 .unwrap_or(Checked::Invalid))
807 }
808 }
809 deserializer.deserialize_u32(Visitor)
810 }
811}
812
813pub const CW: u32 = 2304;
814pub const CCW: u32 = 2305;
815
816#[derive(Clone, Debug, PartialEq, Eq, Copy)]
817pub enum FrontFace {
818 CW,
819 CCW,
820}
821
822impl FrontFace {
823 pub const VALID_FRONT_FACES: &[u32] = &[CW, CCW];
824}
825
826impl From<FrontFace> for u32 {
827 fn from(value: FrontFace) -> Self {
828 match value {
829 FrontFace::CW => CW,
830 FrontFace::CCW => CCW,
831 }
832 }
833}
834
835impl TryFrom<u32> for FrontFace {
836 type Error = ();
837
838 fn try_from(value: u32) -> Result<Self, Self::Error> {
839 match value {
840 CW => Ok(FrontFace::CW),
841 CCW => Ok(FrontFace::CCW),
842 _ => Err(()),
843 }
844 }
845}
846
847impl Serialize for FrontFace {
848 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
849 where
850 S: serde::Serializer,
851 {
852 serializer.serialize_u32((*self).into())
853 }
854}
855
856impl<'de> Deserialize<'de> for Checked<FrontFace> {
857 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
858 where
859 D: serde::Deserializer<'de>,
860 {
861 struct Visitor;
862 impl serde::de::Visitor<'_> for Visitor {
863 type Value = Checked<FrontFace>;
864
865 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
866 write!(f, "any of: {:?}", FrontFace::VALID_FRONT_FACES)
867 }
868
869 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
870 where
871 E: de::Error,
872 {
873 Ok((value as u32)
874 .try_into()
875 .map(Checked::Valid)
876 .unwrap_or(Checked::Invalid))
877 }
878 }
879 deserializer.deserialize_u32(Visitor)
880 }
881}
882#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate)]
883pub struct TechniqueStateFunction {
884 #[serde(
885 rename = "blendColor",
886 skip_serializing_if = "blend_color_is_zero",
887 default = "default_blend_color"
888 )]
889 pub blend_color: [f32; 4],
890 #[serde(
891 rename = "blendEquationSeparate",
892 skip_serializing_if = "blend_equation_seperate_is_default",
893 default = "default_blend_equation_seperate"
894 )]
895 pub blend_equation_seperate: [Checked<BlendEquationSeparate>; 2],
896 #[serde(
897 rename = "blendFuncSeparate",
898 skip_serializing_if = "blend_func_seperate_is_default",
899 default = "default_blend_func_seperate"
900 )]
901 pub blend_func_seperate: [Checked<BlendFuncSeparate>; 4],
902 #[serde(
903 rename = "colorMask",
904 skip_serializing_if = "color_mask_is_default",
905 default = "default_color_mask"
906 )]
907 pub color_mask: [bool; 4],
908 #[serde(
909 rename = "cullFace",
910 skip_serializing_if = "cull_face_is_default",
911 default = "default_cull_face"
912 )]
913 pub cull_face: [Checked<CullFace>; 1],
914 #[serde(
915 rename = "depthFunc",
916 skip_serializing_if = "depth_func_is_default",
917 default = "default_depth_func"
918 )]
919 pub depth_func: [Checked<DepthFunc>; 1],
920 #[serde(
921 rename = "depthMask",
922 skip_serializing_if = "depth_mask_is_default",
923 default = "default_depth_mask"
924 )]
925 pub depth_mask: [bool; 1],
926 #[serde(
927 rename = "depthRange",
928 skip_serializing_if = "depth_range_is_default",
929 default = "default_depth_range"
930 )]
931 pub depth_range: [f32; 2],
932 #[serde(
933 rename = "frontFace",
934 skip_serializing_if = "front_face_is_default",
935 default = "default_front_face"
936 )]
937 pub front_face: [Checked<FrontFace>; 1],
938 #[serde(
939 rename = "lineWidth",
940 skip_serializing_if = "line_width_is_default",
941 default = "default_line_width"
942 )]
943 pub line_width: [f32; 1],
944 #[serde(
945 rename = "polygonOffset",
946 skip_serializing_if = "polygon_offset_is_default",
947 default = "default_polygon_offset"
948 )]
949 pub polygon_offset: [f32; 2],
950 #[serde(
951 skip_serializing_if = "scissor_is_default",
952 default = "default_scissor"
953 )]
954 pub scissor: [f32; 4],
955}
956
957fn blend_color_is_zero(value: &[f32; 4]) -> bool {
958 value[0] == 0.0 && value[1] == 0.0 && value[2] == 0.0 && value[3] == 0.0
959}
960
961fn default_blend_color() -> [f32; 4] {
962 [0.0, 0.0, 0.0, 0.0]
963}
964
965fn blend_equation_seperate_is_default(value: &[Checked<BlendEquationSeparate>; 2]) -> bool {
966 value[0] == Checked::Valid(BlendEquationSeparate::FuncAdd)
967 && value[1] == Checked::Valid(BlendEquationSeparate::FuncAdd)
968}
969
970fn default_blend_equation_seperate() -> [Checked<BlendEquationSeparate>; 2] {
971 [
972 Checked::Valid(BlendEquationSeparate::FuncAdd),
973 Checked::Valid(BlendEquationSeparate::FuncAdd),
974 ]
975}
976fn blend_func_seperate_is_default(value: &[Checked<BlendFuncSeparate>; 4]) -> bool {
977 value[0] == Checked::Valid(BlendFuncSeparate::One)
978 && value[1] == Checked::Valid(BlendFuncSeparate::Zero)
979 && value[2] == Checked::Valid(BlendFuncSeparate::One)
980 && value[3] == Checked::Valid(BlendFuncSeparate::Zero)
981}
982
983fn default_blend_func_seperate() -> [Checked<BlendFuncSeparate>; 4] {
984 [
985 Checked::Valid(BlendFuncSeparate::One),
986 Checked::Valid(BlendFuncSeparate::Zero),
987 Checked::Valid(BlendFuncSeparate::One),
988 Checked::Valid(BlendFuncSeparate::Zero),
989 ]
990}
991
992fn color_mask_is_default(value: &[bool; 4]) -> bool {
993 value[0] && value[1] && value[2] && value[3]
994}
995
996fn default_color_mask() -> [bool; 4] {
997 [true, true, true, true]
998}
999
1000fn cull_face_is_default(value: &[Checked<CullFace>; 1]) -> bool {
1001 value[0] == Checked::Valid(CullFace::Back)
1002}
1003
1004fn default_cull_face() -> [Checked<CullFace>; 1] {
1005 [Checked::Valid(CullFace::Back)]
1006}
1007
1008fn depth_func_is_default(value: &[Checked<DepthFunc>; 1]) -> bool {
1009 value[0] == Checked::Valid(DepthFunc::Less)
1010}
1011
1012fn default_depth_func() -> [Checked<DepthFunc>; 1] {
1013 [Checked::Valid(DepthFunc::Less)]
1014}
1015
1016fn depth_mask_is_default(value: &[bool; 1]) -> bool {
1017 value[0]
1018}
1019
1020fn default_depth_mask() -> [bool; 1] {
1021 [true]
1022}
1023
1024fn depth_range_is_default(value: &[f32; 2]) -> bool {
1025 value[0] == 0.0 && value[1] == 1.0
1026}
1027
1028fn default_depth_range() -> [f32; 2] {
1029 [0.0, 1.0]
1030}
1031
1032fn front_face_is_default(value: &[Checked<FrontFace>; 1]) -> bool {
1033 value[0] == Checked::Valid(FrontFace::CCW)
1034}
1035
1036fn default_front_face() -> [Checked<FrontFace>; 1] {
1037 [Checked::Valid(FrontFace::CCW)]
1038}
1039
1040fn line_width_is_default(value: &[f32; 1]) -> bool {
1041 value[0] == 1.0
1042}
1043
1044fn default_line_width() -> [f32; 1] {
1045 [1.0]
1046}
1047
1048fn polygon_offset_is_default(value: &[f32; 2]) -> bool {
1049 value[0] == 0.0 && value[1] == 0.0
1050}
1051
1052fn default_polygon_offset() -> [f32; 2] {
1053 [0.0, 0.0]
1054}
1055
1056fn scissor_is_default(value: &[f32; 4]) -> bool {
1057 value[0] == 0.0 && value[1] == 0.0 && value[2] == 0.0 && value[3] == 0.0
1058}
1059
1060fn default_scissor() -> [f32; 4] {
1061 [0.0, 0.0, 0.0, 0.0]
1062}
1063
1064#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate)]
1065pub struct TechniqueState {
1066 #[serde(default)]
1067 #[serde(skip_serializing_if = "Vec::is_empty")]
1068 pub enable: Vec<Checked<WebGLState>>,
1069 #[serde(skip_serializing_if = "Option::is_none")]
1070 pub functions: Option<TechniqueStateFunction>,
1071}
1072
1073#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate)]
1074#[gltf(validate_hook = "technique_validate_technique")]
1075pub struct Technique {
1076 #[serde(skip_serializing_if = "IndexMap::is_empty")]
1077 pub parameters: IndexMap<String, TechniqueParameter>,
1078 #[serde(skip_serializing_if = "IndexMap::is_empty")]
1079 pub attributes: IndexMap<String, String>,
1080 pub program: StringIndex<Program>,
1081 #[serde(skip_serializing_if = "IndexMap::is_empty")]
1082 pub uniforms: IndexMap<String, String>,
1083 #[serde(skip_serializing_if = "Option::is_none")]
1084 pub states: Option<TechniqueState>,
1085 #[serde(skip_serializing_if = "Option::is_none")]
1086 pub name: Option<String>,
1087}
1088
1089impl Technique {
1090 pub(crate) fn default_technique(program: String) -> Self {
1091 let mut attributes = IndexMap::new();
1092 attributes.insert("a_position".to_string(), "position".to_string());
1093
1094 let mut parameters = IndexMap::new();
1095 parameters.insert(
1096 "modelViewMatrix".to_string(),
1097 TechniqueParameter {
1098 semantic: Some("MODELVIEW".to_string()),
1099 type_: Checked::Valid(ParameterType::FloatMat4),
1100 ..TechniqueParameter::default()
1101 },
1102 );
1103 parameters.insert(
1104 "projectionMatrix".to_string(),
1105 TechniqueParameter {
1106 semantic: Some("PROJECTION".to_string()),
1107 type_: Checked::Valid(ParameterType::FloatMat4),
1108 ..TechniqueParameter::default()
1109 },
1110 );
1111 parameters.insert(
1112 "emission".to_string(),
1113 TechniqueParameter {
1114 value: Some(Checked::Valid(ParameterValue::NumberArray(vec![
1115 0.5, 0.5, 0.5, 1.0,
1116 ]))),
1117 type_: Checked::Valid(ParameterType::FloatVec4),
1118 ..TechniqueParameter::default()
1119 },
1120 );
1121 parameters.insert(
1122 "position".to_string(),
1123 TechniqueParameter {
1124 semantic: Some("POSITION".to_string()),
1125 type_: Checked::Valid(ParameterType::FloatVec3),
1126 ..TechniqueParameter::default()
1127 },
1128 );
1129
1130 let mut uniforms = IndexMap::new();
1131 uniforms.insert(
1132 "u_modelViewMatrix".to_string(),
1133 "modelViewMatrix".to_string(),
1134 );
1135 uniforms.insert(
1136 "u_projectionMatrix".to_string(),
1137 "projectionMatrix".to_string(),
1138 );
1139 uniforms.insert("u_emission".to_string(), "emission".to_string());
1140
1141 Technique {
1142 attributes,
1143 parameters,
1144 program: StringIndex::new(program),
1145 uniforms,
1146 states: Some(TechniqueState {
1147 enable: vec![
1148 Checked::Valid(WebGLState::CullFace),
1149 Checked::Valid(WebGLState::DepthTest),
1150 ],
1151 functions: None,
1152 }),
1153 name: None,
1154 }
1155 }
1156}
1157fn technique_validate_technique<P, R>(technique: &Technique, _root: &Root, path: P, report: &mut R)
1158where
1159 P: Fn() -> Path,
1160 R: FnMut(&dyn Fn() -> Path, Error),
1161{
1162 for (_, parameter_key) in &technique.attributes {
1163 if !technique.parameters.contains_key(parameter_key) {
1164 report(&path, Error::IndexNotFound);
1165 }
1166 }
1167 for (_, parameter_key) in &technique.uniforms {
1168 if !technique.parameters.contains_key(parameter_key) {
1169 report(&path, Error::IndexNotFound);
1170 }
1171 }
1172}
1173
1174#[derive(Clone, Debug, serde_derive::Deserialize, serde_derive::Serialize, Validate, Default)]
1175pub struct Material {
1176 #[serde(skip_serializing_if = "Option::is_none")]
1177 pub technique: Option<StringIndex<Technique>>,
1178 #[serde(skip_serializing_if = "IndexMap::is_empty")]
1179 pub values: IndexMap<String, Checked<ParameterValue>>,
1180 #[serde(skip_serializing_if = "Option::is_none")]
1181 pub name: Option<String>,
1182 #[serde(default, skip_serializing_if = "Option::is_none")]
1183 pub extensions: Option<extensions::material::Material>,
1184}
1185
1186#[test]
1187fn test_technique_deserialize() {
1188 let data = r#"{
1189 "name": "user-defined technique name",
1190 "parameters": {
1191 "ambient": {
1192 "type": 35666,
1193 "extensions" : {
1194 "extension_name" : {
1195 "extension specific" : "value"
1196 }
1197 },
1198 "extras" : {
1199 "Application specific" : "The extra object can contain any properties."
1200 }
1201 },
1202 "diffuse": {
1203 "type": 35678
1204 },
1205 "lightColor": {
1206 "type": 35665,
1207 "value": [
1208 1,
1209 1,
1210 1
1211 ]
1212 },
1213 "lightTransform": {
1214 "node": "directional_light_node_id",
1215 "type": 35676
1216 },
1217 "modelViewMatrix": {
1218 "semantic": "MODELVIEW",
1219 "type": 35676
1220 },
1221 "projectionMatrix": {
1222 "semantic": "PROJECTION",
1223 "type": 35676
1224 },
1225 "normalMatrix": {
1226 "semantic": "MODELVIEWINVERSETRANSPOSE",
1227 "type": 35675
1228 },
1229
1230 "position": {
1231 "semantic": "POSITION",
1232 "type": 35665
1233 },
1234 "normal": {
1235 "semantic": "NORMAL",
1236 "type": 35665
1237 },
1238 "texcoord": {
1239 "semantic": "TEXCOORD_0",
1240 "type": 35664
1241 },
1242
1243 "joint": {
1244 "semantic": "JOINT",
1245 "type": 35666
1246 },
1247 "jointMatrix": {
1248 "semantic": "JOINTMATRIX",
1249 "type": 35676
1250 },
1251 "weight": {
1252 "semantic": "WEIGHT",
1253 "type": 35666
1254 }
1255 },
1256 "attributes": {
1257 "a_position": "position",
1258 "a_normal": "normal",
1259 "a_texcoord0": "texcoord0",
1260 "a_joint": "joint",
1261 "a_weight": "weight"
1262 },
1263 "program": "program_id",
1264 "uniforms": {
1265 "u_ambient": "ambient",
1266 "u_diffuse": "diffuse",
1267 "u_lightColor": "lightColor",
1268 "u_lightTransformMatrix": "lightTransform",
1269 "u_modelViewMatrix": "modelViewMatrix",
1270 "u_projectionMatrix": "projectionMatrix",
1271 "u_normalMatrix": "normalMatrix",
1272 "u_jointMatrix": "jointMatrix"
1273 },
1274 "states" : {
1275 "enable" : [3042, 2884, 2929, 32823, 32926, 3089],
1276 "functions" : {
1277 "blendColor": [0.0, 0.0, 0.0, 0.0],
1278 "blendEquationSeparate" : [32774, 32774],
1279 "blendFuncSeparate" : [1, 0, 1, 0],
1280 "colorMask" : [true, true, true, true],
1281 "cullFace" : [1029],
1282 "depthFunc" : [513],
1283 "depthMask" : [true],
1284 "depthRange" : [0.0, 1.0],
1285 "frontFace" : [2305],
1286 "lineWidth" : [1.0],
1287 "polygonOffset" : [0.0, 0.0],
1288 "scissor" : [0, 0, 0, 0],
1289 "extensions" : {
1290 "extension_name" : {
1291 "extension specific" : "value"
1292 }
1293 },
1294 "extras" : {
1295 "Application specific" : "The extra object can contain any properties."
1296 }
1297 },
1298 "extensions" : {
1299 "extension_name" : {
1300 "extension specific" : "value"
1301 }
1302 },
1303 "extras" : {
1304 "Application specific" : "The extra object can contain any properties."
1305 }
1306 },
1307 "extensions" : {
1308 "extension_name" : {
1309 "extension specific" : "value"
1310 }
1311 },
1312 "extras" : {
1313 "Application specific" : "The extra object can contain any properties."
1314 }
1315 }"#;
1316 let technique: Result<Technique, _> = serde_json::from_str(data);
1317 let technique_unwrap = technique.unwrap();
1318 println!("{}", serde_json::to_string(&technique_unwrap).unwrap());
1319 assert_eq!(
1320 Some("user-defined technique name".to_string()),
1321 technique_unwrap.name
1322 );
1323}
1324#[test]
1325fn test_material_deserialize() {
1326 let data = r#"{
1327 "technique": "technique_id",
1328 "values": {
1329 "ambient": [
1330 0,
1331 0,
1332 0,
1333 1
1334 ],
1335 "diffuse": "texture_image_0",
1336 "shininess": 38.4
1337 },
1338 "name": "user-defined material name",
1339 "extensions" : {
1340 "extension_name" : {
1341 "extension specific" : "value"
1342 }
1343 },
1344 "extras" : {
1345 "Application specific" : "The extra object can contain any properties."
1346 }
1347 }"#;
1348 let material: Result<Material, _> = serde_json::from_str(data);
1349 let material_unwrap = material.unwrap();
1350 println!("{}", serde_json::to_string(&material_unwrap).unwrap());
1351 assert_eq!(
1352 Some("user-defined material name".to_string()),
1353 material_unwrap.name
1354 );
1355}