179: Add vertex_attr_array macro r=kvark a=dhardy

Specifying `VertexAttributeDescriptor` arrays is tedious, and for no good reason. This PR adds a macro to do the job.

All examples tested. Documentation is short but better than the standard for this crate I feel. 😉



Co-authored-by: Diggory Hardy <git@dhardy.name>
This commit is contained in:
bors[bot]
2020-02-20 14:38:46 +00:00
committed by GitHub
7 changed files with 96 additions and 63 deletions

View File

@@ -9,6 +9,8 @@ mod framework;
use std::fmt::Write;
use zerocopy::{AsBytes};
use wgpu::vertex_attr_array;
// number of boid particles to simulate
@@ -123,32 +125,12 @@ impl framework::Example for Example {
wgpu::VertexBufferDescriptor {
stride: 4 * 4,
step_mode: wgpu::InputStepMode::Instance,
attributes: &[
// instance position
wgpu::VertexAttributeDescriptor {
offset: 0,
format: wgpu::VertexFormat::Float2,
shader_location: 0,
},
// instance velocity
wgpu::VertexAttributeDescriptor {
offset: 2 * 4,
format: wgpu::VertexFormat::Float2,
shader_location: 1,
},
]
attributes: &vertex_attr_array![0 => Float2, 1 => Float2],
},
wgpu::VertexBufferDescriptor {
stride: 2 * 4,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &[
// vertex positions
wgpu::VertexAttributeDescriptor {
offset: 0,
format: wgpu::VertexFormat::Float2,
shader_location: 2,
},
]
attributes: &vertex_attr_array![2 => Float2],
},
],
sample_count: 1,

View File

@@ -3,6 +3,8 @@ mod framework;
use zerocopy::{AsBytes, FromBytes};
use wgpu::vertex_attr_array;
#[repr(C)]
#[derive(Clone, Copy, AsBytes, FromBytes)]
struct Vertex {
@@ -275,18 +277,7 @@ impl framework::Example for Example {
vertex_buffers: &[wgpu::VertexBufferDescriptor {
stride: vertex_size as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &[
wgpu::VertexAttributeDescriptor {
format: wgpu::VertexFormat::Float4,
offset: 0,
shader_location: 0,
},
wgpu::VertexAttributeDescriptor {
format: wgpu::VertexFormat::Float2,
offset: 4 * 4,
shader_location: 1,
},
],
attributes: &vertex_attr_array![0 => Float4, 1 => Float2],
}],
sample_count: 1,
sample_mask: !0,

View File

@@ -3,6 +3,8 @@ mod framework;
use zerocopy::{AsBytes, FromBytes};
use wgpu::vertex_attr_array;
const TEXTURE_FORMAT: wgpu::TextureFormat = wgpu::TextureFormat::Rgba8UnormSrgb;
#[repr(C)]
@@ -359,11 +361,7 @@ impl framework::Example for Example {
vertex_buffers: &[wgpu::VertexBufferDescriptor {
stride: vertex_size as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &[wgpu::VertexAttributeDescriptor {
format: wgpu::VertexFormat::Float4,
offset: 0,
shader_location: 0,
}],
attributes: &vertex_attr_array![0 => Float4],
}],
sample_count: 1,
sample_mask: !0,

View File

@@ -12,6 +12,8 @@ mod framework;
use zerocopy::{AsBytes, FromBytes};
use wgpu::vertex_attr_array;
#[repr(C)]
#[derive(Clone, Copy, AsBytes, FromBytes)]
struct Vertex {
@@ -71,18 +73,7 @@ impl Example {
vertex_buffers: &[wgpu::VertexBufferDescriptor {
stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &[
wgpu::VertexAttributeDescriptor {
format: wgpu::VertexFormat::Float2,
offset: 0,
shader_location: 0,
},
wgpu::VertexAttributeDescriptor {
format: wgpu::VertexFormat::Float4,
offset: 2 * 4,
shader_location: 1,
},
],
attributes: &vertex_attr_array![0 => Float2, 1 => Float4],
}],
sample_count,
sample_mask: !0,

View File

@@ -5,6 +5,8 @@ mod framework;
use zerocopy::{AsBytes, FromBytes};
use wgpu::vertex_attr_array;
#[repr(C)]
#[derive(Clone, Copy, AsBytes, FromBytes)]
@@ -394,18 +396,7 @@ impl framework::Example for Example {
let vb_desc = wgpu::VertexBufferDescriptor {
stride: vertex_size as wgpu::BufferAddress,
step_mode: wgpu::InputStepMode::Vertex,
attributes: &[
wgpu::VertexAttributeDescriptor {
format: wgpu::VertexFormat::Char4,
offset: 0,
shader_location: 0,
},
wgpu::VertexAttributeDescriptor {
format: wgpu::VertexFormat::Char4,
offset: 4 * 1,
shader_location: 1,
},
],
attributes: &vertex_attr_array![0 => Char4, 1 => Char4],
};
let shadow_pass = {

View File

@@ -4,6 +4,9 @@ mod future;
use future::GpuFutureCompletion;
pub use future::GpuFuture;
#[macro_use]
mod macros;
use arrayvec::ArrayVec;
use smallvec::SmallVec;

77
wgpu/src/macros.rs Normal file
View File

@@ -0,0 +1,77 @@
//! Convenience macros
/// Macro to produce an array of [`VertexAttributeDescriptor`]
///
/// Output has type: `[VertexAttributeDescriptor; _]`. Usage is as follows:
/// ```
/// # use wgpu::vertex_attr_array;
/// let attrs = vertex_attr_array![0 => Float2, 1 => Float, 2 => Ushort4];
/// ```
/// This example specifies a list of three [`VertexAttributeDescriptor`],
/// each with the given `shader_location` and `format`.
/// Offsets are calculated automatically.
#[macro_export]
macro_rules! vertex_attr_array {
($($loc:expr => $fmt:ident),*) => {
vertex_attr_array!([] ; 0; $($loc => $fmt ,)*)
};
([$($t:expr,)*] ; $off:expr ;) => { [$($t,)*] };
([$($t:expr,)*] ; $off:expr ; $loc:expr => $item:ident, $($ll:expr => $ii:ident ,)*) => {
vertex_attr_array!(
[$($t,)*
$crate::VertexAttributeDescriptor {
format: $crate::VertexFormat :: $item,
offset: $off,
shader_location: $loc,
},];
$off + $crate::vertex_format_size!($item);
$($ll => $ii ,)*
)
};
}
// For internal usage
#[macro_export]
macro_rules! vertex_format_size {
(Uchar2) => { 2 };
(Uchar4) => { 4 };
(Char2) => { 2 };
(Char4) => { 4 };
(Uchar2Norm) => { 2 };
(Uchar4Norm) => { 4 };
(Char2Norm) => { 2 };
(Char4Norm) => { 4 };
(Ushort2) => { 4 };
(Ushort4) => { 8 };
(Short2) => { 4 };
(Short4) => { 8 };
(Ushort2Norm) => { 4 };
(Ushort4Norm) => { 8 };
(Short2Norm) => { 4 };
(Short4Norm) => { 8 };
(Half2) => { 4 };
(Half4) => { 8 };
(Float) => { 4 };
(Float2) => { 8 };
(Float3) => { 12 };
(Float4) => { 16 };
(Uint) => { 4 };
(Uint2) => { 8 };
(Uint3) => { 12 };
(Uint4) => { 16 };
(Int) => { 4 };
(Int2) => { 8 };
(Int3) => { 12 };
(Int4) => { 16 };
}
#[test]
fn test_vertex_attr_array() {
let attrs = vertex_attr_array![0 => Float2, 3 => Ushort4];
// VertexAttributeDescriptor does not support PartialEq, so we cannot test directly
assert_eq!(attrs.len(), 2);
assert_eq!(attrs[0].offset, 0);
assert_eq!(attrs[0].shader_location, 0);
assert_eq!(attrs[1].offset, std::mem::size_of::<(f32, f32)>() as u64);
assert_eq!(attrs[1].shader_location, 3);
}