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