mint_std140/
lib.rs

1#![deny(warnings)]
2#![deny(missing_docs)]
3
4//! This library contains a single trait [AsStd140] which is implemented for [mint] types that can be converted to [std140] types.
5//!
6//! # Examples
7//!
8//! ```rust
9//! use mint_std140::AsStd140;
10//!
11//! let mint_vector = mint::Vector2 { x: 0.0f32, y: 0.0f32 };
12//! let std140_vector = mint_vector.as_std140();
13//! assert_eq!(mint_vector.x, std140_vector[0]);
14//! assert_eq!(mint_vector.y, std140_vector[1]);
15//!
16//! let mint_matrix = mint::ColumnMatrix2 {
17//!     x: mint::Vector2 { x: 0.0f32, y: 1.0f32 },
18//!     y: mint::Vector2 { x: 2.0f32, y: 3.0f32 },
19//! };
20//! let std140_matrix = mint_matrix.as_std140();
21//! ```
22
23use std140::*;
24
25/// A type that can be converted to a std140 type.
26pub trait AsStd140 {
27    /// The std140 type that this type can be converted to.
28    type Std140Type;
29
30    /// Convert this type to a std140 type.
31    fn as_std140(&self) -> Self::Std140Type;
32}
33
34macro_rules! impl_as_std140_for_vector {
35    ($mint_type:ty, $std140_name:ident, [$($field:ident),+]) => {
36        impl AsStd140 for $mint_type {
37            type Std140Type = $std140_name;
38
39            fn as_std140(&self) -> Self::Std140Type {
40                $std140_name($(self.$field),+)
41            }
42        }
43    };
44}
45
46impl_as_std140_for_vector!(mint::Vector2<f32>, vec2, [x, y]);
47impl_as_std140_for_vector!(mint::Vector3<f32>, vec3, [x, y, z]);
48impl_as_std140_for_vector!(mint::Vector4<f32>, vec4, [x, y, z, w]);
49impl_as_std140_for_vector!(mint::Vector2<i32>, ivec2, [x, y]);
50impl_as_std140_for_vector!(mint::Vector3<i32>, ivec3, [x, y, z]);
51impl_as_std140_for_vector!(mint::Vector4<i32>, ivec4, [x, y, z, w]);
52impl_as_std140_for_vector!(mint::Vector2<u32>, uvec2, [x, y]);
53impl_as_std140_for_vector!(mint::Vector3<u32>, uvec3, [x, y, z]);
54impl_as_std140_for_vector!(mint::Vector4<u32>, uvec4, [x, y, z, w]);
55
56macro_rules! impl_as_std140_for_column_matrix {
57    ($mint_type:ty, $std140_name:ident, [$($field:ident),+]) => {
58        impl AsStd140 for $mint_type {
59            type Std140Type = $std140_name;
60
61            fn as_std140(&self) -> Self::Std140Type {
62                $std140_name(
63                    $(self.$field.as_std140()),+
64                )
65            }
66        }
67    };
68}
69
70impl_as_std140_for_column_matrix!(mint::ColumnMatrix2<f32>, mat2x2, [x, y]);
71impl_as_std140_for_column_matrix!(mint::ColumnMatrix3x2<f32>, mat2x3, [x, y]);
72impl_as_std140_for_column_matrix!(mint::ColumnMatrix4x2<f32>, mat2x4, [x, y]);
73impl_as_std140_for_column_matrix!(mint::ColumnMatrix2x3<f32>, mat3x2, [x, y, z]);
74impl_as_std140_for_column_matrix!(mint::ColumnMatrix3<f32>, mat3x3, [x, y, z]);
75impl_as_std140_for_column_matrix!(mint::ColumnMatrix4x3<f32>, mat3x4, [x, y, z]);
76impl_as_std140_for_column_matrix!(mint::ColumnMatrix2x4<f32>, mat4x2, [x, y, z, w]);
77impl_as_std140_for_column_matrix!(mint::ColumnMatrix3x4<f32>, mat4x3, [x, y, z, w]);
78impl_as_std140_for_column_matrix!(mint::ColumnMatrix4<f32>, mat4x4, [x, y, z, w]);
79
80#[cfg(test)]
81mod tests {
82    use super::AsStd140;
83
84    #[test]
85    fn vectors() {
86        let vector = mint::Vector2 { x: 1.0f32, y: 2.0f32 };
87        let std140_vector = vector.as_std140();
88        assert_eq!(vector.x, std140_vector[0]);
89        assert_eq!(vector.y, std140_vector[1]);
90
91        let vector = mint::Vector3 { x: 1.0f32, y: 2.0f32, z: 3.0f32 };
92        let std140_vector = vector.as_std140();
93        assert_eq!(vector.x, std140_vector[0]);
94        assert_eq!(vector.y, std140_vector[1]);
95        assert_eq!(vector.z, std140_vector[2]);
96
97        let vector = mint::Vector4 { x: 1.0f32, y: 2.0f32, z: 3.0f32, w: 4.0f32 };
98        let std140_vector = vector.as_std140();
99        assert_eq!(vector.x, std140_vector[0]);
100        assert_eq!(vector.y, std140_vector[1]);
101        assert_eq!(vector.z, std140_vector[2]);
102        assert_eq!(vector.w, std140_vector[3]);
103
104        let vector = mint::Vector2 { x: 1i32, y: 2i32 };
105        let std140_vector = vector.as_std140();
106        assert_eq!(vector.x, std140_vector[0]);
107        assert_eq!(vector.y, std140_vector[1]);
108
109        let vector = mint::Vector3 { x: 1i32, y: 2i32, z: 3i32 };
110        let std140_vector = vector.as_std140();
111        assert_eq!(vector.x, std140_vector[0]);
112        assert_eq!(vector.y, std140_vector[1]);
113        assert_eq!(vector.z, std140_vector[2]);
114
115        let vector = mint::Vector4 { x: 1i32, y: 2i32, z: 3i32, w: 4i32 };
116        let std140_vector = vector.as_std140();
117        assert_eq!(vector.x, std140_vector[0]);
118        assert_eq!(vector.y, std140_vector[1]);
119        assert_eq!(vector.z, std140_vector[2]);
120        assert_eq!(vector.w, std140_vector[3]);
121
122        let vector = mint::Vector2 { x: 1u32, y: 2u32 };
123        let std140_vector = vector.as_std140();
124        assert_eq!(vector.x, std140_vector[0]);
125        assert_eq!(vector.y, std140_vector[1]);
126
127        let vector = mint::Vector3 { x: 1u32, y: 2u32, z: 3u32 };
128        let std140_vector = vector.as_std140();
129        assert_eq!(vector.x, std140_vector[0]);
130        assert_eq!(vector.y, std140_vector[1]);
131        assert_eq!(vector.z, std140_vector[2]);
132
133        let vector = mint::Vector4 { x: 1u32, y: 2u32, z: 3u32, w: 4u32 };
134        let std140_vector = vector.as_std140();
135        assert_eq!(vector.x, std140_vector[0]);
136        assert_eq!(vector.y, std140_vector[1]);
137        assert_eq!(vector.z, std140_vector[2]);
138        assert_eq!(vector.w, std140_vector[3]);
139    }
140}