glium/index/
multidraw.rs

1//! Allows one to draw multiple geometry located in the same buffer.
2//!
3use std::ops::Deref;
4use std::ops::DerefMut;
5use std::os::raw;
6
7use crate::backend::Facade;
8use crate::buffer::{BufferCreationError, BufferType, BufferMode, Buffer};
9use crate::buffer::{BufferSlice, BufferMutSlice};
10use crate::index::{IndicesSource, PrimitiveType, IndexBuffer, Index};
11
12/// Represents an element in a list of draw commands.
13#[repr(C)]
14#[derive(Debug, Copy, Clone)]
15pub struct DrawCommandNoIndices {
16    /// Number of vertices to draw.
17    pub count: raw::c_uint,
18    /// Number of instances to draw. If it's `0`, nothing will be drawn.
19    pub instance_count: raw::c_uint,
20    /// First vertex to draw in the vertices source.
21    pub first_index: raw::c_uint,
22    /// Numero of the first instance to draw.
23    pub base_instance: raw::c_uint,
24}
25
26implement_uniform_block!(DrawCommandNoIndices, count, instance_count,
27                         first_index, base_instance);
28
29/// Represents an element in a list of draw commands.
30#[repr(C)]
31#[derive(Debug, Copy, Clone)]
32pub struct DrawCommandIndices {
33    /// Number of indices to use in the index buffer.
34    pub count: raw::c_uint,
35    /// Number of instances to draw. If it's `0`, nothing will be drawn.
36    pub instance_count: raw::c_uint,
37    /// First index to draw in the index buffer.
38    pub first_index: raw::c_uint,
39    /// Value to add to each index.
40    pub base_vertex: raw::c_uint,
41    /// Numero of the first instance to draw.
42    pub base_instance: raw::c_uint,
43}
44
45implement_uniform_block!(DrawCommandIndices, count, instance_count, first_index,
46                         base_vertex, base_instance);
47
48/// A buffer containing a list of draw commands.
49pub struct DrawCommandsNoIndicesBuffer {
50    buffer: Buffer<[DrawCommandNoIndices]>,
51}
52
53impl DrawCommandsNoIndicesBuffer {
54    /// Builds an empty buffer.
55    ///
56    /// The parameter indicates the number of elements.
57    #[inline]
58    pub fn empty<F: ?Sized>(facade: &F, elements: usize)
59                    -> Result<DrawCommandsNoIndicesBuffer, BufferCreationError>
60                    where F: Facade
61    {
62        let buf = Buffer::empty_array(facade, BufferType::DrawIndirectBuffer,
63                                               elements, BufferMode::Default)?;
64        Ok(DrawCommandsNoIndicesBuffer { buffer: buf })
65    }
66
67    /// Builds an empty buffer.
68    ///
69    /// The parameter indicates the number of elements.
70    #[inline]
71    pub fn empty_dynamic<F: ?Sized>(facade: &F, elements: usize)
72                            -> Result<DrawCommandsNoIndicesBuffer, BufferCreationError>
73                            where F: Facade
74    {
75        let buf = Buffer::empty_array(facade, BufferType::DrawIndirectBuffer,
76                                               elements, BufferMode::Dynamic)?;
77        Ok(DrawCommandsNoIndicesBuffer { buffer: buf })
78    }
79
80    /// Builds an empty buffer.
81    ///
82    /// The parameter indicates the number of elements.
83    #[inline]
84    pub fn empty_persistent<F: ?Sized>(facade: &F, elements: usize)
85                               -> Result<DrawCommandsNoIndicesBuffer, BufferCreationError>
86                               where F: Facade
87    {
88        let buf = Buffer::empty_array(facade, BufferType::DrawIndirectBuffer,
89                                               elements, BufferMode::Persistent)?;
90        Ok(DrawCommandsNoIndicesBuffer { buffer: buf })
91    }
92
93    /// Builds an empty buffer.
94    ///
95    /// The parameter indicates the number of elements.
96    #[inline]
97    pub fn empty_immutable<F: ?Sized>(facade: &F, elements: usize)
98                              -> Result<DrawCommandsNoIndicesBuffer, BufferCreationError>
99                              where F: Facade
100    {
101        let buf = Buffer::empty_array(facade, BufferType::DrawIndirectBuffer,
102                                               elements, BufferMode::Immutable)?;
103        Ok(DrawCommandsNoIndicesBuffer { buffer: buf })
104    }
105
106    /// Builds an indices source from this buffer and a primitives type. This indices source can
107    /// be passed to the `draw()` function.
108    #[inline]
109    pub fn with_primitive_type(&self, primitives: PrimitiveType) -> IndicesSource<'_> {
110        IndicesSource::MultidrawArray {
111            buffer: self.buffer.as_slice_any(),
112            primitives,
113        }
114    }
115}
116
117impl Deref for DrawCommandsNoIndicesBuffer {
118    type Target = Buffer<[DrawCommandNoIndices]>;
119
120    #[inline]
121    fn deref(&self) -> &Buffer<[DrawCommandNoIndices]> {
122        &self.buffer
123    }
124}
125
126impl DerefMut for DrawCommandsNoIndicesBuffer {
127    #[inline]
128    fn deref_mut(&mut self) -> &mut Buffer<[DrawCommandNoIndices]> {
129        &mut self.buffer
130    }
131}
132
133impl<'a> From<&'a DrawCommandsNoIndicesBuffer> for BufferSlice<'a, [DrawCommandNoIndices]> {
134    #[inline]
135    fn from(b: &'a DrawCommandsNoIndicesBuffer) -> BufferSlice<'a, [DrawCommandNoIndices]> {
136        let b: &Buffer<[DrawCommandNoIndices]> = &*b;
137        b.as_slice()
138    }
139}
140
141impl<'a> From<&'a mut DrawCommandsNoIndicesBuffer> for BufferMutSlice<'a, [DrawCommandNoIndices]> {
142    #[inline]
143    fn from(b: &'a mut DrawCommandsNoIndicesBuffer) -> BufferMutSlice<'a, [DrawCommandNoIndices]> {
144        let b: &mut Buffer<[DrawCommandNoIndices]> = &mut *b;
145        b.as_mut_slice()
146    }
147}
148
149/// A buffer containing a list of draw commands.
150pub struct DrawCommandsIndicesBuffer {
151    buffer: Buffer<[DrawCommandIndices]>,
152}
153
154impl DrawCommandsIndicesBuffer {
155    /// Builds an empty buffer.
156    ///
157    /// The parameter indicates the number of elements.
158    #[inline]
159    pub fn empty<F: ?Sized>(facade: &F, elements: usize)
160                    -> Result<DrawCommandsIndicesBuffer, BufferCreationError>
161                    where F: Facade
162    {
163        let buf = Buffer::empty_array(facade, BufferType::DrawIndirectBuffer,
164                                               elements, BufferMode::Default)?;
165        Ok(DrawCommandsIndicesBuffer { buffer: buf })
166    }
167
168    /// Builds an empty buffer.
169    ///
170    /// The parameter indicates the number of elements.
171    #[inline]
172    pub fn empty_dynamic<F: ?Sized>(facade: &F, elements: usize)
173                            -> Result<DrawCommandsIndicesBuffer, BufferCreationError>
174                            where F: Facade
175    {
176        let buf = Buffer::empty_array(facade, BufferType::DrawIndirectBuffer,
177                                               elements, BufferMode::Dynamic)?;
178        Ok(DrawCommandsIndicesBuffer { buffer: buf })
179    }
180
181    /// Builds an empty buffer.
182    ///
183    /// The parameter indicates the number of elements.
184    #[inline]
185    pub fn empty_persistent<F: ?Sized>(facade: &F, elements: usize)
186                               -> Result<DrawCommandsIndicesBuffer, BufferCreationError>
187                               where F: Facade
188    {
189        let buf = Buffer::empty_array(facade, BufferType::DrawIndirectBuffer,
190                                               elements, BufferMode::Persistent)?;
191        Ok(DrawCommandsIndicesBuffer { buffer: buf })
192    }
193
194    /// Builds an empty buffer.
195    ///
196    /// The parameter indicates the number of elements.
197    #[inline]
198    pub fn empty_immutable<F: ?Sized>(facade: &F, elements: usize)
199                              -> Result<DrawCommandsIndicesBuffer, BufferCreationError>
200                              where F: Facade
201    {
202        let buf = Buffer::empty_array(facade, BufferType::DrawIndirectBuffer,
203                                               elements, BufferMode::Immutable)?;
204        Ok(DrawCommandsIndicesBuffer { buffer: buf })
205    }
206
207    /// Builds an indices source from this buffer and a primitives type. This indices source can
208    /// be passed to the `draw()` function.
209    #[inline]
210    pub fn with_index_buffer<'a, T>(&'a self, index_buffer: &'a IndexBuffer<T>)
211                                    -> IndicesSource<'a> where T: Index
212    {
213        IndicesSource::MultidrawElement {
214            commands: self.buffer.as_slice_any(),
215            indices: index_buffer.as_slice_any(),
216            data_type: index_buffer.get_indices_type(),
217            primitives: index_buffer.get_primitives_type(),
218        }
219    }
220}
221
222impl Deref for DrawCommandsIndicesBuffer {
223    type Target = Buffer<[DrawCommandIndices]>;
224
225    #[inline]
226    fn deref(&self) -> &Buffer<[DrawCommandIndices]> {
227        &self.buffer
228    }
229}
230
231impl DerefMut for DrawCommandsIndicesBuffer {
232    #[inline]
233    fn deref_mut(&mut self) -> &mut Buffer<[DrawCommandIndices]> {
234        &mut self.buffer
235    }
236}
237
238impl<'a> From<&'a DrawCommandsIndicesBuffer> for BufferSlice<'a, [DrawCommandIndices]> {
239    #[inline]
240    fn from(b: &'a DrawCommandsIndicesBuffer) -> BufferSlice<'a, [DrawCommandIndices]> {
241        let b: &Buffer<[DrawCommandIndices]> = &*b;
242        b.as_slice()
243    }
244}
245
246impl<'a> From<&'a mut DrawCommandsIndicesBuffer> for BufferMutSlice<'a, [DrawCommandIndices]> {
247    #[inline]
248    fn from(b: &'a mut DrawCommandsIndicesBuffer) -> BufferMutSlice<'a, [DrawCommandIndices]> {
249        let b: &mut Buffer<[DrawCommandIndices]> = &mut *b;
250        b.as_mut_slice()
251    }
252}