1#[macro_export]
23macro_rules! vertex_struct {
24 { $struct:ident [
25 $( $num:tt $field:ident => $attr:ident ),* $(,)?
26 ] } => {
27 $crate::vertex_struct! { $struct step Vertex [
28 $( $num $field => $attr , )*
29 ] }
30 };
31 { $struct:ident step $step:ident [
32 $( $num:tt $field:ident => $attr:ident ),* $(,)?
33 ] } => {
34 #[derive(Debug)]
35 #[repr(C, packed(2))]
36 pub struct $struct {
37 $( pub $field: $crate::vertexformat::$attr, )*
38 _padding: [u8; Self::PADDING],
39 }
40
41 impl $struct {
42 pub const SUM_SIZE: usize = {
45 #[repr(C, packed(2))]
46 struct SizeTest {
47 $( $field: $crate::vertexformat::$attr, )*
48 }
49 ::std::mem::size_of::<SizeTest>()
50 };
51 pub const BYTES: usize = Self::SUM_SIZE.next_multiple_of(4);
52 pub const PADDING: usize = Self::BYTES - Self::SUM_SIZE;
53 }
54
55 impl $crate::vertexstruct::MewVertexStruct for $struct {
56 type Bytes = [u8; Self::BYTES];
57 type Inners = ( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* );
58 type InnerRefs<'i> = ( $( &'i <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* );
59 type InnerMuts<'i> = ( $( &'i mut <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* );
60
61 fn from_inners(inners: Self::Inners) -> Self {
62 #[allow(unused_imports)]
63 use $crate::vertexformat::MewVertexFormat;
64 Self {
65 $( $field: $crate::vertexformat::$attr::from_inner(inners.$num), )*
66 _padding: [0; Self::PADDING],
67 }
68 }
69
70 fn zeroed() -> Self {
78 unsafe {
79 Self {
80 $( $field: ::std::mem::zeroed(), )*
81 _padding: [0; Self::PADDING],
82 }
83 }
84 }
85
86 fn get_refs(&self) -> Self::InnerRefs<'_> {
87 unsafe {
88 ( $( &*&raw const self.$field, )* )
89 }
90 }
91
92 fn get_muts(&mut self) -> Self::InnerMuts<'_> {
93 unsafe {
94 ( $( &mut *&raw mut self.$field, )* )
95 }
96 }
97
98 fn vertex_layout() -> $crate::wgpu::VertexBufferLayout<'static> {
99 static ATTRIBUTES: [$crate::wgpu::VertexAttribute; $crate::len! { $( $num )* }] = $crate::wgpu::vertex_attr_array![ $( $num => $attr , )* ];
100 $crate::wgpu::VertexBufferLayout {
101 array_stride: Self::BYTES as u64,
103 step_mode: $crate::wgpu::VertexStepMode::$step,
104 attributes: &ATTRIBUTES,
105 }
106 }
107 }
108
109
110 impl From<( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* )> for $struct {
119 fn from(inners: ( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* )) -> Self {
120 use $crate::vertexstruct::MewVertexStruct;
121 Self::from_inners(inners)
122 }
123 }
124
125 impl AsRef<[u8; Self::BYTES]> for $struct {
126 fn as_ref(&self) -> &[u8; Self::BYTES] {
127 unsafe { ::std::mem::transmute(self) }
128 }
129 }
130 impl AsMut<[u8; Self::BYTES]> for $struct {
131 fn as_mut(&mut self) -> &mut [u8; Self::BYTES] {
132 unsafe { ::std::mem::transmute(self) }
133 }
134 }
135
136 impl Clone for $struct {
137 fn clone(&self) -> Self {
138 unsafe {
139 Self {
140 $( $field: *&raw const self.$field, )*
141 _padding: [0; Self::PADDING],
142 }
143 }
144 }
145 }
146
147 impl Default for $struct {
148 fn default() -> Self {
149 use $crate::vertexstruct::MewVertexStruct;
150 Self::zeroed()
151 }
152 }
153 }
154}
155pub use vertex_struct;
156
157
158pub trait MewVertexStruct {
159 type Bytes;
160 type Inners;
161 type InnerRefs<'i> where Self: 'i;
162 type InnerMuts<'i> where Self: 'i;
163 fn from_inners(inners: Self::Inners) -> Self;
164 fn zeroed() -> Self;
166 fn get_refs<'i>(&'i self) -> Self::InnerRefs<'i>;
167 fn get_muts<'i>(&'i mut self) -> Self::InnerMuts<'i>;
168 fn vertex_layout() -> wgpu::VertexBufferLayout<'static>;
169}