#[allow(unused_imports)]
use crate::vertexformat;
#[macro_export]
macro_rules! vertex_struct {
{ @step } => { $crate::wgpu::VertexStepMode::Vertex };
{ @step $attr:ident } => { $crate::wgpu::VertexStepMode::$attr };
{ $struct:ident $( step $step:ident )? $( + $location:literal )? [
$( $num:tt $field:ident => $attr:ident ),* $(,)?
] } => {
#[derive(Clone, Debug, PartialEq, PartialOrd)]
#[repr(C, packed(2))]
pub struct $struct {
$( pub $field: $crate::vertexformat::$attr, )*
_padding: [u8; Self::PADDING],
}
impl $struct {
const SUM_SIZE: usize = {
#[repr(C, packed(2))]
struct SizeTest {
$( $field: $crate::vertexformat::$attr, )*
}
::std::mem::size_of::<SizeTest>()
};
pub const BYTES: usize = Self::SUM_SIZE.next_multiple_of(4);
pub const PADDING: usize = Self::BYTES - Self::SUM_SIZE;
}
impl $crate::vertexstruct::MewVertexStruct for $struct {
type Bytes = [u8; Self::BYTES];
type Inners = ( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* );
fn from_inners(inners: Self::Inners) -> Self {
#[allow(unused_imports)]
use $crate::vertexformat::MewVertexFormat;
Self {
$( $field: $crate::vertexformat::$attr::from_inner(inners.$num), )*
_padding: [0; Self::PADDING],
}
}
fn from_bytes(bytes: Self::Bytes) -> Self {
unsafe { ::std::mem::transmute(bytes) }
}
fn zeroed() -> Self {
unsafe {
Self {
$( $field: ::std::mem::zeroed(), )*
_padding: [0; Self::PADDING],
}
}
}
fn vertex_layout() -> $crate::wgpu::VertexBufferLayout<'static> {
static ATTRIBUTES: [$crate::wgpu::VertexAttribute; $crate::len! { $( $num )* }] = {
#[allow(unused_mut)]
let mut attrs = $crate::wgpu::vertex_attr_array![ $( $num => $attr , )* ];
$(
let mut i = 0;
while i < attrs.len() {
attrs[i].shader_location += $location;
i += 1;
}
)?
attrs
};
$crate::wgpu::VertexBufferLayout {
array_stride: Self::BYTES as u64,
step_mode: $crate::vertex_struct! {@step $( $step )? },
attributes: &ATTRIBUTES,
}
}
}
impl From<[u8; Self::BYTES]> for $struct {
fn from(bytes: [u8; Self::BYTES]) -> Self {
use $crate::vertexstruct::MewVertexStruct;
Self::from_bytes(bytes)
}
}
impl From<( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* )> for $struct {
fn from(inners: ( $( <$crate::vertexformat::$attr as $crate::vertexformat::MewVertexFormat>::Inner , )* )) -> Self {
use $crate::vertexstruct::MewVertexStruct;
Self::from_inners(inners)
}
}
impl AsRef<[u8; Self::BYTES]> for $struct {
fn as_ref(&self) -> &[u8; Self::BYTES] {
unsafe { &*::std::ptr::from_ref(self).cast() }
}
}
impl AsMut<[u8; Self::BYTES]> for $struct {
fn as_mut(&mut self) -> &mut [u8; Self::BYTES] {
unsafe { &mut *::std::ptr::from_mut(self).cast() }
}
}
impl Default for $struct {
fn default() -> Self {
use $crate::vertexstruct::MewVertexStruct;
Self::zeroed()
}
}
}
}
pub use vertex_struct;
pub trait MewVertexStruct {
type Bytes;
type Inners;
fn from_inners(inners: Self::Inners) -> Self;
fn from_bytes(bytes: Self::Bytes) -> Self;
fn zeroed() -> Self;
fn vertex_layout() -> crate::wgpu::VertexBufferLayout<'static>;
}
pub trait MewVertexStructByteSlice {
fn as_byte_slice(&self) -> &[u8];
}
impl<S: MewVertexStruct> MewVertexStructByteSlice for [S] {
fn as_byte_slice(&self) -> &[u8] {
unsafe {
std::slice::from_raw_parts(
(&raw const *self).cast(),
size_of_val(self),
)
}
}
}