shine_gltf/
texture.rs

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
8/// Corresponds to `GL_NEAREST`.
9pub const NEAREST: u32 = 9728;
10
11/// Corresponds to `GL_LINEAR`.
12pub const LINEAR: u32 = 9729;
13
14/// Corresponds to `GL_NEAREST_MIPMAP_NEAREST`.
15pub const NEAREST_MIPMAP_NEAREST: u32 = 9984;
16
17/// Corresponds to `GL_LINEAR_MIPMAP_NEAREST`.
18pub const LINEAR_MIPMAP_NEAREST: u32 = 9985;
19
20/// Corresponds to `GL_NEAREST_MIPMAP_LINEAR`.
21pub const NEAREST_MIPMAP_LINEAR: u32 = 9986;
22
23/// Corresponds to `GL_LINEAR_MIPMAP_LINEAR`.
24pub const LINEAR_MIPMAP_LINEAR: u32 = 9987;
25
26/// Corresponds to `GL_CLAMP_TO_EDGE`.
27pub const CLAMP_TO_EDGE: u32 = 33_071;
28
29/// Corresponds to `GL_MIRRORED_REPEAT`.
30pub const MIRRORED_REPEAT: u32 = 33_648;
31
32/// Corresponds to `GL_REPEAT`.
33pub const REPEAT: u32 = 10_497;
34
35/// All valid magnification filters.
36pub const VALID_MAG_FILTERS: &[u32] = &[NEAREST, LINEAR];
37
38/// All valid minification filters.
39pub 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
48/// All valid wrapping modes.
49pub const VALID_WRAPPING_MODES: &[u32] = &[CLAMP_TO_EDGE, MIRRORED_REPEAT, REPEAT];
50
51/// Magnification filter.
52#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
53pub enum MagFilter {
54    /// Corresponds to `GL_NEAREST`.
55    Nearest = 1,
56
57    /// Corresponds to `GL_LINEAR`.
58    Linear,
59}
60
61impl MagFilter {
62    /// OpenGL enum
63    pub fn as_gl_enum(self) -> u32 {
64        match self {
65            MagFilter::Nearest => NEAREST,
66            MagFilter::Linear => LINEAR,
67        }
68    }
69}
70
71/// Minification filter.
72#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
73pub enum MinFilter {
74    /// Corresponds to `GL_NEAREST`.
75    Nearest = 1,
76
77    /// Corresponds to `GL_LINEAR`.
78    Linear,
79
80    /// Corresponds to `GL_NEAREST_MIPMAP_NEAREST`.
81    NearestMipmapNearest,
82
83    /// Corresponds to `GL_LINEAR_MIPMAP_NEAREST`.
84    LinearMipmapNearest,
85
86    /// Corresponds to `GL_NEAREST_MIPMAP_LINEAR`.
87    NearestMipmapLinear,
88
89    /// Corresponds to `GL_LINEAR_MIPMAP_LINEAR`.
90    LinearMipmapLinear,
91}
92
93impl MinFilter {
94    /// Returns the corresponding OpenGL enum value.
95    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/// Texture co-ordinate wrapping mode.
108#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq)]
109pub enum WrappingMode {
110    /// Corresponds to `GL_CLAMP_TO_EDGE`.
111    ClampToEdge = 1,
112
113    /// Corresponds to `GL_MIRRORED_REPEAT`.
114    MirroredRepeat,
115
116    /// Corresponds to `GL_REPEAT`.
117    Repeat,
118}
119
120impl WrappingMode {
121    /// Returns the corresponding OpenGL enum value.
122    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/// Texture sampler properties for filtering and wrapping modes.
132#[derive(Clone, Debug, Default, Deserialize, Serialize, Validate)]
133#[serde(default)]
134pub struct Sampler {
135    /// Magnification filter.
136    #[serde(rename = "magFilter")]
137    #[serde(skip_serializing_if = "Option::is_none")]
138    pub mag_filter: Option<Checked<MagFilter>>,
139
140    /// Minification filter.
141    #[serde(rename = "minFilter")]
142    #[serde(skip_serializing_if = "Option::is_none")]
143    pub min_filter: Option<Checked<MinFilter>>,
144
145    /// `s` wrapping mode.
146    #[serde(default, rename = "wrapS")]
147    pub wrap_s: Checked<WrappingMode>,
148
149    /// `t` wrapping mode.
150    #[serde(default, rename = "wrapT")]
151    pub wrap_t: Checked<WrappingMode>,
152
153    /// Extension specific data.
154    #[serde(default, skip_serializing_if = "Option::is_none")]
155    pub extensions: Option<extensions::texture::Sampler>,
156}
157
158/// A texture and its sampler.
159#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
160pub struct Texture {
161    /// The index of the sampler used by this texture.
162    #[serde(skip_serializing_if = "Option::is_none")]
163    pub sampler: Option<Index<Sampler>>,
164
165    /// The index of the image used by this texture.
166    pub source: Index<image::Image>,
167
168    /// Extension specific data.
169    #[serde(default, skip_serializing_if = "Option::is_none")]
170    pub extensions: Option<extensions::texture::Texture>,
171}
172
173#[derive(Clone, Debug, Deserialize, Serialize, Validate)]
174/// Reference to a `Texture`.
175pub struct Info {
176    /// The index of the texture.
177    pub index: Index<Texture>,
178
179    /// The set index of the texture's `TEXCOORD` attribute.
180    #[serde(default, rename = "texCoord")]
181    pub tex_coord: u32,
182
183    /// Extension specific data.
184    #[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}