1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
#[macro_export] macro_rules! program_cache { { $vertex:expr, $fragment:expr } => { thread_local!(static SHADER: ::std::cell::UnsafeCell<::std::collections::HashMap<usize, ::glin::Program>> = ::std::cell::UnsafeCell::new(::std::collections::HashMap::new())); pub fn get_program<'c, R: ::glin::RenderSurface>(gl: &$crate::Renderer<'c, R>) -> &'static ::glin::Program{ fn new_program<'c, R: ::glin::RenderSurface>(gl: &$crate::Renderer<'c, R>) -> ::glin::Program{ gl.new_program() .from_src_bindings(&[ (::gl::VERTEX_SHADER, shaders::VERTEX_SHADER), (::gl::FRAGMENT_SHADER, shaders::FRAGMENT_SHADER) ], &$crate::default_attribute_bindings()).unwrap() } SHADER.with(|cache| { let cache = unsafe{ &mut *cache.get() }; let program = cache .entry(gl.id()) .or_insert_with(|| new_program(gl)); unsafe{ ::std::mem::transmute(program) } }) } mod shaders{ pub static VERTEX_SHADER: &'static str = include_str!($vertex); pub static FRAGMENT_SHADER: &'static str = include_str!($fragment); } }; { $vertex:expr, $fragment:expr, $getter:ident, $shader:ident } => { thread_local!(static $shader: ::std::cell::UnsafeCell<::std::collections::HashMap<usize, ::glin::Program>> = ::std::cell::UnsafeCell::new(::std::collections::HashMap::new())); pub fn $getter<'c, R: ::glin::RenderSurface>(gl: &$crate::Renderer<'c, R>) -> &'static ::glin::Program{ static VERTEX_SHADER: &'static str = include_str!($vertex); static FRAGMENT_SHADER: &'static str = include_str!($fragment); fn new_program<'c, R: ::glin::RenderSurface>(gl: &$crate::Renderer<'c, R>) -> ::glin::Program{ gl.new_program() .from_src_bindings(&[ (::gl::VERTEX_SHADER, VERTEX_SHADER), (::gl::FRAGMENT_SHADER, FRAGMENT_SHADER) ], &$crate::default_attribute_bindings()).unwrap() } $shader.with(|cache| { let cache = unsafe{ &mut *cache.get() }; let program = cache .entry(gl.id()) .or_insert_with(|| new_program(gl)); unsafe{ ::std::mem::transmute(program) } }) } } } #[macro_export] macro_rules! geometry_cache{ {$ty: ty, $mesh: expr} => { thread_local!(static GEOMETRY: ::std::cell::UnsafeCell<::std::collections::HashMap<usize, ::glin::SimpleVao<$ty>>> = ::std::cell::UnsafeCell::new(::std::collections::HashMap::new())); pub fn get_geometry<'r, 'c, R: glin::RenderSurface>(gl: &'r $crate::Renderer<'c, R>) -> &'r mut ::glin::SimpleVao<$ty> { GEOMETRY.with(|cache|{ let cache = unsafe{ &mut *cache.get() }; let vao = cache.entry(gl.id()) .or_insert_with(|| { gl.new_simple_vao().from_data_bindings( &$mesh, &$crate::default_attribute_bindings(), $crate::STATIC_DRAW).unwrap() }); unsafe{ ::std::mem::transmute(vao) } }) } } } #[macro_export] macro_rules! geometry_cache_per_vertex_type { {} => { thread_local!(static GEOMETRY: ::std::cell::UnsafeCell<::std::collections::HashMap<(usize, ::std::any::TypeId), Box<::std::any::Any>>> = ::std::cell::UnsafeCell::new(::std::collections::HashMap::new())); pub fn get_geometry<'r, 'c, T: VertexFormat, R: $crate::offscreen_buffer::RenderSurface>(gl: &'r $crate::Renderer<'c, R>, mesh: ::graphics::Mesh<T>) -> &'r mut ::glin::SimpleVao<T> { GEOMETRY.with(|cache|{ let cache = unsafe{ &mut *cache.get() }; let vao = cache.entry((gl.id(), ::std::any::TypeId::of::<T>())) .or_insert_with(|| { gl.new_simple_vao().from_data_bindings( &$mesh, &$crate::default_attribute_bindings(), $crate::STATIC_DRAW).unwrap() }); unsafe{ ::std::mem::transmute(vao) } }) } } } #[macro_export] macro_rules! image_cache{ {$getter:ident, $cache_name: ident, $image: expr} => { thread_local!(static $cache_name: ::std::cell::UnsafeCell<::std::collections::HashMap<usize, ::glin::Texture>> = ::std::cell::UnsafeCell::new(::std::collections::HashMap::new())); pub fn $getter<'r, 'c, R: glin::RenderSurface>(gl: &'r $crate::Renderer<'c, R>) -> &'r mut ::glin::Texture { $cache_name.with(|cache|{ let cache = unsafe{ &mut *cache.get() }; let tex = cache.entry(gl.id()) .or_insert_with(|| { gl.new_texture().from_image(&$image, glin::gl::TEXTURE_2D).unwrap() }); unsafe{ ::std::mem::transmute(tex) } }) } } }