1#[macro_export]
2macro_rules! vertex_struct {
3 { $struct:ident [
4 $( $num:tt $field:ident => $attr:ident ),* $(,)?
5 ] } => {
6 $crate::vertex_struct! { $struct step Vertex [
7 $( $num $field => $attr , )*
8 ] }
9 };
10 { $struct:ident step $step:ident [
11 $( $num:tt $field:ident => $attr:ident ),* $(,)?
12 ] } => {
13 #[derive(Debug)]
14 #[repr(C, packed(2))]
15 pub struct $struct {
16 $( pub $field: $crate::vertexformat::$attr, )*
17 pub _padding: [u8; Self::PADDING],
18 }
19
20 impl $struct {
21 pub const SUM_SIZE: usize = {
24 #[repr(C, packed(2))]
25 struct SizeTest {
26 $( $field: $crate::vertexformat::$attr, )*
27 }
28 ::std::mem::size_of::<SizeTest>()
29 };
30 pub const BYTES: usize = Self::SUM_SIZE.next_multiple_of(4);
31 pub const PADDING: usize = Self::BYTES - Self::SUM_SIZE;
32 }
33
34 impl $crate::vertexstruct::MewVertexStruct for $struct {
35 type Bytes = [u8; Self::BYTES];
36 type Inners = ( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* );
37 type InnerRefs<'i> = ( $( &'i <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* );
38 type InnerMuts<'i> = ( $( &'i mut <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* );
39
40 fn from_inners(inners: Self::Inners) -> Self {
41 use $crate::vertexformat::MewVertexFormat;
42 Self {
43 $( $field: $crate::vertexformat::$attr::from_inner(inners.$num), )*
44 _padding: [0; Self::PADDING],
45 }
46 }
47
48 fn from_bytes(bytes: Self::Bytes) -> Self {
49 todo!()
51 }
52
53 fn zeroed() -> Self {
54 unsafe {
55 Self {
56 $( $field: ::std::mem::zeroed(), )*
57 _padding: [0; Self::PADDING],
58 }
59 }
60 }
61
62 fn get_refs(&self) -> Self::InnerRefs<'_> {
63 unsafe {
64 ( $( &*&raw const self.$field, )* )
65 }
66 }
67
68 fn get_muts(&mut self) -> Self::InnerMuts<'_> {
69 unsafe {
70 ( $( &mut *&raw mut self.$field, )* )
71 }
72 }
73
74 fn vertex_layout() -> $crate::wgpu::VertexBufferLayout<'static> {
75 static ATTRIBUTES: [$crate::wgpu::VertexAttribute; len! { $( $num )* }] = $crate::wgpu::vertex_attr_array![ $( $num => $attr , )* ];
76 $crate::wgpu::VertexBufferLayout {
77 array_stride: Self::BYTES as u64,
79 step_mode: $crate::wgpu::VertexStepMode::$step,
80 attributes: &ATTRIBUTES,
81 }
82 }
83 }
84
85
86 impl From<[u8; Self::BYTES]> for $struct {
87 fn from(bytes: [u8; Self::BYTES]) -> Self {
88 Self::from_bytes(bytes)
89 }
90 }
91 impl From<( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* )> for $struct {
92 fn from(inners: ( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* )) -> Self {
93 Self::from_inners(inners)
94 }
95 }
96
97 impl AsRef<[u8; Self::BYTES]> for $struct {
98 fn as_ref(&self) -> &[u8; Self::BYTES] {
99 unsafe { ::std::mem::transmute(self) }
100 }
101 }
102 impl AsMut<[u8; Self::BYTES]> for $struct {
103 fn as_mut(&mut self) -> &mut [u8; Self::BYTES] {
104 unsafe { ::std::mem::transmute(self) }
105 }
106 }
107
108 impl Clone for $struct {
109 fn clone(&self) -> Self {
110 unsafe {
111 Self {
112 $( $field: *&raw const self.$field, )*
113 _padding: [0; Self::PADDING],
114 }
115 }
116 }
117 }
118
119 impl Default for $struct {
120 fn default() -> Self {
121 Self::zeroed()
122 }
123 }
124 }
125}
126pub use vertex_struct;
127
128
129pub trait MewVertexStruct {
130 type Bytes;
131 type Inners;
132 type InnerRefs<'i> where Self: 'i;
133 type InnerMuts<'i> where Self: 'i;
134 fn from_inners(inners: Self::Inners) -> Self;
135 fn from_bytes(bytes: Self::Bytes) -> Self;
136 fn zeroed() -> Self;
137 fn get_refs<'i>(&'i self) -> Self::InnerRefs<'i>;
138 fn get_muts<'i>(&'i mut self) -> Self::InnerMuts<'i>;
139 fn vertex_layout() -> wgpu::VertexBufferLayout<'static>;
140}