1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
use bytemuck::{Pod, Zeroable};

use crate::bool::Bool;
use crate::glsl::Glsl;
use crate::std140::{AsStd140, Std140};

unsafe impl Std140 for f32 {
    const ALIGNMENT: usize = 4;
}

unsafe impl Std140 for f64 {
    const ALIGNMENT: usize = 8;
}

unsafe impl Std140 for i32 {
    const ALIGNMENT: usize = 4;
}

unsafe impl Std140 for u32 {
    const ALIGNMENT: usize = 4;
}

unsafe impl Std140 for Bool {
    const ALIGNMENT: usize = 4;
}

impl AsStd140 for bool {
    type Output = Bool;

    fn as_std140(&self) -> Self::Output {
        (*self).into()
    }

    fn from_std140(val: Self::Output) -> Self {
        val.into()
    }
}

macro_rules! vectors {
    (
        $(
            #[$doc:meta] align($align:literal) $glsl_name:ident $name:ident <$prim:ident> ($($field:ident),+)
        )+
    ) => {
        $(
            #[$doc]
            #[allow(missing_docs)]
            #[derive(Debug, Clone, Copy, PartialEq)]
            #[repr(C)]
            pub struct $name {
                $(pub $field: $prim,)+
            }

            unsafe impl Zeroable for $name {}
            unsafe impl Pod for $name {}

            unsafe impl Std140 for $name {
                const ALIGNMENT: usize = $align;
            }

            unsafe impl Glsl for $name {
                const NAME: &'static str = stringify!($glsl_name);
            }
        )+
    };
}

vectors! {
    #[doc = "Corresponds to a GLSL `vec2` in std140 layout."] align(8) vec2 Vec2<f32>(x, y)
    #[doc = "Corresponds to a GLSL `vec3` in std140 layout."] align(16) vec3 Vec3<f32>(x, y, z)
    #[doc = "Corresponds to a GLSL `vec4` in std140 layout."] align(16) vec4 Vec4<f32>(x, y, z, w)

    #[doc = "Corresponds to a GLSL `ivec2` in std140 layout."] align(8) ivec2 IVec2<i32>(x, y)
    #[doc = "Corresponds to a GLSL `ivec3` in std140 layout."] align(16) ivec3 IVec3<i32>(x, y, z)
    #[doc = "Corresponds to a GLSL `ivec4` in std140 layout."] align(16) ivec4 IVec4<i32>(x, y, z, w)

    #[doc = "Corresponds to a GLSL `uvec2` in std140 layout."] align(8) uvec2 UVec2<u32>(x, y)
    #[doc = "Corresponds to a GLSL `uvec3` in std140 layout."] align(16) uvec3 UVec3<u32>(x, y, z)
    #[doc = "Corresponds to a GLSL `uvec4` in std140 layout."] align(16) uvec4 UVec4<u32>(x, y, z, w)

    #[doc = "Corresponds to a GLSL `bvec2` in std140 layout."] align(8) bvec2 BVec2<Bool>(x, y)
    #[doc = "Corresponds to a GLSL `bvec3` in std140 layout."] align(16) bvec3 BVec3<Bool>(x, y, z)
    #[doc = "Corresponds to a GLSL `bvec4` in std140 layout."] align(16) bvec4 BVec4<Bool>(x, y, z, w)

    #[doc = "Corresponds to a GLSL `dvec2` in std140 layout."] align(16) dvec2 DVec2<f64>(x, y)
    #[doc = "Corresponds to a GLSL `dvec3` in std140 layout."] align(32) dvec3 DVec3<f64>(x, y, z)
    #[doc = "Corresponds to a GLSL `dvec4` in std140 layout."] align(32) dvec4 DVec4<f64>(x, y, z, w)
}

macro_rules! matrices {
    (
        $(
            #[$doc:meta]
            align($align:literal)
            $glsl_name:ident $name:ident {
                $($field:ident: $field_ty:ty,)+
            }
        )+
    ) => {
        $(
            #[$doc]
            #[allow(missing_docs)]
            #[derive(Debug, Clone, Copy)]
            #[repr(C)]
            pub struct $name {
                $(pub $field: $field_ty,)+
            }

            unsafe impl Zeroable for $name {}
            unsafe impl Pod for $name {}

            unsafe impl Std140 for $name {
                const ALIGNMENT: usize = $align;
            }

            unsafe impl Glsl for $name {
                const NAME: &'static str = stringify!($glsl_name);
            }
        )+
    };
}

matrices! {
    #[doc = "Corresponds to a GLSL `mat2` in std140 layout."]
    align(16)
    mat2 Mat2 {
        x: Vec2,
        _pad_x: [f32; 2],
        y: Vec2,
        _pad_y: [f32; 2],
    }

    #[doc = "Corresponds to a GLSL `mat3` in std140 layout."]
    align(16)
    mat3 Mat3 {
        x: Vec3,
        _pad_x: f32,
        y: Vec3,
        _pad_y: f32,
        z: Vec3,
        _pad_z: f32,
    }

    #[doc = "Corresponds to a GLSL `mat4` in std140 layout."]
    align(16)
    mat4 Mat4 {
        x: Vec4,
        y: Vec4,
        z: Vec4,
        w: Vec4,
    }

    #[doc = "Corresponds to a GLSL `dmat2` in std140 layout."]
    align(16)
    dmat2 DMat2 {
        x: DVec2,
        y: DVec2,
    }

    #[doc = "Corresponds to a GLSL `dmat3` in std140 layout."]
    align(32)
    dmat3 DMat3 {
        x: DVec3,
        _pad_x: f64,
        y: DVec3,
        _pad_y: f64,
        z: DVec3,
        _pad_z: f64,
    }

    #[doc = "Corresponds to a GLSL `dmat3` in std140 layout."]
    align(32)
    dmat4 DMat4 {
        x: DVec4,
        y: DVec4,
        z: DVec4,
        w: DVec4,
    }
}