1use crate::buffer::{Buffer, BufferSlice, BufferMutSlice, BufferAny, BufferType};
2use crate::buffer::{BufferMode, BufferCreationError};
3use crate::gl;
4use crate::GlObject;
5
6use crate::backend::Facade;
7
8use crate::index::IndicesSource;
9use crate::index::Index;
10use crate::index::IndexType;
11use crate::index::PrimitiveType;
12
13use std::ops::{Deref, DerefMut};
14use std::fmt;
15use std::error::Error;
16use crate::utils::range::RangeArgument;
17
18#[derive(Debug, Copy, Clone)]
20pub enum CreationError {
21 IndexTypeNotSupported,
23
24 PrimitiveTypeNotSupported,
26
27 BufferCreationError(BufferCreationError),
29}
30
31impl fmt::Display for CreationError {
32 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
33 use self::CreationError::*;
34 let desc = match *self {
35 IndexTypeNotSupported =>
36 "The type of index is not supported by the backend",
37 PrimitiveTypeNotSupported =>
38 "The type of primitives is not supported by the backend",
39 BufferCreationError(_) =>
40 "An error happened while creating the buffer",
41 };
42 fmt.write_str(desc)
43 }
44}
45
46impl Error for CreationError {
47 fn source(&self) -> Option<&(dyn Error + 'static)> {
48 use self::CreationError::*;
49 match *self {
50 BufferCreationError(ref err) => Some(err),
51 _ => None,
52 }
53 }
54}
55
56impl From<BufferCreationError> for CreationError {
57 #[inline]
58 fn from(err: BufferCreationError) -> CreationError {
59 CreationError::BufferCreationError(err)
60 }
61}
62
63#[derive(Debug)]
65pub struct IndexBuffer<T> where T: Index {
66 buffer: Buffer<[T]>,
67 primitives: PrimitiveType,
68}
69
70impl<T> IndexBuffer<T> where T: Index {
71 #[inline]
73 pub fn new<F: ?Sized>(facade: &F, prim: PrimitiveType, data: &[T])
74 -> Result<IndexBuffer<T>, CreationError>
75 where F: Facade
76 {
77 IndexBuffer::new_impl(facade, prim, data, BufferMode::Default)
78 }
79
80 #[inline]
82 pub fn dynamic<F: ?Sized>(facade: &F, prim: PrimitiveType, data: &[T])
83 -> Result<IndexBuffer<T>, CreationError>
84 where F: Facade
85 {
86 IndexBuffer::new_impl(facade, prim, data, BufferMode::Dynamic)
87 }
88
89 #[inline]
91 pub fn persistent<F: ?Sized>(facade: &F, prim: PrimitiveType, data: &[T])
92 -> Result<IndexBuffer<T>, CreationError>
93 where F: Facade
94 {
95 IndexBuffer::new_impl(facade, prim, data, BufferMode::Persistent)
96 }
97
98 #[inline]
100 pub fn immutable<F: ?Sized>(facade: &F, prim: PrimitiveType, data: &[T])
101 -> Result<IndexBuffer<T>, CreationError>
102 where F: Facade
103 {
104 IndexBuffer::new_impl(facade, prim, data, BufferMode::Immutable)
105 }
106
107 #[inline]
108 fn new_impl<F: ?Sized>(facade: &F, prim: PrimitiveType, data: &[T], mode: BufferMode)
109 -> Result<IndexBuffer<T>, CreationError>
110 where F: Facade
111 {
112 if !prim.is_supported(facade) {
113 return Err(CreationError::PrimitiveTypeNotSupported);
114 }
115
116 if !T::is_supported(facade) {
117 return Err(CreationError::IndexTypeNotSupported);
118 }
119
120 Ok(IndexBuffer {
121 buffer: Buffer::new(facade, data, BufferType::ElementArrayBuffer, mode)?,
122 primitives: prim,
123 })
124 }
125
126 #[inline]
128 pub fn empty<F: ?Sized>(facade: &F, prim: PrimitiveType, len: usize)
129 -> Result<IndexBuffer<T>, CreationError>
130 where F: Facade
131 {
132 IndexBuffer::empty_impl(facade, prim, len, BufferMode::Default)
133 }
134
135 #[inline]
137 pub fn empty_dynamic<F: ?Sized>(facade: &F, prim: PrimitiveType, len: usize)
138 -> Result<IndexBuffer<T>, CreationError>
139 where F: Facade
140 {
141 IndexBuffer::empty_impl(facade, prim, len, BufferMode::Dynamic)
142 }
143
144 #[inline]
146 pub fn empty_persistent<F: ?Sized>(facade: &F, prim: PrimitiveType, len: usize)
147 -> Result<IndexBuffer<T>, CreationError>
148 where F: Facade
149 {
150 IndexBuffer::empty_impl(facade, prim, len, BufferMode::Persistent)
151 }
152
153 #[inline]
155 pub fn empty_immutable<F: ?Sized>(facade: &F, prim: PrimitiveType, len: usize)
156 -> Result<IndexBuffer<T>, CreationError>
157 where F: Facade
158 {
159 IndexBuffer::empty_impl(facade, prim, len, BufferMode::Immutable)
160 }
161
162 #[inline]
163 fn empty_impl<F: ?Sized>(facade: &F, prim: PrimitiveType, len: usize, mode: BufferMode)
164 -> Result<IndexBuffer<T>, CreationError>
165 where F: Facade
166 {
167 if !prim.is_supported(facade) {
168 return Err(CreationError::PrimitiveTypeNotSupported);
169 }
170
171 if !T::is_supported(facade) {
172 return Err(CreationError::IndexTypeNotSupported);
173 }
174
175 Ok(IndexBuffer {
176 buffer: Buffer::empty_array(facade, BufferType::ElementArrayBuffer, len,
177 mode)?,
178 primitives: prim,
179 })
180 }
181
182 #[inline]
184 pub fn get_primitives_type(&self) -> PrimitiveType {
185 self.primitives
186 }
187
188 #[inline]
190 pub fn get_indices_type(&self) -> IndexType {
191 <T as Index>::get_type()
192 }
193
194 #[inline]
196 pub fn slice<R: RangeArgument<usize>>(&self, range: R) -> Option<IndexBufferSlice<'_, T>> {
197 self.buffer.slice(range).map(|b| {
198 IndexBufferSlice {
199 buffer: b,
200 primitives: self.primitives,
201 }
202 })
203 }
204}
205
206impl<T> Deref for IndexBuffer<T> where T: Index {
207 type Target = Buffer<[T]>;
208
209 #[inline]
210 fn deref(&self) -> &Buffer<[T]> {
211 &self.buffer
212 }
213}
214
215impl<T> DerefMut for IndexBuffer<T> where T: Index {
216 #[inline]
217 fn deref_mut(&mut self) -> &mut Buffer<[T]> {
218 &mut self.buffer
219 }
220}
221
222impl<'a, T> From<&'a IndexBuffer<T>> for BufferSlice<'a, [T]> where T: Index {
223 #[inline]
224 fn from(b: &'a IndexBuffer<T>) -> BufferSlice<'a, [T]> {
225 let b: &Buffer<[T]> = &*b;
226 b.as_slice()
227 }
228}
229
230impl<'a, T> From<&'a mut IndexBuffer<T>> for BufferMutSlice<'a, [T]> where T: Index {
231 #[inline]
232 fn from(b: &'a mut IndexBuffer<T>) -> BufferMutSlice<'a, [T]> {
233 let b: &mut Buffer<[T]> = &mut *b;
234 b.as_mut_slice()
235 }
236}
237
238impl<T> GlObject for IndexBuffer<T> where T: Index {
240 type Id = gl::types::GLuint;
241
242 #[inline]
243 fn get_id(&self) -> gl::types::GLuint {
244 self.buffer.get_id()
245 }
246}
247
248impl<'a, T> From<&'a IndexBuffer<T>> for IndicesSource<'a> where T: Index {
249 #[inline]
250 fn from(buf: &'a IndexBuffer<T>) -> IndicesSource<'a> {
251 IndicesSource::IndexBuffer {
252 buffer: buf.buffer.as_slice_any(),
253 data_type: buf.get_indices_type(),
254 primitives: buf.primitives,
255 }
256 }
257}
258
259#[derive(Debug)]
261pub struct IndexBufferSlice<'a, T> where T: Index {
262 buffer: BufferSlice<'a, [T]>,
263 primitives: PrimitiveType,
264}
265
266impl<'a, T: 'a> IndexBufferSlice<'a, T> where T: Index {
267 #[inline]
269 pub fn get_primitives_type(&self) -> PrimitiveType {
270 self.primitives
271 }
272
273 #[inline]
275 pub fn get_indices_type(&self) -> IndexType {
276 <T as Index>::get_type()
277 }
278
279 #[inline]
281 pub fn slice<R: RangeArgument<usize>>(&self, range: R) -> Option<IndexBufferSlice<'a, T>> {
282 self.buffer.slice(range).map(|b| {
283 IndexBufferSlice {
284 buffer: b,
285 primitives: self.primitives,
286 }
287 })
288 }
289}
290
291impl<'a, T> Deref for IndexBufferSlice<'a, T> where T: Index {
292 type Target = BufferSlice<'a, [T]>;
293
294 #[inline]
295 fn deref(&self) -> &BufferSlice<'a, [T]> {
296 &self.buffer
297 }
298}
299
300impl<'a, T> DerefMut for IndexBufferSlice<'a, T> where T: Index {
301 #[inline]
302 fn deref_mut(&mut self) -> &mut BufferSlice<'a, [T]> {
303 &mut self.buffer
304 }
305}
306
307impl<'a, T> From<IndexBufferSlice<'a, T>> for BufferSlice<'a, [T]> where T: Index {
308 #[inline]
309 fn from(b: IndexBufferSlice<'a, T>) -> BufferSlice<'a, [T]> {
310 b.buffer
311 }
312}
313
314impl<'a, T> From<IndexBufferSlice<'a, T>> for IndicesSource<'a> where T: Index {
315 #[inline]
316 fn from(buf: IndexBufferSlice<'a, T>) -> IndicesSource<'a> {
317 IndicesSource::IndexBuffer {
318 buffer: buf.buffer.as_slice_any(),
319 data_type: buf.get_indices_type(),
320 primitives: buf.primitives,
321 }
322 }
323}
324
325impl<'a, 'r, T> From<&'r IndexBufferSlice<'a, T>> for IndicesSource<'a> where T: Index {
326 #[inline]
327 fn from(buf: &'r IndexBufferSlice<'a, T>) -> IndicesSource<'a> {
328 IndicesSource::IndexBuffer {
329 buffer: buf.buffer.as_slice_any(),
330 data_type: buf.get_indices_type(),
331 primitives: buf.primitives,
332 }
333 }
334}
335
336#[derive(Debug)]
340pub struct IndexBufferAny {
341 buffer: BufferAny,
342 primitives: PrimitiveType,
343 data_type: IndexType,
344}
345
346impl IndexBufferAny {
347 #[inline]
349 pub fn get_primitives_type(&self) -> PrimitiveType {
350 self.primitives
351 }
352
353 #[inline]
355 pub fn get_indices_type(&self) -> IndexType {
356 self.data_type
357 }
358}
359
360impl Deref for IndexBufferAny {
361 type Target = BufferAny;
362
363 #[inline]
364 fn deref(&self) -> &BufferAny {
365 &self.buffer
366 }
367}
368
369impl DerefMut for IndexBufferAny {
370 #[inline]
371 fn deref_mut(&mut self) -> &mut BufferAny {
372 &mut self.buffer
373 }
374}
375
376impl<T> From<IndexBuffer<T>> for IndexBufferAny where T: Index {
377 #[inline]
378 fn from(buffer: IndexBuffer<T>) -> IndexBufferAny {
379 let ty = buffer.get_indices_type();
380
381 IndexBufferAny {
382 buffer: buffer.buffer.into(),
383 data_type: ty,
384 primitives: buffer.primitives,
385 }
386 }
387}
388
389impl<'a> From<&'a IndexBufferAny> for IndicesSource<'a> {
390 #[inline]
391 fn from(buf: &'a IndexBufferAny) -> IndicesSource<'a> {
392 IndicesSource::IndexBuffer {
393 buffer: buf.buffer.as_slice_any(),
394 data_type: buf.data_type,
395 primitives: buf.primitives,
396 }
397 }
398}