1use crate::validation::Checked;
2use crate::{extensions, image, Index};
3use serde::{de, ser};
4use serde_derive::{Deserialize, Serialize};
5use shine_gltf_macro::Validate;
6use std::fmt;
7
8pub const NEAREST: u32 = 9728;
10
11pub const LINEAR: u32 = 9729;
13
14pub const NEAREST_MIPMAP_NEAREST: u32 = 9984;
16
17pub const LINEAR_MIPMAP_NEAREST: u32 = 9985;
19
20pub const NEAREST_MIPMAP_LINEAR: u32 = 9986;
22
23pub const LINEAR_MIPMAP_LINEAR: u32 = 9987;
25
26pub const CLAMP_TO_EDGE: u32 = 33_071;
28
29pub const MIRRORED_REPEAT: u32 = 33_648;
31
32pub const REPEAT: u32 = 10_497;
34
35pub const VALID_MAG_FILTERS: &[u32] = &[NEAREST, LINEAR];
37
38pub const VALID_MIN_FILTERS: &[u32] = &[
40 NEAREST,
41 LINEAR,
42 NEAREST_MIPMAP_NEAREST,
43 LINEAR_MIPMAP_NEAREST,
44 NEAREST_MIPMAP_LINEAR,
45 LINEAR_MIPMAP_LINEAR,
46];
47
48pub const VALID_WRAPPING_MODES: &[u32] = &[CLAMP_TO_EDGE, MIRRORED_REPEAT, REPEAT];
50
51#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
53pub enum MagFilter {
54 Nearest = 1,
56
57 Linear,
59}
60
61impl MagFilter {
62 pub fn as_gl_enum(self) -> u32 {
64 match self {
65 MagFilter::Nearest => NEAREST,
66 MagFilter::Linear => LINEAR,
67 }
68 }
69}
70
71#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
73pub enum MinFilter {
74 Nearest = 1,
76
77 Linear,
79
80 NearestMipmapNearest,
82
83 LinearMipmapNearest,
85
86 NearestMipmapLinear,
88
89 LinearMipmapLinear,
91}
92
93impl MinFilter {
94 pub fn as_gl_enum(self) -> u32 {
96 match self {
97 MinFilter::Nearest => NEAREST,
98 MinFilter::Linear => LINEAR,
99 MinFilter::NearestMipmapNearest => NEAREST_MIPMAP_NEAREST,
100 MinFilter::LinearMipmapNearest => LINEAR_MIPMAP_NEAREST,
101 MinFilter::NearestMipmapLinear => NEAREST_MIPMAP_LINEAR,
102 MinFilter::LinearMipmapLinear => LINEAR_MIPMAP_LINEAR,
103 }
104 }
105}
106
107#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
109pub enum WrappingMode {
110 ClampToEdge = 1,
112
113 MirroredRepeat,
115
116 Repeat,
118}
119
120impl WrappingMode {
121 pub fn as_gl_enum(self) -> u32 {
123 match self {
124 WrappingMode::ClampToEdge => CLAMP_TO_EDGE,
125 WrappingMode::MirroredRepeat => MIRRORED_REPEAT,
126 WrappingMode::Repeat => REPEAT,
127 }
128 }
129}
130
131#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
133#[serde(default)]
134pub struct Sampler {
135 #[serde(rename = "magFilter")]
137 #[serde(skip_serializing_if = "Option::is_none")]
138 pub mag_filter: Option<Checked<MagFilter>>,
139
140 #[serde(rename = "minFilter")]
142 #[serde(skip_serializing_if = "Option::is_none")]
143 pub min_filter: Option<Checked<MinFilter>>,
144
145 #[serde(default, rename = "wrapS")]
147 pub wrap_s: Checked<WrappingMode>,
148
149 #[serde(default, rename = "wrapT")]
151 pub wrap_t: Checked<WrappingMode>,
152
153 #[serde(default, skip_serializing_if = "Option::is_none")]
155 pub extensions: Option<extensions::texture::Sampler>,
156}
157
158#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
160pub struct Texture {
161 #[serde(skip_serializing_if = "Option::is_none")]
163 pub sampler: Option<Index<Sampler>>,
164
165 pub source: Index<image::Image>,
167
168 #[serde(default, skip_serializing_if = "Option::is_none")]
170 pub extensions: Option<extensions::texture::Texture>,
171}
172
173#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
174pub struct Info {
176 pub index: Index<Texture>,
178
179 #[serde(default, rename = "texCoord")]
181 pub tex_coord: u32,
182
183 #[serde(default, skip_serializing_if = "Option::is_none")]
185 pub extensions: Option<extensions::texture::Info>,
186}
187
188impl<'de> de::Deserialize<'de> for Checked<MagFilter> {
189 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
190 where
191 D: de::Deserializer<'de>,
192 {
193 struct Visitor;
194 impl<'de> de::Visitor<'de> for Visitor {
195 type Value = Checked<MagFilter>;
196
197 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
198 write!(f, "any of: {:?}", VALID_MAG_FILTERS)
199 }
200
201 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
202 where
203 E: de::Error,
204 {
205 use self::MagFilter::*;
206 use crate::validation::Checked::*;
207 Ok(match value as u32 {
208 NEAREST => Valid(Nearest),
209 LINEAR => Valid(Linear),
210 _ => Invalid,
211 })
212 }
213 }
214 deserializer.deserialize_u64(Visitor)
215 }
216}
217
218impl<'de> de::Deserialize<'de> for Checked<MinFilter> {
219 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
220 where
221 D: de::Deserializer<'de>,
222 {
223 struct Visitor;
224 impl<'de> de::Visitor<'de> for Visitor {
225 type Value = Checked<MinFilter>;
226
227 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
228 write!(f, "any of: {:?}", VALID_MIN_FILTERS)
229 }
230
231 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
232 where
233 E: de::Error,
234 {
235 use self::MinFilter::*;
236 use crate::validation::Checked::*;
237 Ok(match value as u32 {
238 NEAREST => Valid(Nearest),
239 LINEAR => Valid(Linear),
240 NEAREST_MIPMAP_NEAREST => Valid(NearestMipmapNearest),
241 LINEAR_MIPMAP_NEAREST => Valid(LinearMipmapNearest),
242 NEAREST_MIPMAP_LINEAR => Valid(NearestMipmapLinear),
243 LINEAR_MIPMAP_LINEAR => Valid(LinearMipmapLinear),
244 _ => Invalid,
245 })
246 }
247 }
248 deserializer.deserialize_u64(Visitor)
249 }
250}
251
252impl ser::Serialize for MinFilter {
253 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
254 where
255 S: ser::Serializer,
256 {
257 serializer.serialize_u32(self.as_gl_enum())
258 }
259}
260
261impl<'de> de::Deserialize<'de> for Checked<WrappingMode> {
262 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
263 where
264 D: de::Deserializer<'de>,
265 {
266 struct Visitor;
267 impl<'de> de::Visitor<'de> for Visitor {
268 type Value = Checked<WrappingMode>;
269
270 fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
271 write!(f, "any of: {:?}", VALID_WRAPPING_MODES)
272 }
273
274 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
275 where
276 E: de::Error,
277 {
278 use self::WrappingMode::*;
279 use crate::validation::Checked::*;
280 Ok(match value as u32 {
281 CLAMP_TO_EDGE => Valid(ClampToEdge),
282 MIRRORED_REPEAT => Valid(MirroredRepeat),
283 REPEAT => Valid(Repeat),
284 _ => Invalid,
285 })
286 }
287 }
288 deserializer.deserialize_u64(Visitor)
289 }
290}
291
292impl ser::Serialize for MagFilter {
293 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
294 where
295 S: ser::Serializer,
296 {
297 serializer.serialize_u32(self.as_gl_enum())
298 }
299}
300
301impl Default for WrappingMode {
302 fn default() -> Self {
303 WrappingMode::Repeat
304 }
305}
306
307impl ser::Serialize for WrappingMode {
308 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
309 where
310 S: ser::Serializer,
311 {
312 serializer.serialize_u32(self.as_gl_enum())
313 }
314}