use super::*; use GL::spec::*; pub trait AnyMesh { fn Draw(&self); fn to_trait(self) -> Box; } impl AnyMesh for Mesh { fn Draw(&self) { self.vao.Bind().Draw(self.draw); } fn to_trait(self) -> Box { Box(self) } } pub struct Mesh { pub vao: Vao, pub buff: (IdxArr, AttrArr, Option>, AttrArr), pub draw: (u32, GLenum), } impl Mesh { pub fn new(args: impl MeshArgs) -> Self { let (idx, xyz, uv, norm, mode) = args.get(); let draw = (u32(idx.len()), mode); let idx = IdxArr::new(idx); let xyz = AttrArr::new(xyz); let norm = AttrArr::new(norm); let mut vao = Vao::new(); vao.BindIdxs(&idx); let uv = uv.map(|uv| { let uv = AttrArr::new(uv); vao.AttribFmt(&uv, (1, 2)); uv }); vao.AttribFmt(&xyz, (0, 3)); vao.AttribFmt(&norm, (2, 3)); let buff = (idx, xyz, uv, norm); Self { vao, buff, draw } } } type MArgs<'s, I, C, T, N> = (&'s [I], &'s [C], Option<&'s [T]>, &'s [N], GLenum); pub trait MeshArgs { fn get(&self) -> MArgs<'_, I, C, T, N>; } impl, SC: AsRef<[C]>, ST: AsRef<[T]>, SN: AsRef<[N]>> MeshArgs for (SI, SC, ST, SN, GLenum) { fn get(&self) -> MArgs<'_, I, C, T, N> { (self.0.as_ref(), self.1.as_ref(), Some(self.2.as_ref()), self.3.as_ref(), self.4) } } impl, SC: AsRef<[C]>, SN: AsRef<[N]>> MeshArgs for (SI, SC, SN, GLenum) { fn get(&self) -> MArgs<'_, I, C, f16, N> { (self.0.as_ref(), self.1.as_ref(), None, self.2.as_ref(), self.3) } }