1pub mod vertexprimitive {
2 use std::{
3 mem::size_of,
4 ops::{ Deref, DerefMut, },
5 };
6
7 macro_rules! primitive {
8 { $name:ident [ $innerty:ty ; $innerlen:literal ] $align:literal } => {
9 #[derive(Debug)]
10 #[repr(C)]
11 pub struct $name (
12 [u8; Self::BYTES],
13 );
15
16 impl $name {
17 const BYTE: usize = size_of::<$innerty>();
18 const BYTES: usize = Self::BYTE * $innerlen;
19 }
21 impl $crate::vertexprimitive::MewVertexPrimitive for $name {
22 type Inner = [$innerty; $innerlen];
23
24 fn new() -> Self {
25 Self (
26 [0; Self::BYTES],
27 )
29 }
30 fn from_inner(mut value: Self::Inner) -> Self {
31 unsafe {
32 value.iter_mut().for_each(|val| *val = ::std::mem::transmute(val.to_le_bytes()));
33 Self (
34 ::std::mem::transmute(value),
35 )
37 }
38 }
39
40 #[cfg(target_endian = "little")]
41 fn as_inner_ref(&self) -> &Self::Inner {
42 unsafe { ::std::mem::transmute(&self.0) }
43 }
44 #[cfg(target_endian = "little")]
45 fn as_inner_mut(&mut self) -> &mut Self::Inner {
46 unsafe { ::std::mem::transmute(&mut self.0) }
47 }
48 }
49 impl From<[u8; Self::BYTES]> for $name {
50 fn from(value: [u8; Self::BYTES]) -> Self {
51 Self (
52 value,
53 )
55 }
56 }
57 impl Default for $name {
79 fn default() -> Self {
80 Self::new()
81 }
82 }
83
84 impl AsRef<[u8]> for $name {
85 fn as_ref(&self) -> &[u8] {
86 &self.0
87 }
88 }
89 impl AsMut<[u8]> for $name {
90 fn as_mut(&mut self) -> &mut [u8] {
91 &mut self.0
92 }
93 }
94 impl Deref for $name {
95 type Target = [u8];
96 fn deref(&self) -> &Self::Target {
97 &self.0
98 }
99 }
100 impl DerefMut for $name {
101 fn deref_mut(&mut self) -> &mut Self::Target {
102 &mut self.0
103 }
104 }
105 }
106 }
107
108 primitive! { Uint8x2 [u8; 2] 2 }
109 primitive! { Uint8x4 [u8; 4] 4 }
110 primitive! { Sint8x2 [u8; 2] 2 }
111 primitive! { Sint8x4 [u8; 4] 4 }
112
113 primitive! { Unorm8x2 [u8; 2] 2 }
114 primitive! { Unorm8x4 [u8; 4] 4 }
115 primitive! { Snorm8x2 [u8; 2] 2 }
116 primitive! { Snorm8x4 [u8; 4] 4 }
117
118
119 primitive! { Uint16x2 [u16; 2] 4 }
120 primitive! { Uint16x4 [u16; 4] 8 }
121 primitive! { Sint16x2 [u16; 2] 4 }
122 primitive! { Sint16x4 [u16; 4] 8 }
123
124 primitive! { Unorm16x2 [u16; 2] 4 }
125 primitive! { Unorm16x4 [u16; 4] 8 }
126 primitive! { Snorm16x2 [u16; 2] 4 }
127 primitive! { Snorm16x4 [u16; 4] 8 }
128
129 primitive! { Float16x2 [u32; 1] 4 }
130 primitive! { Float16x4 [u64; 1] 8 }
131
132
133 primitive! { Uint32 [u32; 1] 4 }
134 primitive! { Uint32x2 [u32; 2] 8 }
135 primitive! { Uint32x3 [u32; 3] 16 }
136 primitive! { Uint32x4 [u32; 4] 16 }
137 primitive! { Sint32 [u32; 1] 4 }
138 primitive! { Sint32x2 [u32; 2] 8 }
139 primitive! { Sint32x3 [u32; 3] 16 }
140 primitive! { Sint32x4 [u32; 4] 16 }
141
142 primitive! { Float32 [f32; 1] 4 }
143 primitive! { Float32x2 [f32; 2] 8 }
144 primitive! { Float32x3 [f32; 3] 16 }
145 primitive! { Float32x4 [f32; 4] 16 }
146
147 primitive! { Unorm10_10_2 [u32; 1] 16 }
148
149
150 primitive! { Float64 [f64; 1] 8 }
151 primitive! { Float64x2 [f64; 2] 16 }
152 primitive! { Float64x3 [f64; 3] 32 }
153 primitive! { Float64x4 [f64; 4] 32 }
154
155 pub trait MewVertexPrimitive {
156 type Inner;
157 fn new() -> Self;
158 fn from_inner(inner: Self::Inner) -> Self;
159 #[cfg(target_endian = "little")]
160 fn as_inner_ref(&self) -> &Self::Inner;
161 #[cfg(target_endian = "little")]
162 fn as_inner_mut(&mut self) -> &mut Self::Inner;
163 }
164}
165pub use vertexprimitive::*;
166
167#[macro_export]
168macro_rules! vertex_struct {
169 { @len } => {
170 0
171 };
172 { @len $last:tt } => {
173 $last + 1
174 };
175 { @len $first:tt $( $rest:tt )+ } => {
176 $crate::vertex_struct!{ @len $( $rest )+ }
177 };
178
179 { $struct:ident [
180 $( $num:tt $field:ident => $attr:ident ),* $(,)?
181 ] } => {
182 $crate::vertex_struct! { $struct step Vertex [
183 $( $num $field => $attr , )*
184 ] }
185 };
186 { $struct:ident step $step:ident [
187 $( $num:tt $field:ident => $attr:ident ),* $(,)?
188 ] } => {
189 #[derive(Debug)]
190 #[repr(C)]
191 pub struct $struct {
192 $(
193 pub $field : $crate::vertexprimitive::$attr ,
194 )*
195 _padding: [u8; Self::PADDING],
196 }
197
198 impl $struct {
199 const SUM_SIZE: usize = $crate::shader_struct!{ @sum_size $( $attr )* };
200 const NEXT_MULT: usize = Self::SUM_SIZE.next_multiple_of($crate::wgpu::VERTEX_STRIDE_ALIGNMENT as usize);
201 const PADDING: usize = Self::NEXT_MULT - Self::SUM_SIZE;
202 }
203
204 impl Default for $struct {
205 fn default() -> Self {
206 Self::new()
207 }
208 }
209 impl $crate::MewVertexStruct for $struct {
210 type Inners = ( $( <$crate::vertexprimitive::$attr as $crate::vertexprimitive::MewVertexPrimitive>::Inner , )* );
211
212 fn new() -> Self {
213 Self {
214 $(
215 $field : $crate::vertexprimitive::$attr::new(),
216 )*
217 _padding: [0; Self::PADDING],
218 }
219 }
220
221 fn from_inners(inners: Self::Inners) -> Self {
222 Self {
223 $(
224 $field : $crate::vertexprimitive::$attr::from_inner(inners.$num),
225 )*
226 _padding: [0; Self::PADDING],
227 }
228 }
229
230 fn vertex_layout() -> $crate::wgpu::VertexBufferLayout<'static> {
231 static ATTRIBUTES: [$crate::wgpu::VertexAttribute; $crate::vertex_struct!{@len $( $num )* }] = $crate::wgpu::vertex_attr_array![ $( $num => $attr , )* ];
232 $crate::wgpu::VertexBufferLayout {
233 array_stride: ::std::mem::size_of::<Self>() as u64,
234 step_mode: $crate::wgpu::VertexStepMode::$step,
235 attributes: &ATTRIBUTES,
236 }
237 }
238 }
239 }
240}
241
242
243pub trait MewVertexStruct {
244 type Inners;
245
246 fn new() -> Self;
247 fn from_inners(inners: Self::Inners) -> Self;
248 fn vertex_layout() -> wgpu::VertexBufferLayout<'static>;
249}
250
251
252
253#[macro_export]
254macro_rules! shader_struct {
255 { @sum $( $size:expr ; )* } => {
256 0 $( + { $size } )*
257 };
258
259 { @size $ty:ty } => {
260 {
261 const SIZE: usize = ::std::mem::size_of::<$ty>();
262 if SIZE == 0 { 0 } else { SIZE.next_power_of_two() }
263 }
264 };
265
266 { @max } => {
267 0
268 };
269 { @max $size:expr ; } => {
270 $size
271 };
272 { @max $size:expr ; $( $rest:expr ; )+ } => {
273 {
274 const FIRST: usize = $size;
275 const REST: usize = $crate::shader_struct!{ @max $( $rest ; )+ };
276 if FIRST > REST { FIRST } else { REST }
277 }
278 };
279
280 { @sum_size $( $ty:ty )* } => {
281 $crate::shader_struct!{ @sum $( $crate::shader_struct!{ @size $ty } ; )* }
282 };
283 { @max_size $( $ty:ty )* } => {
284 $crate::shader_struct!{ @max $( $crate::shader_struct!{ @size $ty } ; )* }
285 };
286
287 { $struct:ident [
288 $( $num:tt $field:ident => $ty:ty ),* $(,)?
289 ] } => {
290 #[derive(Debug)]
291 #[repr(C)]
292 pub struct $struct {
293 $(
294 pub $field: [u8; $crate::shader_struct!{ @size $ty } ],
295 )*
296 _padding: [u8; Self::PADDING],
297 }
298
299 impl $struct {
300 const SUM_SIZE: usize = $crate::shader_struct!{ @sum_size $( $ty )* };
301 const MAX_SIZE: usize = $crate::shader_struct!{ @max_size $( $ty )* };
302 const NEXT_MULT: usize = Self::SUM_SIZE.next_multiple_of(Self::MAX_SIZE);
303 const PADDING: usize = Self::NEXT_MULT - Self::SUM_SIZE;
304 }
305
306 impl $crate::MewShaderStruct for $struct {
307 #[cfg(target_endian = "little")]
308 type InnerRefs<'a> = ( $( &'a $ty , )* );
309 #[cfg(target_endian = "little")]
310 type InnerMuts<'a> = ( $( &'a mut $ty , )* );
311
312 fn new() -> Self {
313 Self {
314 $( $field: [0; $crate::shader_struct!{ @size $ty } ], )*
315 _padding: [0; Self::PADDING],
316 }
317 }
318
319 #[cfg(target_endian = "little")]
320 fn as_refs<'a>(&'a self) -> Self::InnerRefs<'a> {
321 ( $( unsafe {
322 &*::std::mem::transmute::<*const u8, *const $ty>(&self.$field as *const u8)
323 }, )* )
324 }
325
326 #[cfg(target_endian = "little")]
327 fn as_muts<'a>(&'a mut self) -> Self::InnerMuts<'a> {
328 ( $( unsafe {
329 &mut *::std::mem::transmute::<*mut u8, *mut $ty>(&mut self.$field as *mut u8)
330 }, )* )
331 }
332 }
333 }
334}
335
336pub trait MewShaderStruct {
337 #[cfg(target_endian = "little")]
338 type InnerRefs<'a> where Self: 'a;
339 #[cfg(target_endian = "little")]
340 type InnerMuts<'a> where Self: 'a;
341 fn new() -> Self;
342 #[cfg(target_endian = "little")]
343 fn as_refs<'a>(&'a self) -> Self::InnerRefs<'a>;
344 #[cfg(target_endian = "little")]
345 fn as_muts<'a>(&'a mut self) -> Self::InnerMuts<'a>;
346}