grafix_toolbox/kit/opengl/buffer/
vao.rs

1use super::{format::*, vao_args::*, *};
2
3#[derive(Default, Debug)]
4pub struct Vao<I> {
5	o: Object<VertArrObj>,
6	d: Dummy<I>,
7}
8impl<I: IdxType> Vao<I> {
9	pub fn new() -> Self {
10		Self { o: Def(), d: Dummy }
11	}
12	pub fn obj(&self) -> u32 {
13		self.o.obj
14	}
15	pub fn Bind(&self) -> VaoBinding<I> {
16		VaoBinding::new(self)
17	}
18	pub fn BindIdxs(&mut self, o: &IdxArr<I>) {
19		GL!(glVaoElementBuffer(self.obj(), o.obj));
20		debug_assert!({
21			*Index::crossbindcheck_map().entry(self.obj()).or_default() = vec![o.obj];
22			true
23		});
24	}
25	pub fn AttribFmt<A: AttrType>(&mut self, o: &AttrArr<A>, args: impl AttrFmtArgs) {
26		let (idx, size, norm, stride, offset) = args.get();
27		ASSERT!(size > 0 && size < 5, "Attribute size({size}) isn't valid");
28		let t_size = u32(type_size::<A>());
29		GL!(glVertexAttribFormat(self.obj(), o.obj, idx, size, A::TYPE, to_glbool(norm), stride, offset, t_size));
30		debug_assert!({
31			let attrs = Attribute::crossbindcheck_map().entry(self.obj()).or_default();
32			if attrs.len() < usize(idx + 1) {
33				attrs.resize(usize(idx + 1), u32::MAX);
34			}
35			attrs[usize(idx)] = o.obj;
36			true
37		});
38	}
39}
40impl<I> Drop for Vao<I> {
41	fn drop(&mut self) {
42		debug_assert!({
43			Index::crossbindcheck_map().remove(&self.o.obj);
44			Attribute::crossbindcheck_map().remove(&self.o.obj);
45			true
46		})
47	}
48}
49
50pub struct VaoBinding<'l, I> {
51	_b: Binding<'l, VertArrObj>,
52	d: Dummy<I>,
53}
54impl<I: IdxType> VaoBinding<'_, I> {
55	pub fn new(o: &Vao<I>) -> Self {
56		let _b = Binding::new(&o.o);
57		Self { _b, d: Dummy }
58	}
59	pub fn Draw(&self, args: impl DrawArgs) {
60		Index::checkcrossbinds(VertArrObj::bound_obj());
61		Attribute::checkcrossbinds(VertArrObj::bound_obj());
62		let (num, offset, mode) = args.get();
63		GL!(gl::DrawElements(mode, num, I::TYPE, (offset * type_size::<I>()) as *const GLvoid));
64	}
65	pub fn DrawUnindexed(&self, args: impl DrawArgs) {
66		Attribute::checkcrossbinds(VertArrObj::bound_obj());
67		let (num, offset, mode) = args.get();
68		GL!(gl::DrawArrays(mode, i32(offset), num));
69	}
70	pub fn DrawInstanced<T>(&self, n: T, args: impl DrawArgs)
71	where
72		i32: Cast<T>,
73	{
74		Index::checkcrossbinds(VertArrObj::bound_obj());
75		Attribute::checkcrossbinds(VertArrObj::bound_obj());
76		let (num, offset, mode) = args.get();
77		let offset = (offset * type_size::<I>()) as *const GLvoid;
78		GL!(gl::DrawElementsInstanced(mode, num, I::TYPE, offset, i32(n)));
79	}
80}