Use the gfx vertex macro via a workaround
@@ -224,48 +224,48 @@ use glium::implement_vertex;
implement_vertex!(DrawVert, pos, uv, col);
#[cfg(feature = "gfx")]
+mod gfx_support {
+ use gfx::*;
+ use super::DrawVert;
+
+ // gfx doesn't provide a macro to implement vertex structure for an existing struct, so we
+ // create a dummy vertex with the same memory layout using gfx macros, and delegate query(name)
+ // calls later to the automatically derived implementation
+ gfx_vertex_struct! {
+ Dummy {
+ pos: [f32; 2] = "pos",
+ uv: [f32; 2] = "uv",
+ col: [format::U8Norm; 4] = "col",
+ }
+ }
unsafe impl gfx::traits::Pod for DrawVert {}
-#[cfg(feature = "gfx")]
impl gfx::pso::buffer::Structure<gfx::format::Format> for DrawVert {
fn query(name: &str) -> Option<gfx::pso::buffer::Element<gfx::format::Format>> {
- // array query hack from gfx_impl_struct_meta macro
- use gfx::format::Formatted;
- use gfx::pso::buffer::{ElemOffset, Element};
- use std::mem::{size_of, transmute};
- // using "1" here as a simple non-zero pointer addres
- let tmp: &DrawVert = unsafe { transmute(1usize) };
- let base = tmp as *const _ as usize;
- //HACK: special treatment of array queries
- let (sub_name, big_offset) = {
- let mut split = name.split(|c| c == '[' || c == ']');
- let _ = split.next().unwrap();
- match split.next() {
- Some(s) => {
- let array_id: ElemOffset = s.parse().unwrap();
- let sub_name = match split.next() {
- Some(s) if s.starts_with('.') => &s[1..],
- _ => name,
- };
- (sub_name, array_id * (size_of::<DrawVert>() as ElemOffset))
+ // Dummy has the same memory layout, so this should be ok
+ Dummy::query(name)
}
- None => (name, 0),
}
+
+ #[test]
+ fn test_dummy_memory_layout() {
+ use std::mem;
+ assert_eq!(
+ mem::size_of::<DrawVert>(),
+ mem::size_of::<Dummy>()
+ );
+ assert_eq!(
+ mem::align_of::<DrawVert>(),
+ mem::align_of::<Dummy>()
+ );
+ use memoffset::offset_of;
+ macro_rules! assert_field_offset {
+ ($l:ident, $r:ident) => {
+ assert_eq!(offset_of!(DrawVert, $l), offset_of!(Dummy, $r));
};
- match sub_name {
- "pos" => Some(Element {
- format: <[f32; 2] as Formatted>::get_format(),
- offset: ((&tmp.pos as *const _ as usize) - base) as ElemOffset + big_offset,
- }),
- "uv" => Some(Element {
- format: <[f32; 2] as Formatted>::get_format(),
- offset: ((&tmp.uv as *const _ as usize) - base) as ElemOffset + big_offset,
- }),
- "col" => Some(Element {
- format: <[gfx::format::U8Norm; 4] as Formatted>::get_format(),
- offset: ((&tmp.col as *const _ as usize) - base) as ElemOffset + big_offset,
- }),
- _ => None,
- }
+ };
+ assert_field_offset!(pos, pos);
+ assert_field_offset!(uv, uv);
+ assert_field_offset!(col, col);
}
}
