Skip to content

Commit

Permalink
Managed to make the derive macro work not required const ATTRIBUTES def.
Browse files Browse the repository at this point in the history
  • Loading branch information
joaoccmartins committed Oct 11, 2024
1 parent f1c819c commit e4ac6c9
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 10 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ resolver = "2"
members = [
"crates/rusteroids",
"crates/wgpu_utils",
"crates/wgpu_utils/internals",
"crates/wgpu_utils/vertex_attribute_derive",
]
8 changes: 2 additions & 6 deletions crates/rusteroids/src/mesh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ use std::ops::Range;

use glam::Mat4;
use wgpu::util::DeviceExt;
use wgpu::{Queue, RenderPass, VertexAttribute};
use wgpu_utils::VertexAttributeArray;
use wgpu::{Queue, RenderPass};
use wgpu_utils::{format_of, VertexAttributeArray};

use crate::utils::{common_layout_descriptor, Bindable, UniformBuffer};
#[repr(C)]
Expand All @@ -13,10 +13,6 @@ pub struct Vertex {
pub color: [f32; 3],
}

impl Vertex {
const ATTR: [VertexAttribute; 2] = wgpu::vertex_attr_array![0 => Float32x2, 1 => Float32x3];
}

pub struct Geometry {
vertex_buffer: Option<wgpu::Buffer>,
model_uniform: Option<UniformBuffer>,
Expand Down
3 changes: 2 additions & 1 deletion crates/wgpu_utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ edition = "2021"

[dependencies]
vertex_attribute_derive = { path = "vertex_attribute_derive" }
wgpu = "22.0"
wgpu = "22.0"
internals = { path = "internals"}
7 changes: 7 additions & 0 deletions crates/wgpu_utils/internals/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[package]
name = "internals"
version = "0.1.0"
edition = "2021"

[dependencies]
wgpu = "22.0"
39 changes: 39 additions & 0 deletions crates/wgpu_utils/internals/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
pub trait ConstFormat {
const FORMAT: wgpu::VertexFormat;
}

pub const fn format_of<T: ConstFormat>() -> wgpu::VertexFormat {
T::FORMAT
}
/// Defines the default VertexFormat of a particular type.
/// By defining it using
/// ``````
/// const_format_of!(MyVec3 => VertexFormat::Float32x3)
/// ```
///
/// You can then use its format with the following call
/// ```
/// let vertex_format: wgpu::VertexFormat = format_of::<MyVec3>();
/// ```
///
/// And use this in conjunction with VertexAttributeArray macro
/// ```
/// #[derive(VertexAttributeArray)]
/// struct MyVertexBuffer{
/// pos: MyVec3,
/// }
macro_rules! const_format_of {
($T:ty => $format:expr) => {
impl ConstFormat for $T {
const FORMAT: wgpu::VertexFormat = $format;
}
};
}

const_format_of!(f32 => wgpu::VertexFormat::Float32);
const_format_of!([f32; 2] => wgpu::VertexFormat::Float32x2);
const_format_of!([f32; 3] => wgpu::VertexFormat::Float32x3);
const_format_of!([f32; 4] => wgpu::VertexFormat::Float32x4);
const_format_of!(u32 => wgpu::VertexFormat::Uint32);
const_format_of!([u32; 2] => wgpu::VertexFormat::Uint32x2);
const_format_of!([u32; 3] => wgpu::VertexFormat::Uint32x3);
1 change: 1 addition & 0 deletions crates/wgpu_utils/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub use internals::format_of;
pub use vertex_attribute_derive::VertexAttributeArray;

pub trait VertexAttributeArray {
Expand Down
3 changes: 2 additions & 1 deletion crates/wgpu_utils/vertex_attribute_derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ proc-macro = true
[dependencies]
quote = "1.0.37"
syn = "2.0.79"
wgpu = "22.0"
wgpu = "22.0"
internals = { path = "../internals" }
34 changes: 32 additions & 2 deletions crates/wgpu_utils/vertex_attribute_derive/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use internals::format_of;
use proc_macro::TokenStream;
use quote::quote;

use syn::{Data, Fields};
/// Ensures the struct is capable of generating a VertexBufferLayout
/// by calling desc. Requires the existing of a ```const ATTR: [wgpu::VertexAttribute; N]```
///
Expand Down Expand Up @@ -30,13 +31,42 @@ pub fn vertex_attribute_derive(input: TokenStream) -> TokenStream {

fn impl_vertex_attribute(ast: &syn::DeriveInput) -> TokenStream {
let name = &ast.ident;
let fields = match &ast.data {
Data::Struct(data) => {
if let Fields::Named(named_fields) = &data.fields {
named_fields.named.clone()
} else {
panic!("#[derive(VertexAttributeArray)] is only supported on structs with named fields");
}
}
// TODO: Add enums
_ => panic!("#[derive(VertexAttributeArray)] is only supported on structs"),
};

// Generate the vertex attributes
let field_types = fields.iter().enumerate().map(|(i, f)| {
let ty = &f.ty;
quote! {
wgpu::VertexAttribute {
format: format_of::<#ty>(),
offset: size_of::<#ty>() as u64,
shader_location: #i as u32,
}
}
});

let attrs_array_len = field_types.len();

let gen = quote! {
impl VertexAttributeArray for #name {
fn desc() -> wgpu::VertexBufferLayout<'static> {
static attr: [wgpu::VertexAttribute; #attrs_array_len] = [
#(#field_types),*
];
wgpu::VertexBufferLayout {
array_stride: std::mem::size_of::<Self>() as wgpu::BufferAddress,
step_mode: wgpu::VertexStepMode::Vertex,
attributes: &Self::ATTR,
attributes: &attr,
}
}
}
Expand Down

0 comments on commit e4ac6c9

Please sign in to comment.