three_d/core/
buffer.rs

1//!
2//! Different types of buffers used for sending data (primarily geometry data) to the GPU.
3//!
4mod element_buffer;
5use std::marker::PhantomData;
6
7#[doc(inline)]
8pub use element_buffer::*;
9
10mod vertex_buffer;
11#[doc(inline)]
12pub use vertex_buffer::*;
13
14mod instance_buffer;
15#[doc(inline)]
16pub use instance_buffer::*;
17
18mod uniform_buffer;
19#[doc(inline)]
20pub use uniform_buffer::*;
21
22use crate::core::*;
23use data_type::*;
24
25/// The basic data type used for each element in a [VertexBuffer] or [InstanceBuffer].
26pub trait BufferDataType: DataType {}
27impl BufferDataType for u8 {}
28impl BufferDataType for u16 {}
29impl BufferDataType for u32 {}
30impl BufferDataType for i8 {}
31impl BufferDataType for i16 {}
32impl BufferDataType for i32 {}
33impl BufferDataType for f16 {}
34impl BufferDataType for f32 {}
35
36impl<T: BufferDataType + PrimitiveDataType> BufferDataType for Vector2<T> {}
37impl<T: BufferDataType + PrimitiveDataType> BufferDataType for Vector3<T> {}
38impl<T: BufferDataType + PrimitiveDataType> BufferDataType for Vector4<T> {}
39impl<T: BufferDataType + PrimitiveDataType> BufferDataType for [T; 2] {}
40impl<T: BufferDataType + PrimitiveDataType> BufferDataType for [T; 3] {}
41impl<T: BufferDataType + PrimitiveDataType> BufferDataType for [T; 4] {}
42
43impl BufferDataType for Quat {}
44
45struct Buffer<T: BufferDataType> {
46    context: Context,
47    id: crate::context::Buffer,
48    attribute_count: u32,
49    _d: PhantomData<T>,
50}
51
52impl<T: BufferDataType> Buffer<T> {
53    pub fn new(context: &Context) -> Self {
54        Self {
55            context: context.clone(),
56            id: unsafe { context.create_buffer().expect("Failed creating buffer") },
57            attribute_count: 0,
58            _d: PhantomData,
59        }
60    }
61
62    pub fn new_with_data(context: &Context, data: &[T]) -> Self {
63        let mut buffer = Self::new(context);
64        if !data.is_empty() {
65            buffer.fill(data);
66        }
67        buffer
68    }
69
70    pub fn fill(&mut self, data: &[T]) {
71        self.bind();
72        unsafe {
73            self.context.buffer_data_u8_slice(
74                crate::context::ARRAY_BUFFER,
75                to_byte_slice(data),
76                if self.attribute_count > 0 {
77                    crate::context::DYNAMIC_DRAW
78                } else {
79                    crate::context::STATIC_DRAW
80                },
81            );
82            self.context.bind_buffer(crate::context::ARRAY_BUFFER, None);
83        }
84        self.attribute_count = data.len() as u32;
85    }
86
87    pub fn fill_subset(&mut self, offset: u32, data: &[T]) {
88        self.bind();
89        unsafe {
90            self.context.buffer_sub_data_u8_slice(
91                crate::context::ARRAY_BUFFER,
92                offset as i32,
93                to_byte_slice(data),
94            );
95            self.context.bind_buffer(crate::context::ARRAY_BUFFER, None);
96        }
97        self.attribute_count = (offset as u32 + data.len() as u32).max(self.attribute_count);
98    }
99
100    pub fn attribute_count(&self) -> u32 {
101        self.attribute_count
102    }
103
104    pub fn bind(&self) {
105        unsafe {
106            self.context
107                .bind_buffer(crate::context::ARRAY_BUFFER, Some(self.id));
108        }
109    }
110}
111
112impl<T: BufferDataType> Drop for Buffer<T> {
113    fn drop(&mut self) {
114        unsafe {
115            self.context.delete_buffer(self.id);
116        }
117    }
118}