1use std::error::Error;
2use std::fmt;
3use std::ops::{Deref, DerefMut};
4use crate::utils::range::RangeArgument;
5
6use crate::buffer::{Buffer, BufferSlice, BufferMutSlice, BufferAny, BufferType, BufferMode, BufferCreationError, Content};
7use crate::vertex::{Vertex, VerticesSource, PerInstance};
8use crate::vertex::format::VertexFormat;
9
10use crate::gl;
11use crate::GlObject;
12
13use crate::backend::Facade;
14use crate::version::{Api, Version};
15use crate::CapabilitiesSource;
16
17#[derive(Copy, Clone, Debug)]
19pub enum CreationError {
20 FormatNotSupported,
24
25 BufferCreationError(BufferCreationError),
27}
28
29impl From<BufferCreationError> for CreationError {
30 #[inline]
31 fn from(err: BufferCreationError) -> CreationError {
32 CreationError::BufferCreationError(err)
33 }
34}
35
36impl fmt::Display for CreationError {
37 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
38 use self::CreationError::*;
39 let desc = match self {
40 FormatNotSupported => "The vertex format is not supported by the backend",
41 BufferCreationError(_) => "Error while creating the vertex buffer",
42 };
43 fmt.write_str(desc)
44 }
45}
46
47impl Error for CreationError {
48 fn source(&self) -> Option<&(dyn Error + 'static)> {
49 use self::CreationError::*;
50 match *self {
51 BufferCreationError(ref error) => Some(error),
52 FormatNotSupported => None,
53 }
54 }
55}
56
57impl<T: Copy> GlObject for VertexBuffer<T> {
58 type Id = gl::types::GLuint;
59
60 #[inline]
61 fn get_id(&self) -> gl::types::GLuint {
62 self.buffer.get_id()
63 }
64}
65
66#[derive(Debug)]
68pub struct VertexBuffer<T> where T: Copy {
69 buffer: Buffer<[T]>,
70 bindings: VertexFormat,
71}
72
73pub struct VertexBufferSlice<'b, T> where T: Copy {
75 buffer: BufferSlice<'b, [T]>,
76 bindings: VertexFormat,
77}
78
79impl<'b, T: 'b> VertexBufferSlice<'b, T> where T: Copy + Content {
80 #[inline]
88 pub fn per_instance(&'b self) -> Result<PerInstance<'b>, InstancingNotSupported> {
89 if !(self.get_context().get_version() >= &Version(Api::Gl, 3, 3)) &&
91 !(self.get_context().get_version() >= &Version(Api::GlEs, 3, 0)) &&
92 !self.get_context().get_extensions().gl_arb_instanced_arrays
93 {
94 return Err(InstancingNotSupported);
95 }
96
97 Ok(PerInstance(self.buffer.as_slice_any(), self.bindings))
98 }
99}
100
101impl<T> VertexBuffer<T> where T: Vertex {
102 #[inline]
131 pub fn new<F: ?Sized>(facade: &F, data: &[T]) -> Result<VertexBuffer<T>, CreationError>
132 where F: Facade
133 {
134 VertexBuffer::new_impl(facade, data, BufferMode::Default)
135 }
136
137 #[inline]
141 pub fn dynamic<F: ?Sized>(facade: &F, data: &[T]) -> Result<VertexBuffer<T>, CreationError>
142 where F: Facade
143 {
144 VertexBuffer::new_impl(facade, data, BufferMode::Dynamic)
145 }
146
147 #[inline]
149 pub fn persistent<F: ?Sized>(facade: &F, data: &[T]) -> Result<VertexBuffer<T>, CreationError>
150 where F: Facade
151 {
152 VertexBuffer::new_impl(facade, data, BufferMode::Persistent)
153 }
154
155 #[inline]
157 pub fn immutable<F: ?Sized>(facade: &F, data: &[T]) -> Result<VertexBuffer<T>, CreationError>
158 where F: Facade
159 {
160 VertexBuffer::new_impl(facade, data, BufferMode::Immutable)
161 }
162
163 #[inline]
164 fn new_impl<F: ?Sized>(facade: &F, data: &[T], mode: BufferMode)
165 -> Result<VertexBuffer<T>, CreationError>
166 where F: Facade
167 {
168 if !T::is_supported(facade) {
169 return Err(CreationError::FormatNotSupported);
170 }
171
172 let buffer = Buffer::new(facade, data, BufferType::ArrayBuffer, mode)?;
173 Ok(buffer.into())
174 }
175
176 #[inline]
180 pub fn empty<F: ?Sized>(facade: &F, elements: usize) -> Result<VertexBuffer<T>, CreationError>
181 where F: Facade
182 {
183 VertexBuffer::empty_impl(facade, elements, BufferMode::Default)
184 }
185
186 #[inline]
190 pub fn empty_dynamic<F: ?Sized>(facade: &F, elements: usize) -> Result<VertexBuffer<T>, CreationError>
191 where F: Facade
192 {
193 VertexBuffer::empty_impl(facade, elements, BufferMode::Dynamic)
194 }
195
196 #[inline]
200 pub fn empty_persistent<F: ?Sized>(facade: &F, elements: usize)
201 -> Result<VertexBuffer<T>, CreationError>
202 where F: Facade
203 {
204 VertexBuffer::empty_impl(facade, elements, BufferMode::Persistent)
205 }
206
207 #[inline]
211 pub fn empty_immutable<F: ?Sized>(facade: &F, elements: usize) -> Result<VertexBuffer<T>, CreationError>
212 where F: Facade
213 {
214 VertexBuffer::empty_impl(facade, elements, BufferMode::Immutable)
215 }
216
217 #[inline]
218 fn empty_impl<F: ?Sized>(facade: &F, elements: usize, mode: BufferMode)
219 -> Result<VertexBuffer<T>, CreationError>
220 where F: Facade
221 {
222 if !T::is_supported(facade) {
223 return Err(CreationError::FormatNotSupported);
224 }
225
226 let buffer = Buffer::empty_array(facade, BufferType::ArrayBuffer, elements, mode)?;
227 Ok(buffer.into())
228 }
229}
230
231impl<T> VertexBuffer<T> where T: Copy {
232 #[inline]
264 pub unsafe fn new_raw<F: ?Sized>(facade: &F, data: &[T],
265 bindings: VertexFormat, elements_size: usize)
266 -> Result<VertexBuffer<T>, CreationError>
267 where F: Facade
268 {
269 Ok(VertexBuffer {
272 buffer: Buffer::new(facade, data, BufferType::ArrayBuffer,
273 BufferMode::Default)?,
274 bindings,
275 })
276 }
277
278 #[inline]
280 pub unsafe fn new_raw_dynamic<F: ?Sized>(facade: &F, data: &[T],
281 bindings: VertexFormat, elements_size: usize)
282 -> Result<VertexBuffer<T>, CreationError>
283 where F: Facade
284 {
285 Ok(VertexBuffer {
288 buffer: Buffer::new(facade, data, BufferType::ArrayBuffer,
289 BufferMode::Dynamic)?,
290 bindings,
291 })
292 }
293
294 #[inline]
298 pub fn slice<R: RangeArgument<usize>>(&self, range: R) -> Option<VertexBufferSlice<'_, T>> {
299 let slice = match self.buffer.slice(range) {
300 None => return None,
301 Some(s) => s
302 };
303
304 Some(VertexBufferSlice {
305 buffer: slice,
306 bindings: self.bindings,
307 })
308 }
309
310 #[inline]
312 pub fn get_bindings(&self) -> &VertexFormat {
313 &self.bindings
314 }
315
316 #[inline]
323 pub fn per_instance(&self) -> Result<PerInstance<'_>, InstancingNotSupported> {
324 if !(self.buffer.get_context().get_version() >= &Version(Api::Gl, 3, 3)) &&
326 !(self.get_context().get_version() >= &Version(Api::GlEs, 3, 0)) &&
327 !self.buffer.get_context().get_extensions().gl_arb_instanced_arrays
328 {
329 return Err(InstancingNotSupported);
330 }
331
332 Ok(PerInstance(self.buffer.as_slice_any(), self.bindings))
333 }
334}
335
336impl<T> VertexBuffer<T> where T: Copy + Send + 'static {
337 #[inline]
339 #[deprecated(note = "use .into() instead.")]
340 pub fn into_vertex_buffer_any(self) -> VertexBufferAny {
341 self.into_vertex_buffer_any_inner()
342 }
343 #[inline]
344 fn into_vertex_buffer_any_inner(self) -> VertexBufferAny {
345 VertexBufferAny {
346 buffer: self.buffer.into(),
347 bindings: self.bindings,
348 }
349 }
350}
351
352impl<T> From<Buffer<[T]>> for VertexBuffer<T> where T: Vertex + Copy {
353 #[inline]
354 fn from(buffer: Buffer<[T]>) -> VertexBuffer<T> {
355 assert!(T::is_supported(buffer.get_context()));
356
357 let bindings = <T as Vertex>::build_bindings();
358
359 VertexBuffer {
360 buffer,
361 bindings,
362 }
363 }
364}
365
366impl<T> Deref for VertexBuffer<T> where T: Copy {
367 type Target = Buffer<[T]>;
368
369 #[inline]
370 fn deref(&self) -> &Buffer<[T]> {
371 &self.buffer
372 }
373}
374
375impl<T> DerefMut for VertexBuffer<T> where T: Copy {
376 #[inline]
377 fn deref_mut(&mut self) -> &mut Buffer<[T]> {
378 &mut self.buffer
379 }
380}
381
382impl<'a, T> From<&'a VertexBuffer<T>> for BufferSlice<'a, [T]> where T: Copy {
383 #[inline]
384 fn from(b: &'a VertexBuffer<T>) -> BufferSlice<'a, [T]> {
385 let b: &Buffer<[T]> = &*b;
386 b.as_slice()
387 }
388}
389
390impl<'a, T> From<&'a mut VertexBuffer<T>> for BufferMutSlice<'a, [T]> where T: Copy {
391 #[inline]
392 fn from(b: &'a mut VertexBuffer<T>) -> BufferMutSlice<'a, [T]> {
393 let b: &mut Buffer<[T]> = &mut *b;
394 b.as_mut_slice()
395 }
396}
397
398impl<'a, T> From<&'a VertexBuffer<T>> for VerticesSource<'a> where T: Copy {
399 #[inline]
400 fn from(this: &VertexBuffer<T>) -> VerticesSource<'_> {
401 VerticesSource::VertexBuffer(this.buffer.as_slice_any(), this.bindings, false)
402 }
403}
404
405impl<'a, T> Deref for VertexBufferSlice<'a, T> where T: Copy {
406 type Target = BufferSlice<'a, [T]>;
407
408 #[inline]
409 fn deref(&self) -> &BufferSlice<'a, [T]> {
410 &self.buffer
411 }
412}
413
414impl<'a, T> DerefMut for VertexBufferSlice<'a, T> where T: Copy {
415 #[inline]
416 fn deref_mut(&mut self) -> &mut BufferSlice<'a, [T]> {
417 &mut self.buffer
418 }
419}
420
421impl<'a, T> From<VertexBufferSlice<'a, T>> for BufferSlice<'a, [T]> where T: Copy {
422 #[inline]
423 fn from(b: VertexBufferSlice<'a, T>) -> BufferSlice<'a, [T]> {
424 b.buffer
425 }
426}
427
428impl<'a, T> From<VertexBufferSlice<'a, T>> for VerticesSource<'a> where T: Copy {
429 #[inline]
430 fn from(this: VertexBufferSlice<'a, T>) -> VerticesSource<'a> {
431 VerticesSource::VertexBuffer(this.buffer.as_slice_any(), this.bindings, false)
432 }
433}
434
435#[derive(Debug)]
443pub struct VertexBufferAny {
444 buffer: BufferAny,
445 bindings: VertexFormat,
446}
447
448impl VertexBufferAny {
449 #[inline]
451 pub fn get_elements_size(&self) -> usize {
452 self.buffer.get_elements_size()
453 }
454
455 #[inline]
457 pub fn len(&self) -> usize {
458 self.buffer.get_elements_count()
459 }
460
461 #[inline]
463 pub fn get_bindings(&self) -> &VertexFormat {
464 &self.bindings
465 }
466
467 #[inline]
469 pub unsafe fn into_vertex_buffer<T: Copy>(self) -> VertexBuffer<T> {
470 unimplemented!();
471 }
472
473 #[inline]
480 pub fn per_instance(&self) -> Result<PerInstance<'_>, InstancingNotSupported> {
481 if !(self.buffer.get_context().get_version() >= &Version(Api::Gl, 3, 3)) &&
483 !(self.get_context().get_version() >= &Version(Api::GlEs, 3, 0)) &&
484 !self.buffer.get_context().get_extensions().gl_arb_instanced_arrays
485 {
486 return Err(InstancingNotSupported);
487 }
488
489 Ok(PerInstance(self.buffer.as_slice_any(), self.bindings))
490 }
491}
492
493impl<T> From<VertexBuffer<T>> for VertexBufferAny where T: Copy + Send + 'static {
494 #[inline]
495 fn from(buf: VertexBuffer<T>) -> VertexBufferAny {
496 buf.into_vertex_buffer_any_inner()
497 }
498}
499
500impl<T> From<Buffer<[T]>> for VertexBufferAny where T: Vertex + Copy + Send + 'static {
501 #[inline]
502 fn from(buf: Buffer<[T]>) -> VertexBufferAny {
503 let buf: VertexBuffer<T> = buf.into();
504 buf.into_vertex_buffer_any_inner()
505 }
506}
507
508impl Deref for VertexBufferAny {
509 type Target = BufferAny;
510
511 #[inline]
512 fn deref(&self) -> &BufferAny {
513 &self.buffer
514 }
515}
516
517impl DerefMut for VertexBufferAny {
518 #[inline]
519 fn deref_mut(&mut self) -> &mut BufferAny {
520 &mut self.buffer
521 }
522}
523
524impl<'a> From<&'a VertexBufferAny> for VerticesSource<'a> {
525 #[inline]
526 fn from(this :&VertexBufferAny) -> VerticesSource<'_> {
527 VerticesSource::VertexBuffer(this.buffer.as_slice_any(), this.bindings, false)
528 }
529}
530
531#[derive(Debug, Copy, Clone)]
533pub struct InstancingNotSupported;