egaku2d_core/
batch.rs

1//! Contains all batch drawing code. See the crate level documentation.
2
3use super::*;
4use core::marker::PhantomData;
5pub struct BatchCircle<T, F> {
6    buffer: vbo::GrowableBuffer<T>,
7    func: F,
8    _p: PhantomData<T>,
9    _ns: NotSend,
10}
11
12impl<T, F: Fn(&T) -> &[f32; 2]> BatchCircle<T, F> {
13    pub(crate) fn new(bots: &[T], func: F) -> BatchCircle<T, F> {
14        let mut b = BatchCircle {
15            buffer: vbo::GrowableBuffer::new(),
16            func,
17            _p: PhantomData,
18            _ns: ns(),
19        };
20        b.buffer.send_to_gpu(bots);
21        b
22    }
23
24    pub fn send_and_uniforms<'a>(
25        &'a mut self,
26        sys: &'a mut SimpleCanvas,
27        bots: &[T],
28        radius: f32,
29    ) -> Uniforms<'a> {
30        self.buffer.send_to_gpu(bots);
31
32        let stride = if bots.len() < 2 {
33            0i32
34        } else {
35            let first = (self.func)(&bots[0]);
36            let second = (self.func)(&bots[1]);
37
38            let a = first as *const _ as usize;
39            let b = second as *const _ as usize;
40
41            assert!(b > a);
42
43            let tsize = core::mem::size_of::<T>();
44            let diff = b - a;
45            assert!(diff >= tsize);
46
47            (diff) as i32
48        };
49
50        let common = UniformCommon {
51            color: sys.color,
52            offset: vec2same(0.0),
53        };
54        let un = ProgramUniformValues {
55            mode: gl::POINTS,
56            radius,
57            stride,
58            texture: None,
59        };
60
61        Uniforms {
62            sys,
63            common,
64            un: UniformVals::Circle(un),
65            buffer: self.buffer.get_info(bots.len()),
66        }
67    }
68}