three_d/core/buffer/
element_buffer.rs1use std::marker::PhantomData;
2
3use crate::core::*;
4
5pub trait ElementBufferDataType: data_type::DataType {
7 fn as_u32(&self) -> u32;
11}
12impl ElementBufferDataType for u8 {
13 fn as_u32(&self) -> u32 {
14 *self as u32
15 }
16}
17impl ElementBufferDataType for u16 {
18 fn as_u32(&self) -> u32 {
19 *self as u32
20 }
21}
22impl ElementBufferDataType for u32 {
23 fn as_u32(&self) -> u32 {
24 *self
25 }
26}
27
28pub struct ElementBuffer<T: ElementBufferDataType> {
34 context: Context,
35 id: crate::context::Buffer,
36 count: u32,
37 _d: PhantomData<T>,
38}
39
40impl<T: ElementBufferDataType> ElementBuffer<T> {
41 pub fn new(context: &Context) -> Self {
45 let id = unsafe { context.create_buffer().expect("Failed creating buffer") };
46 Self {
47 context: context.clone(),
48 id,
49 count: 0,
50 _d: PhantomData,
51 }
52 }
53
54 pub fn new_with_data(context: &Context, data: &[T]) -> Self {
58 let mut buffer = Self::new(context);
59 if !data.is_empty() {
60 buffer.fill(data);
61 }
62 buffer
63 }
64
65 pub fn fill(&mut self, indices: &[T]) {
70 self.bind();
71 unsafe {
72 self.context.buffer_data_u8_slice(
73 crate::context::ELEMENT_ARRAY_BUFFER,
74 to_byte_slice(indices),
75 crate::context::STATIC_DRAW,
76 );
77 self.context
78 .bind_buffer(crate::context::ELEMENT_ARRAY_BUFFER, None);
79 }
80 self.count = indices.len() as u32;
81 }
82
83 pub fn fill_subset(&mut self, offset: u32, indices: &[T]) {
88 self.bind();
89 unsafe {
90 self.context.buffer_sub_data_u8_slice(
91 crate::context::ELEMENT_ARRAY_BUFFER,
92 offset as i32,
93 to_byte_slice(indices),
94 );
95 self.context
96 .bind_buffer(crate::context::ELEMENT_ARRAY_BUFFER, None);
97 }
98 self.count = (offset as u32 + indices.len() as u32).max(self.count);
99 }
100
101 pub fn count(&self) -> u32 {
105 self.count
106 }
107
108 pub fn triangle_count(&self) -> u32 {
112 self.count / 3
113 }
114
115 pub(crate) fn bind(&self) {
116 unsafe {
117 self.context
118 .bind_buffer(crate::context::ELEMENT_ARRAY_BUFFER, Some(self.id));
119 }
120 }
121}
122
123impl<T: ElementBufferDataType> Drop for ElementBuffer<T> {
124 fn drop(&mut self) {
125 unsafe {
126 self.context.delete_buffer(self.id);
127 }
128 }
129}