webgl_rc/
element_buffer.rs

1use crate::settings::Settings;
2use crate::{BufferUsage, Gl, GlError};
3use std::cell::Cell;
4use std::rc::Rc;
5use web_sys::{WebGlBuffer, WebGlRenderingContext};
6
7#[derive(Debug, Clone)]
8pub struct ElementBufferData {
9    pub(self) gl: Gl,
10    pub(self) handle: WebGlBuffer,
11    pub(self) length: Cell<usize>,
12}
13
14impl Drop for ElementBufferData {
15    fn drop(&mut self) {
16        self.gl.context().delete_buffer(Some(&self.handle));
17    }
18}
19
20#[derive(Debug, Clone)]
21pub struct ElementsBuffer {
22    pub(self) data: Rc<ElementBufferData>,
23}
24
25impl PartialEq<ElementsBuffer> for ElementsBuffer {
26    fn eq(&self, other: &ElementsBuffer) -> bool {
27        self.data.handle == other.data.handle
28    }
29}
30
31impl Eq for ElementsBuffer {}
32
33impl ElementsBuffer {
34    pub fn new(gl: Gl, data: &[u32], usage: BufferUsage) -> Result<ElementsBuffer, GlError> {
35        let ref context: &WebGlRenderingContext = gl.context();
36        let buffer = context
37            .create_buffer()
38            .ok_or(GlError::BufferAllocationError)?;
39
40        let result = ElementsBuffer {
41            data: Rc::new(ElementBufferData {
42                gl: gl.clone(),
43                handle: buffer,
44                length: Default::default(),
45            }),
46        };
47
48        result.set_content(data, usage);
49
50        return Ok(result);
51    }
52
53    pub(crate) fn handle(&self) -> WebGlBuffer {
54        self.data.handle.clone()
55    }
56
57    pub fn set_content(&self, data: &[u32], usage: BufferUsage) {
58        self.data
59            .gl
60            .apply(Gl::settings().element_buffer(self.clone()), || {
61                let bytes = unsafe {
62                    std::slice::from_raw_parts(data.as_ptr() as *const u8, data.len() * 4)
63                };
64                self.data.gl.context().buffer_data_with_u8_array(
65                    WebGlRenderingContext::ELEMENT_ARRAY_BUFFER,
66                    &bytes,
67                    usage.into(),
68                );
69            });
70
71        self.data.length.set(data.len());
72    }
73
74    pub fn len(&self) -> usize {
75        self.data.length.get()
76    }
77}