Skip to main content

mew/
vertexformat.rs

1//! Yes, these differ from [`crate::shaderprimitive`]s.
2//!
3//! Vertex buffers are packed a lot more tightly, requiring different alignment.
4//! The naming convention also follows that of
5//! [`wgpu::VertexFormat`](https://docs.rs/wgpu/latest/wgpu/enum.VertexFormat.html)
6//! rather than _wgsl_-looking types, because that's what
7//! [`wgpu::vertex_attr_array!`](https://docs.rs/wgpu/latest/wgpu/macro.vertex_attr_array.html)
8//! takes.
9//!
10//! All these types are internally represented by arrays. For example
11//! [`Float32x3`] is just a unit struct over `[f32; 3]`, but a single `[Float32]`
12//! is also an array of length 1 (`[f32; 1]`). Of course you can deref them into
13//! regular arrays, but keep in mind that's not what they directly are.
14//!
15//! ```
16//! // There shouldn't be a reason to construct these explicitly, just pass
17//! // arrays into vertex struct constructors, but for the sake of the example
18//! let mut float32_3: Float32x3 = [1.0, 2.0, 3.0].into();
19//! *float32_3 = [3.0, 2.0, 1.0];
20//! float32_3[2] = 0.0;
21//! let bytes: &[u32] = float32_3.as_ref();
22//! ```
23
24use std::ops::{ Deref, DerefMut, };
25
26
27macro_rules! vertex_format {
28    { @if_not_u8 $name:ident u8 } => {
29    };
30    { @if_not_u8 $name:ident $ty:ident } => {
31        impl From<[u8; Self::BYTES]> for $name {
32            fn from(bytes: [u8; Self::BYTES]) -> Self {
33                Self::from_bytes(bytes)
34            }
35        }
36    };
37
38    { $name:ident [ $ty:ident ; $len:literal ] } => {
39        #[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
40        //#[repr(align(1))]
41        #[repr(transparent)]
42        pub struct $name([$ty; $len]);
43
44        impl $name {
45            pub const BYTES: usize = size_of::<$ty>() * $len;
46            //const PADDING: usize = Self::BYTES.next_multiple_of($crate::wgpu::VERTEX_STRIDE_ALIGNMENT as usize) - Self::BYTES;
47        }
48
49        impl $crate::vertexformat::MewVertexFormat for $name {
50            type Bytes = [u8; Self::BYTES];
51            type Inner = [$ty; $len];
52
53            fn from_inner(inner: Self::Inner) -> Self {
54                //value.iter_mut().for_each(|val| *val = ::std::mem::transmute(val.to_le_bytes()));
55                Self(inner)
56            }
57
58            fn from_bytes(bytes: Self::Bytes) -> Self {
59                unsafe { Self(::std::mem::transmute(bytes)) }
60            }
61
62            fn zeroed() -> Self {
63                unsafe { Self(::std::mem::zeroed()) }
64            }
65        }
66
67        impl From<[$ty; $len]> for $name {
68            fn from(inner: [$ty; $len]) -> Self {
69                Self::from_inner(inner)
70            }
71        }
72        vertex_format! { @if_not_u8 $name $ty }
73
74        impl Deref for $name {
75            type Target = [$ty; $len];
76            fn deref(&self) -> &Self::Target {
77                &self.0
78            }
79        }
80        impl DerefMut for $name {
81            fn deref_mut(&mut self) -> &mut Self::Target {
82                &mut self.0
83            }
84        }
85
86        impl AsRef<[u8; Self::BYTES]> for $name {
87            fn as_ref(&self) -> &[u8; Self::BYTES] {
88                unsafe { ::std::mem::transmute(&self.0) }
89            }
90        }
91        impl AsMut<[u8; Self::BYTES]> for $name {
92            fn as_mut(&mut self) -> &mut [u8; Self::BYTES] {
93                unsafe { ::std::mem::transmute(&mut self.0) }
94            }
95        }
96
97        impl Default for $name {
98            fn default() -> Self {
99                Self::zeroed()
100            }
101        }
102    };
103}
104
105vertex_format! { Uint8 [u8; 1] }  // => 1 }
106vertex_format! { Uint8x2 [u8; 2] }  // => 2 }
107vertex_format! { Uint8x4 [u8; 4] }  // => 4 }
108vertex_format! { Sint8 [i8; 1] }  // => 1 }
109vertex_format! { Sint8x2 [i8; 2] }  // => 2 }
110vertex_format! { Sint8x4 [i8; 4] }  // => 4 }
111
112vertex_format! { Unorm8 [u8; 1] }  // => 1 }
113vertex_format! { Unorm8x2 [u8; 2] }  // => 2 }
114vertex_format! { Unorm8x4 [u8; 4] }  // => 4 }
115vertex_format! { Snorm8 [i8; 1] }  // => 1 }
116vertex_format! { Snorm8x2 [i8; 2] }  // => 2 }
117vertex_format! { Snorm8x4 [i8; 4] }  // => 4 }
118
119
120vertex_format! { Uint16 [u16; 1] }  // => 2 }
121vertex_format! { Uint16x2 [u16; 2] }  // => 4 }
122vertex_format! { Uint16x4 [u16; 4] }  // => 8 }
123vertex_format! { Sint16 [i16; 1] }  // => 2 }
124vertex_format! { Sint16x2 [i16; 2] }  // => 4 }
125vertex_format! { Sint16x4 [i16; 4] }  // => 8 }
126
127vertex_format! { Unorm16 [u16; 1] }  // => 2 }
128vertex_format! { Unorm16x2 [u16; 2] }  // => 4 }
129vertex_format! { Unorm16x4 [u16; 4] }  // => 8 }
130vertex_format! { Snorm16 [i16; 1] }  // => 2 }
131vertex_format! { Snorm16x2 [i16; 2] }  // => 4 }
132vertex_format! { Snorm16x4 [i16; 4] }  // => 8 }
133
134vertex_format! { Float16 [u16; 1] }  // => 2 }
135vertex_format! { Float16x2 [u16; 2] }  // => 4 }
136vertex_format! { Float16x4 [u16; 4] }  // => 8 }
137
138
139vertex_format! { Uint32 [u32; 1] }  // => 4 }
140vertex_format! { Uint32x2 [u32; 2] }  // => 8 }
141vertex_format! { Uint32x3 [u32; 3] }  // => 16 }
142vertex_format! { Uint32x4 [u32; 4] }  // => 16 }
143vertex_format! { Sint32 [i32; 1] }  // => 4 }
144vertex_format! { Sint32x2 [i32; 2] }  // => 8 }
145vertex_format! { Sint32x3 [i32; 3] }  // => 16 }
146vertex_format! { Sint32x4 [i32; 4] }  // => 16 }
147
148vertex_format! { Float32 [f32; 1] }  // => 4 }
149vertex_format! { Float32x2 [f32; 2] }  // => 4 }
150vertex_format! { Float32x3 [f32; 3] }  // => 8 }
151vertex_format! { Float32x4 [f32; 4] }  // => 8 }
152
153
154vertex_format! { Float64 [f64; 1] }  // => 8 }
155vertex_format! { Float64x2 [f64; 2] }  // => 16 }
156vertex_format! { Float64x3 [f64; 3] }  // => 16 }
157vertex_format! { Float64x4 [f64; 4] }  // => 16 }
158
159
160pub type Unorm10_10_10_2 = Uint32;
161pub type Unorm8x4Bgra = Unorm8x4;
162
163
164pub trait MewVertexFormat {
165    type Bytes;
166    type Inner;
167    fn from_inner(inner: Self::Inner) -> Self;
168    fn from_bytes(bytes: Self::Bytes) -> Self;
169    fn zeroed() -> Self;
170}