grafix_toolbox/kit/opengl/buffer/
vao.rs1use 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}