#[macro_export]
macro_rules! gfx_vertex {
($name:ident {
$($gl_name:ident@ $field:ident: $ty:ty,)*
}) => {
#[derive(Clone, Debug)]
pub struct $name {
$(pub $field: $ty,)*
}
impl $crate::VertexFormat for $name {
fn generate<R: $crate::Resources>(buffer: &$crate::handle::Buffer<R, $name>)
-> Vec<$crate::Attribute<R>> {
use std::mem::size_of;
use $crate::attrib::{Offset, Stride};
use $crate::attrib::format::ToFormat;
let stride = size_of::<$name>() as Stride;
let mut offset = 0 as Offset;
let mut attributes = Vec::new();
$(
let (count, etype) = <$ty as ToFormat>::describe();
let format = $crate::attrib::Format {
elem_count: count,
elem_type: etype,
offset: offset,
stride: stride,
instance_rate: 0,
};
attributes.push($crate::Attribute {
name: stringify!($gl_name).to_string(),
format: format,
buffer: buffer.raw().clone(),
});
offset += size_of::<$ty>() as Offset;
)*
assert_eq!(offset, stride as Offset);
attributes
}
}
}
}
#[macro_export]
macro_rules! gfx_parameters {
($name:ident/$link_name:ident {
$($gl_name:ident@ $field:ident: $ty:ty,)*
}) => {
#[derive(Clone, Debug)]
pub struct $name<R: $crate::Resources> {
$(pub $field: $ty,)*
pub _r: ::std::marker::PhantomData<R>,
}
#[derive(Clone, Debug)]
pub struct $link_name {
$($field: Option<$crate::shade::ParameterId>,)*
}
impl<R: $crate::Resources> $crate::shade::ShaderParam for $name<R> {
type Resources = R;
type Link = $link_name;
fn create_link(_: Option<&$name<R>>, info: &$crate::ProgramInfo)
-> Result<$link_name, $crate::shade::ParameterError> {
use $crate::shade::Parameter;
let mut link = $link_name{
$( $field: None, )*
};
for (i, u) in info.uniforms.iter().enumerate() {
match &u.name[..] {
$(
stringify!($gl_name) => {
if !<$ty as Parameter<R>>::check_uniform(u) {
return Err($crate::shade::ParameterError::BadUniform(u.name.clone()))
}
link.$field = Some(i as $crate::shade::ParameterId);
},
)*
_ => return Err($crate::shade::ParameterError::MissingUniform(u.name.clone()))
}
}
for (i, b) in info.blocks.iter().enumerate() {
match &b.name[..] {
$(
stringify!($gl_name) => {
if !<$ty as Parameter<R>>::check_block(b) {
return Err($crate::shade::ParameterError::BadBlock(b.name.clone()))
}
link.$field = Some(i as $crate::shade::ParameterId);
},
)*
_ => return Err($crate::shade::ParameterError::MissingBlock(b.name.clone()))
}
}
for (i, t) in info.textures.iter().enumerate() {
match &t.name[..] {
$(
stringify!($gl_name) => {
if !<$ty as Parameter<R>>::check_texture(t) {
return Err($crate::shade::ParameterError::BadBlock(t.name.clone()))
}
link.$field = Some(i as $crate::shade::ParameterId);
},
)*
_ => return Err($crate::shade::ParameterError::MissingBlock(t.name.clone()))
}
}
Ok(link)
}
fn fill_params(&self, link: &$link_name, storage: &mut $crate::ParamStorage<R>) {
use $crate::shade::Parameter;
$(
if let Some(id) = link.$field {
self.$field.put(id, storage);
}
)*
}
}
}
}
#[cfg(test)]
gfx_vertex!(_Foo {
x@ _x: i8,
y@ _y: f32,
z@ _z: [u32; 4],
});
gfx_parameters!(_Bar/BarLink {
x@ _x: i32,
y@ _y: [f32; 4],
b@ _b: ::handle::RawBuffer<R>,
t@ _t: ::shade::TextureParam<R>,
});
#[test]
fn test() {}