use std::ops::{ Deref, DerefMut, };
macro_rules! vertex_format {
{ @if_not_u8 $name:ident u8 } => {
};
{ @if_not_u8 $name:ident $ty:ident } => {
impl From<[u8; Self::BYTES]> for $name {
fn from(bytes: [u8; Self::BYTES]) -> Self {
Self::from_bytes(bytes)
}
}
};
{ $name:ident [ $ty:ident ; $len:literal ] } => {
#[derive(Clone, Copy, Debug, PartialEq, PartialOrd)]
#[repr(transparent)]
pub struct $name([$ty; $len]);
impl $name {
pub const BYTES: usize = size_of::<$ty>() * $len;
}
impl $crate::vertexformat::MewVertexFormat for $name {
type Bytes = [u8; Self::BYTES];
type Inner = [$ty; $len];
fn from_inner(inner: Self::Inner) -> Self {
Self(inner)
}
fn from_bytes(bytes: Self::Bytes) -> Self {
#[allow(clippy::useless_transmute)]
unsafe { Self(::std::mem::transmute::<[u8; Self::BYTES], [$ty; $len]>(bytes)) }
}
fn zeroed() -> Self {
unsafe { Self(::std::mem::zeroed()) }
}
}
impl From<[$ty; $len]> for $name {
fn from(inner: [$ty; $len]) -> Self {
Self::from_inner(inner)
}
}
vertex_format! { @if_not_u8 $name $ty }
impl Deref for $name {
type Target = [$ty; $len];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for $name {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
impl AsRef<[u8; Self::BYTES]> for $name {
fn as_ref(&self) -> &[u8; Self::BYTES] {
unsafe { &*(&raw const self.0).cast() }
}
}
impl AsMut<[u8; Self::BYTES]> for $name {
fn as_mut(&mut self) -> &mut [u8; Self::BYTES] {
unsafe { &mut *(&raw mut self.0).cast() }
}
}
impl Default for $name {
fn default() -> Self {
Self::zeroed()
}
}
};
}
vertex_format! { Uint8 [u8; 1] } vertex_format! { Uint8x2 [u8; 2] } vertex_format! { Uint8x4 [u8; 4] } vertex_format! { Sint8 [i8; 1] } vertex_format! { Sint8x2 [i8; 2] } vertex_format! { Sint8x4 [i8; 4] }
vertex_format! { Unorm8 [u8; 1] } vertex_format! { Unorm8x2 [u8; 2] } vertex_format! { Unorm8x4 [u8; 4] } vertex_format! { Snorm8 [i8; 1] } vertex_format! { Snorm8x2 [i8; 2] } vertex_format! { Snorm8x4 [i8; 4] }
vertex_format! { Uint16 [u16; 1] } vertex_format! { Uint16x2 [u16; 2] } vertex_format! { Uint16x4 [u16; 4] } vertex_format! { Sint16 [i16; 1] } vertex_format! { Sint16x2 [i16; 2] } vertex_format! { Sint16x4 [i16; 4] }
vertex_format! { Unorm16 [u16; 1] } vertex_format! { Unorm16x2 [u16; 2] } vertex_format! { Unorm16x4 [u16; 4] } vertex_format! { Snorm16 [i16; 1] } vertex_format! { Snorm16x2 [i16; 2] } vertex_format! { Snorm16x4 [i16; 4] }
vertex_format! { Float16 [u16; 1] } vertex_format! { Float16x2 [u16; 2] } vertex_format! { Float16x4 [u16; 4] }
vertex_format! { Uint32 [u32; 1] } vertex_format! { Uint32x2 [u32; 2] } vertex_format! { Uint32x3 [u32; 3] } vertex_format! { Uint32x4 [u32; 4] } vertex_format! { Sint32 [i32; 1] } vertex_format! { Sint32x2 [i32; 2] } vertex_format! { Sint32x3 [i32; 3] } vertex_format! { Sint32x4 [i32; 4] }
vertex_format! { Float32 [f32; 1] } vertex_format! { Float32x2 [f32; 2] } vertex_format! { Float32x3 [f32; 3] } vertex_format! { Float32x4 [f32; 4] }
vertex_format! { Float64 [f64; 1] } vertex_format! { Float64x2 [f64; 2] } vertex_format! { Float64x3 [f64; 3] } vertex_format! { Float64x4 [f64; 4] }
pub type Unorm10_10_10_2 = Uint32;
pub type Unorm8x4Bgra = Unorm8x4;
pub trait MewVertexFormat {
type Bytes;
type Inner;
fn from_inner(inner: Self::Inner) -> Self;
fn from_bytes(bytes: Self::Bytes) -> Self;
fn zeroed() -> Self;
}