1
2use crate::prelude::*;
3use std::{
4 cmp::min,
5 ffi::c_void,
6 fmt::{self, Debug, Formatter},
7 mem::size_of,
8 rc::Rc,
9};
10
11#[derive(Clone, Copy, PartialEq)]
13pub enum BufferTarget {
14 ArrayBuffer = GL_ARRAY_BUFFER as isize,
15 AtomicCounterBuffer = GL_ATOMIC_COUNTER_BUFFER as isize,
16 CopyReadBuffer = GL_COPY_READ_BUFFER as isize,
17 CopyWriteBuffer = GL_COPY_WRITE_BUFFER as isize,
18 DispatchIndirectBuffer = GL_DISPATCH_INDIRECT_BUFFER as isize,
19 DrawIndirectBuffer = GL_DRAW_INDIRECT_BUFFER as isize,
20 ElementArrayBuffer = GL_ELEMENT_ARRAY_BUFFER as isize,
21 PixelPackBuffer = GL_PIXEL_PACK_BUFFER as isize,
22 PixelUnpackBuffer = GL_PIXEL_UNPACK_BUFFER as isize,
23 QueryBuffer = GL_QUERY_BUFFER as isize,
24 ShaderStorageBuffer = GL_SHADER_STORAGE_BUFFER as isize,
25 TextureBuffer = GL_TEXTURE_BUFFER as isize,
26 TransformFeedbackBuffer = GL_TRANSFORM_FEEDBACK_BUFFER as isize,
27 UniformBuffer = GL_UNIFORM_BUFFER as isize,
28}
29
30#[derive(Clone, Copy, PartialEq)]
32pub enum BufferUsage {
33 StreamDraw = GL_STREAM_DRAW as isize,
34 StreamRead = GL_STREAM_READ as isize,
35 StreamCopy = GL_STREAM_COPY as isize,
36 StaticDraw = GL_STATIC_DRAW as isize,
37 StaticRead = GL_STATIC_READ as isize,
38 StaticCopy = GL_STATIC_COPY as isize,
39 DynamicDraw = GL_DYNAMIC_DRAW as isize,
40 DynamicRead = GL_DYNAMIC_READ as isize,
41 DynamicCopy = GL_DYNAMIC_COPY as isize,
42}
43
44#[derive(Clone, Copy, PartialEq)]
46pub enum MapAccess {
47 ReadOnly = GL_READ_ONLY as isize,
48 WriteOnly = GL_WRITE_ONLY as isize,
49 ReadWrite = GL_READ_WRITE as isize,
50}
51
52pub struct Buffer {
54 pub glcore: Rc<GLCore>,
55 name: u32,
56 usage: BufferUsage,
57 target: BufferTarget,
58 size: usize,
59}
60
61#[derive(Debug)]
63pub struct BufferBind<'a> {
64 pub buffer: &'a Buffer,
65 target: BufferTarget,
66}
67
68#[derive(Debug)]
70pub struct BufferMapping<'a> {
71 pub buffer: &'a Buffer,
72 target: BufferTarget,
73 access: MapAccess,
74 address: *mut c_void,
75}
76
77impl Buffer {
78 pub fn get_name(&self) -> u32 {
80 self.name
81 }
82
83 pub fn new(glcore: Rc<GLCore>, target: BufferTarget, size: usize, usage: BufferUsage, data_ptr: *const c_void) -> Self {
85 let mut name: u32 = 0;
86 glcore.glGenBuffers(1, &mut name as *mut u32);
87 glcore.glBindBuffer(target as u32, name);
88 glcore.glBufferData(target as u32, size, data_ptr, usage as u32);
89 glcore.glBindBuffer(target as u32, 0);
90 Self {
91 glcore,
92 name,
93 usage,
94 target,
95 size,
96 }
97 }
98
99 pub fn size(&self) -> usize {
101 self.size
102 }
103
104 pub fn get_target(&self) -> BufferTarget {
106 self.target
107 }
108
109 pub fn get_usage(&self) -> BufferUsage {
111 self.usage
112 }
113
114 pub fn resize<T: Copy + Sized>(&mut self, new_len: usize, value: T) {
116 let new_len = min(self.size, new_len);
117 let data = vec![value; new_len / size_of::<T>()];
118 let mut name: u32 = 0;
119 self.glcore.glGenBuffers(1, &mut name as *mut u32);
120 self.glcore.glBindBuffer(BufferTarget::CopyReadBuffer as u32, self.name);
121 self.glcore.glBindBuffer(BufferTarget::CopyWriteBuffer as u32, name);
122 self.glcore.glBufferData(BufferTarget::CopyWriteBuffer as u32, new_len,
123 if new_len > self.size {
124 data.as_ptr() as *const c_void
125 } else {
126 std::ptr::null()
127 },
128 self.usage as u32);
129 self.glcore.glCopyBufferSubData(BufferTarget::CopyReadBuffer as u32, BufferTarget::CopyWriteBuffer as u32, 0, 0, new_len);
130 self.glcore.glBindBuffer(BufferTarget::CopyReadBuffer as u32, 0);
131 self.glcore.glBindBuffer(BufferTarget::CopyWriteBuffer as u32, 0);
132 self.glcore.glDeleteBuffers(1, &self.name as *const u32);
133 self.name = name;
134 }
135
136 pub fn set_target(&mut self, target: BufferTarget) {
138 self.target = target;
139 }
140
141 pub fn bind<'a>(&'a self) -> BufferBind<'a> {
143 BufferBind::new(self, self.target)
144 }
145
146 pub fn bind_to<'a>(&'a self, target: BufferTarget) -> BufferBind<'a> {
148 BufferBind::new(&*self, target)
149 }
150}
151
152impl Drop for Buffer {
153 fn drop(&mut self) {
155 self.glcore.glDeleteBuffers(1, &self.name as *const u32);
156 }
157}
158
159impl Clone for Buffer {
160 fn clone(&self) -> Self {
161 let mut name: u32 = 0;
162 self.glcore.glGenBuffers(1, &mut name as *mut u32);
163 self.glcore.glBindBuffer(self.target as u32, name);
164 self.glcore.glBindBuffer(BufferTarget::CopyReadBuffer as u32, self.name);
165 self.glcore.glBufferData(BufferTarget::CopyWriteBuffer as u32, self.size, std::ptr::null(), self.usage as u32);
166 self.glcore.glCopyBufferSubData(BufferTarget::CopyReadBuffer as u32, self.target as u32, 0, 0, self.size);
167 self.glcore.glBindBuffer(self.target as u32, 0);
168 self.glcore.glBindBuffer(BufferTarget::CopyReadBuffer as u32, 0);
169 Self {
170 glcore: self.glcore.clone(),
171 name,
172 usage: self.usage,
173 target: self.target,
174 size: self.size,
175 }
176 }
177}
178
179impl Debug for Buffer {
180 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
181 f.debug_struct("Buffer")
182 .field("name", &self.name)
183 .field("usage", &self.usage)
184 .field("target", &self.target)
185 .field("size", &self.size)
186 .finish()
187 }
188}
189
190impl<'a> BufferBind<'a> {
191 fn new(buffer: &'a Buffer, target: BufferTarget) -> Self {
193 buffer.glcore.glBindBuffer(target as u32, buffer.name);
194 Self {
195 buffer,
196 target,
197 }
198 }
199
200 pub fn unbind(self) {} pub fn map(&self, access: MapAccess) -> (BufferMapping<'a>, *mut c_void) {
205 BufferMapping::new(self.buffer, self.target, access)
206 }
207
208 pub fn map_ranged(&self, offset: usize, length: usize, access: MapAccess) -> (BufferMapping<'a>, *mut c_void) {
210 BufferMapping::new_ranged(self.buffer, self.target, offset, length, access)
211 }
212
213 pub fn get_target(&self) -> BufferTarget {
215 self.target
216 }
217}
218
219impl<'a> Drop for BufferBind<'a> {
220 fn drop(&mut self) {
222 self.buffer.glcore.glBindBuffer(self.target as u32, 0);
223 }
224}
225
226impl<'a> BufferMapping<'a> {
227 fn new(buffer: &'a Buffer, target: BufferTarget, access: MapAccess) -> (Self, *mut c_void) {
229 let address = buffer.glcore.glMapBuffer(target as u32, access as u32);
230 (Self {
231 buffer,
232 target,
233 access,
234 address,
235 }, address)
236 }
237
238 fn new_ranged(buffer: &'a Buffer, target: BufferTarget, offset: usize, length: usize, access: MapAccess) -> (Self, *mut c_void) {
240 let address = buffer.glcore.glMapBufferRange(target as u32, offset, length, access as u32);
241 (Self {
242 buffer,
243 target,
244 access,
245 address,
246 }, address)
247 }
248
249 pub fn unmap(self) {} pub fn get_target(&self) -> BufferTarget {
254 self.target
255 }
256
257 pub fn get_access(&self) -> MapAccess {
259 self.access
260 }
261
262 pub fn get_mapping_address(&self) -> *mut c_void {
264 self.address
265 }
266}
267
268impl<'a> Drop for BufferMapping<'a> {
269 fn drop(&mut self) {
271 self.buffer.glcore.glUnmapBuffer(self.target as u32);
272 }
273}
274
275impl Debug for BufferTarget {
276 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
277 match self {
278 Self::ArrayBuffer => write!(f, "ArrayBuffer"),
279 Self::AtomicCounterBuffer => write!(f, "AtomicCounterBuffer"),
280 Self::CopyReadBuffer => write!(f, "CopyReadBuffer"),
281 Self::CopyWriteBuffer => write!(f, "CopyWriteBuffer"),
282 Self::DispatchIndirectBuffer => write!(f, "DispatchIndirectBuffer"),
283 Self::DrawIndirectBuffer => write!(f, "DrawIndirectBuffer"),
284 Self::ElementArrayBuffer => write!(f, "ElementArrayBuffer"),
285 Self::PixelPackBuffer => write!(f, "PixelPackBuffer"),
286 Self::PixelUnpackBuffer => write!(f, "PixelUnpackBuffer"),
287 Self::QueryBuffer => write!(f, "QueryBuffer"),
288 Self::ShaderStorageBuffer => write!(f, "ShaderStorageBuffer"),
289 Self::TextureBuffer => write!(f, "TextureBuffer"),
290 Self::TransformFeedbackBuffer => write!(f, "TransformFeedbackBuffer"),
291 Self::UniformBuffer => write!(f, "UniformBuffer"),
292 }
293 }
294}
295
296impl Debug for BufferUsage {
297 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
298 match self {
299 Self::StreamDraw => write!(f, "StreamDraw"),
300 Self::StreamRead => write!(f, "StreamRead"),
301 Self::StreamCopy => write!(f, "StreamCopy"),
302 Self::StaticDraw => write!(f, "StaticDraw"),
303 Self::StaticRead => write!(f, "StaticRead"),
304 Self::StaticCopy => write!(f, "StaticCopy"),
305 Self::DynamicDraw => write!(f, "DynamicDraw"),
306 Self::DynamicRead => write!(f, "DynamicRead"),
307 Self::DynamicCopy => write!(f, "DynamicCopy"),
308 }
309 }
310}
311
312impl Debug for MapAccess {
313 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
314 match self {
315 Self::ReadOnly => write!(f, "StreamDraw"),
316 Self::WriteOnly => write!(f, "StreamRead"),
317 Self::ReadWrite => write!(f, "StreamCopy"),
318 }
319 }
320}