gls/
buffer.rs

1use crate::{gl, prelude::*, GLboolean, GLenum, GLint, GLsizei, GLsizeiptr, GLuint};
2
3#[derive(Clone, Default, Debug)]
4pub struct Buffer {
5    buffer_type: GLuint,
6    vbo: GLuint,
7}
8
9impl Buffer {
10    pub fn new_array() -> Buffer {
11        Self::new(gl::ARRAY_BUFFER)
12    }
13
14    pub fn new_element_array() -> Buffer {
15        Self::new(gl::ELEMENT_ARRAY_BUFFER)
16    }
17
18    pub fn new_draw_indirect() -> Buffer {
19        Self::new(gl::DRAW_INDIRECT_BUFFER)
20    }
21
22    pub fn new(buffer_type: GLuint) -> Buffer {
23        let vbo = crate::new_buffer();
24        crate::bind_buffer(buffer_type, vbo);
25        Buffer { buffer_type, vbo }
26    }
27
28    pub fn static_draw_data<T>(&self, data: &[T])
29    where
30        T: Sized,
31    {
32        crate::buffer_data(
33            self.buffer_type, // target
34            -1,               // size of data in bytes
35            Some(data),       // pointer to data
36            gl::STATIC_DRAW,  // usage
37        );
38    }
39
40    pub fn stream_draw_data<T>(&self, data: &[T])
41    where
42        T: Sized,
43    {
44        crate::buffer_data(
45            self.buffer_type, // target
46            -1,               // size of data in bytes
47            Some(data),       // pointer to data
48            gl::STREAM_DRAW,  // usage
49        );
50    }
51
52    pub fn stream_draw_data_null<T>(&self, size: usize)
53    where
54        T: Sized,
55    {
56        crate::buffer_data::<T>(
57            self.buffer_type,                                // target
58            (size * std::mem::size_of::<T>()) as GLsizeiptr, // size of data in bytes
59            None,                                            // pointer to data
60            gl::STREAM_DRAW,                                 // usage
61        );
62    }
63
64    #[cfg(feature = "gl4")]
65    pub unsafe fn map_buffer_range_write_invalidate<'r, T>(
66        &self,
67        offset: usize,
68        size: usize,
69    ) -> Option<MappedBuffer<'r, T>>
70    where
71        T: Sized,
72    {
73        let ptr = crate::map_buffer_range(
74            self.buffer_type,                                  // target
75            (offset * std::mem::size_of::<T>()) as GLsizeiptr, // offset
76            (size * std::mem::size_of::<T>()) as GLsizeiptr,   //  length
77            gl::MAP_WRITE_BIT | gl::MAP_INVALIDATE_RANGE_BIT,  // usage
78        );
79        if ptr == ::std::ptr::null_mut() {
80            return None;
81        }
82        return Some(MappedBuffer {
83            buffer_type: self.buffer_type,
84            data: ::std::slice::from_raw_parts_mut(ptr as *mut T, size),
85            position: 0,
86        });
87    }
88
89    pub fn update<T>(&self, data: &[T])
90    where
91        T: Sized,
92    {
93        crate::buffer_sub_data(
94            self.buffer_type, // target
95            0,                // offset into the buffer
96            data,             // pointer to data
97        );
98    }
99
100    pub fn update_partial<T>(&self, offset: isize, data: &[T])
101    where
102        T: Sized,
103    {
104        crate::buffer_sub_data(
105            self.buffer_type, // target
106            offset,           // offset into the buffer
107            data,             // pointer to data
108        );
109    }
110}
111
112impl Drop for Buffer {
113    fn drop(&mut self) {
114        crate::delete_buffers(&[self.vbo]);
115    }
116}
117
118impl Bindable for Buffer {
119    fn bind(&self) {
120        crate::bind_buffer(self.buffer_type, self.vbo);
121    }
122
123    fn unbind(&self) {
124        crate::bind_buffer(self.buffer_type, 0);
125    }
126}
127
128#[cfg(feature = "gl4")]
129pub struct MappedBuffer<'a, DataT: 'a> {
130    buffer_type: GLuint,
131    data: &'a mut [DataT],
132    position: usize,
133}
134
135#[cfg(feature = "gl4")]
136impl<'a, DataT: 'a> MappedBuffer<'a, DataT> {
137    pub fn clear(&mut self) {
138        self.position = 0;
139    }
140
141    pub fn push(&mut self, data: DataT) {
142        if self.position < self.data.len() {
143            *unsafe { self.data.get_unchecked_mut(self.position) } = data;
144            self.position += 1;
145        }
146    }
147}
148
149#[cfg(feature = "gl4")]
150impl<'a, DataT: 'a> ::std::ops::Deref for MappedBuffer<'a, DataT> {
151    type Target = [DataT];
152
153    fn deref(&self) -> &Self::Target {
154        self.data
155    }
156}
157
158#[cfg(feature = "gl4")]
159impl<'a, DataT: 'a> ::std::ops::DerefMut for MappedBuffer<'a, DataT> {
160    fn deref_mut(&mut self) -> &mut Self::Target {
161        self.data
162    }
163}
164
165#[cfg(feature = "gl4")]
166impl<'a, DataT: 'a> Drop for MappedBuffer<'a, DataT> {
167    fn drop(&mut self) {
168        crate::unmap_buffer(self.buffer_type);
169    }
170}
171
172#[derive(Clone, Copy, Debug)]
173pub struct VertexAttrib {
174    location: GLuint,
175    components: GLint,
176    data_type: GLenum,
177    normalized: GLboolean,
178    stride: GLsizei,
179    offset: GLsizeiptr,
180}
181
182impl VertexAttrib {
183    pub fn new(
184        location: GLuint,
185        components: GLint,
186        data_type: GLenum,
187        normalized: GLboolean,
188        stride: GLsizei,
189        offset: GLsizeiptr,
190    ) -> Self {
191        Self {
192            location,
193            components,
194            data_type,
195            normalized,
196            stride,
197            offset,
198        }
199    }
200}
201
202impl Bindable for VertexAttrib {
203    fn bind(&self) {
204        crate::enable_vertex_attrib_array(self.location);
205        crate::vertex_attrib_pointer(
206            self.location,
207            self.components,
208            self.data_type,
209            self.normalized,
210            self.stride,
211            self.offset,
212        );
213    }
214    fn unbind(&self) {
215        crate::disable_vertex_attrib_array(self.location);
216    }
217}
218
219#[derive(Clone, Default, Debug)]
220pub struct VertexArray {
221    vao: GLuint,
222}
223
224impl VertexArray {
225    pub fn new() -> VertexArray {
226        VertexArray {
227            vao: crate::new_vertex_array(),
228        }
229    }
230
231    pub fn enable_attrib(&self, attr: &VertexAttrib) {
232        crate::enable_vertex_attrib_array(attr.location);
233        crate::vertex_attrib_pointer(
234            attr.location,
235            attr.components,
236            attr.data_type,
237            attr.normalized,
238            attr.stride,
239            attr.offset,
240        );
241    }
242
243    pub fn disable_attrib(self, attr: &VertexAttrib) {
244        crate::disable_vertex_attrib_array(attr.location);
245    }
246}
247
248impl Drop for VertexArray {
249    fn drop(&mut self) {
250        crate::delete_vertex_arrays(&[self.vao]);
251    }
252}
253
254impl Bindable for VertexArray {
255    fn bind(&self) {
256        crate::bind_vertex_array(self.vao);
257    }
258
259    fn unbind(&self) {
260        crate::bind_vertex_array(0);
261    }
262}