1use crate::prelude::*;
2use crate::{Context, GLContext};
3
4type BufferResource = <glow::Context as HasContext>::Buffer;
5
6use super::as_u8_mut_slice;
7use super::as_u8_slice;
8
9pub struct Buffer {
11 gl : GLContext,
12 resource : BufferResource
13}
14
15impl Buffer {
16 fn new(context:&Context) -> Self {
17 let gl = context.gl_context();
18 let resource = unsafe {
19 gl.create_buffer().expect("Couldn't create Buffer")
20 };
21 Self { gl, resource }
22 }
23
24 pub fn resource(&self) -> BufferResource {
26 self.resource
27 }
28
29 pub fn from_data<T>(context:&Context, data: &[T]) -> Self {
31 let mut buffer = Buffer::new(context);
32 buffer.set_data(data);
33 buffer
34 }
35
36 pub fn allocate(context:&Context, n_bytes:usize) -> Self {
38 let mut buffer = Buffer::new(context);
39 if n_bytes > 0 { buffer.reallocate(n_bytes); }
40 buffer
41 }
42
43 pub(crate) fn bind(&self) {
44 let resource = self.resource();
45 let resource = if resource == Default::default() { None } else { Some(resource) };
46 unsafe {
47 self.gl.bind_buffer(glow::ARRAY_BUFFER, resource);
48 }
49 }
50
51 pub fn size(&self) -> usize {
53 self.bind();
54 unsafe {
55 self.gl.get_buffer_parameter_i32(glow::ARRAY_BUFFER, glow::BUFFER_SIZE) as usize
56 }
57 }
58
59 pub fn set_data<T>(&mut self, data: &[T]) {
61 self.bind();
62 unsafe {
63 let slice = as_u8_slice(data);
64 self.gl.buffer_data_u8_slice(glow::ARRAY_BUFFER, slice, glow::STATIC_DRAW);
65 }
66 }
67
68 pub fn data<T>(&self) -> Vec<T> {
70 let size = self.size();
71 let capacity = size / std::mem::size_of::<T>();
72 let mut data : Vec<T> = Vec::with_capacity(capacity);
73 self.bind();
74 unsafe {
75 data.set_len(capacity);
76 let offset = 0;
77 let data = as_u8_mut_slice(data.as_mut());
78 self.gl.get_buffer_sub_data(glow::ARRAY_BUFFER, offset, data);
79 }
80 data
81 }
82
83 pub fn reallocate(&mut self, size: usize) {
85 self.bind();
86 unsafe {
87 self.gl.buffer_data_size(glow::ARRAY_BUFFER, size as i32, glow::STATIC_DRAW);
88 }
89 }
90}
91
92impl Drop for Buffer {
93 fn drop(&mut self) {
94 unsafe {
95 self.gl.delete_buffer(self.resource());
96 }
97 }
98}