luminance/
tess.rs

1//! Vertex sets.
2//!
3//! [`Tess`] is a type that represents the gathering of vertices and the way to connect / link
4//! them. A [`Tess`] has several intrinsic properties:
5//!
6//! - Its _primitive mode_ — [`Mode`]. That object tells the GPU how to connect the vertices.
7//! - A default number of vertex to render. When passing the [`Tess`] to the GPU for rendering,
8//!   it’s possible to specify the number of vertices to render or just let the [`Tess`] render
9//!   a default number of vertices (typically, the whole [`Tess`]).
10//! - A default number of _instances_, which allows for geometry instancing. Geometry instancing
11//!   is the fact of drawing with the same [`Tess`] several times, only changing the
12//!   instance index every time a new render is performed. This is done entirely on the backend to
13//!   prevent bandwidth exhaustion. The index of the instance, in the shader stages, is often used
14//!   to pick material properties, matrices, etc. to customize each instances. Instances can manually
15//!   be asked when using a [`TessView`].
16//! - An indexed configuration, allowing to tell the GPU how to render the vertices by referring to
17//!   them via indices.
18//! - For indexed configuration, an optional _primitive restart index_ can be specified. That
19//!   index, when present in the indexed set, will make some primitive modes _“restart”_ and create
20//!   new primitives. More on this on the documentation of [`Mode`].
21//!
22//! # Tessellation creation
23//!
24//! [`Tess`] is not created directly. Instead, you need to use a [`TessBuilder`]. Tessellation
25//! builders make it easy to customize what a [`Tess`] will be made of before actually requesting
26//! the GPU to create them. They support a large number of possible situations:
27//!
28//! - _Attributeless_: when you only specify the [`Mode`] and number of vertices to render (and
29//!   optionally the number of instances). That will create a vertex set with no vertex data. Your
30//!   vertex shader will be responsible for creating the vertex attributes on the fly.
31//! - _Direct geometry_: when you pass vertices directly.
32//! - _Indexed geometry_: when you pass vertices and reference from with indices.
33//! - _Instanced geometry_: when you ask to use instances, making the graphics pipeline create
34//!   several instances of your vertex set on the GPU.
35//!
36//! # Tessellation views
37//!
38//! Once you have a [`Tess`] — created from [`TessBuilder::build`], you can now render it in a
39//! [`TessGate`]. In order to do so, you need a [`TessView`].
40//!
41//! A [`TessView`] is a temporary _view_ into a [`Tess`], describing what part of it should be
42//! drawn. It is also responsible in providing the number of instances to draw.
43//! Creating [`TessView`]s is a cheap operation, and can be done in two different ways:
44//!
45//! - By directly using the methods from [`TessView`].
46//! - By using the [`View`] trait.
47//!
48//! The [`View`] trait is a convenient way to create [`TessView`]. It provides the
49//! [`View::view`] and [`View::inst_view`] (for instanced rendering) methods, which accept Rust’s
50//! range operators to create the [`TessView`]s in a more comfortable way.
51//!
52//! # Tessellation mapping
53//!
54//! Sometimes, you will want to edit tessellations in a dynamic way instead of re-creating new
55//! ones. That can be useful for streaming data of for using a small part of a big [`Tess`]. The
56//! [`Tess`] type has several methods to obtain subparts, allow you to map values and iterate over
57//! them via standard Rust slices. See these for further details:
58//!
59//! - [`Tess::vertices`] [`Tess::vertices_mut`] to map tessellations’ vertices.
60//! - [`Tess::indices`] [`Tess::indices_mut`] to map tessellations’ indices.
61//! - [`Tess::instances`] [`Tess::instances_mut`] to map tessellations’ instances.
62//!
63//! > Note: because of their slice nature, mapping a tessellation (vertices, indices or instances)
64//! > will not help you with resizing a [`Tess`], as this is not currently supported. Creating a large
65//! > enough [`Tess`] is preferable for now.
66//!
67//! [`TessGate`]: crate::tess_gate::TessGate
68
69use crate::{
70  backend::tess::{
71    IndexSlice as IndexSliceBackend, InstanceSlice as InstanceSliceBackend, Tess as TessBackend,
72    VertexSlice as VertexSliceBackend,
73  },
74  context::GraphicsContext,
75  vertex::{Deinterleave, Vertex, VertexDesc},
76};
77use std::{
78  error, fmt,
79  marker::PhantomData,
80  ops::{Deref, DerefMut, Range, RangeFrom, RangeFull, RangeInclusive, RangeTo, RangeToInclusive},
81};
82
83/// Primitive mode.
84///
85/// Some modes allow for _primitive restart_. Primitive restart is a cool feature that allows to
86/// _break_ the building of a primitive to _start over again_. For instance, when making a curve,
87/// you can imagine gluing segments next to each other. If at some point, you want to start a new
88/// curve, you have two choices:
89///
90///   - Either you stop your draw call and make another one.
91///   - Or you just use the _primitive restart_ feature to ask to create another line from scratch.
92///
93/// _Primitive restart_ should be used as much as possible as it will decrease the number of GPU
94/// commands you have to issue.
95///
96/// > Deprecation notice: the next version of luminance will not support setting the primitive restart index: you will
97/// then must provide the maximum value of index type.
98///
99/// That feature is encoded with a special _vertex index_. You can setup the value of the _primitive
100/// restart index_ with [`TessBuilder::set_primitive_restart_index`]. Whenever a vertex index is set
101/// to the same value as the _primitive restart index_, the value is not interpreted as a vertex
102/// index but just a marker / hint to start a new primitive.
103#[derive(Copy, Clone, Debug, Eq, PartialEq)]
104pub enum Mode {
105  /// A single point.
106  ///
107  /// Points are left unconnected from each other and represent a _point cloud_. This is the typical
108  /// primitive mode you want to do, for instance, particles rendering.
109  Point,
110  /// A line, defined by two points.
111  ///
112  /// Every pair of vertices are connected together to form a straight line.
113  Line,
114  /// A strip line, defined by at least two points and zero or many other ones.
115  ///
116  /// The first two vertices create a line, and every new vertex flowing in the graphics pipeline
117  /// (starting from the third, then) well extend the initial line, making a curve composed of
118  /// several segments.
119  ///
120  /// > This kind of primitive mode allows the usage of _primitive restart_.
121  LineStrip,
122  /// A triangle, defined by three points.
123  Triangle,
124  /// A triangle fan, defined by at least three points and zero or many other ones.
125  ///
126  /// Such a mode is easy to picture: a cooling fan is a circular shape, with blades.
127  /// [`Mode::TriangleFan`] is kind of the same. The first vertex is at the center of the fan, then
128  /// the second vertex creates the first edge of the first triangle. Every time you add a new
129  /// vertex, a triangle is created by taking the first (center) vertex, the very previous vertex
130  /// and the current vertex. By specifying vertices around the center, you actually create a
131  /// fan-like shape.
132  ///
133  /// > This kind of primitive mode allows the usage of _primitive restart_.
134  TriangleFan,
135  /// A triangle strip, defined by at least three points and zero or many other ones.
136  ///
137  /// This mode is a bit different from [`Mode::TriangleFan`]. The first two vertices define the
138  /// first edge of the first triangle. Then, for each new vertex, a new triangle is created by
139  /// taking the very previous vertex and the last to very previous vertex. What it means is that
140  /// every time a triangle is created, the next vertex will share the edge that was created to
141  /// spawn the previous triangle.
142  ///
143  /// This mode is useful to create long ribbons / strips of triangles.
144  ///
145  /// > This kind of primitive mode allows the usage of _primitive restart_.
146  TriangleStrip,
147  /// A general purpose primitive with _n_ vertices, for use in tessellation shaders.
148  /// For example, `Mode::Patch(3)` represents triangle patches, so every three vertices in the
149  /// buffer form a patch.
150  ///
151  /// If you want to employ tessellation shaders, this is the only primitive mode you can use.
152  Patch(usize),
153}
154
155impl fmt::Display for Mode {
156  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
157    match *self {
158      Mode::Point => f.write_str("point"),
159      Mode::Line => f.write_str("line"),
160      Mode::LineStrip => f.write_str("line strip"),
161      Mode::Triangle => f.write_str("triangle"),
162      Mode::TriangleStrip => f.write_str("triangle strip"),
163      Mode::TriangleFan => f.write_str("triangle fan"),
164      Mode::Patch(ref n) => write!(f, "patch ({})", n),
165    }
166  }
167}
168
169/// Error that can occur while trying to map GPU tessellations to host code.
170#[non_exhaustive]
171#[derive(Debug, Eq, PartialEq)]
172pub enum TessMapError {
173  /// Cannot obtain a slice on the backend.
174  CannotMap,
175  /// Vertex target type is not the same as the one stored in the buffer.
176  VertexTypeMismatch(VertexDesc, VertexDesc),
177  /// Index target type is not the same as the one stored in the buffer.
178  IndexTypeMismatch(TessIndexType, TessIndexType),
179  /// The CPU mapping failed because you cannot map an attributeless tessellation since it doesn’t
180  /// have any vertex attribute.
181  ForbiddenAttributelessMapping,
182  /// The CPU mapping failed because currently, mapping deinterleaved buffers is not supported via
183  /// a single slice.
184  ForbiddenDeinterleavedMapping,
185}
186
187impl TessMapError {
188  /// Cannot obtain a slice on the backend.
189  pub fn cannot_map() -> Self {
190    TessMapError::CannotMap
191  }
192
193  /// Vertex target type is not the same as the one stored in the buffer.
194  pub fn vertex_type_mismatch(a: VertexDesc, b: VertexDesc) -> Self {
195    TessMapError::VertexTypeMismatch(a, b)
196  }
197
198  /// Index target type is not the same as the one stored in the buffer.
199  pub fn index_type_mismatch(a: TessIndexType, b: TessIndexType) -> Self {
200    TessMapError::IndexTypeMismatch(a, b)
201  }
202
203  /// The CPU mapping failed because you cannot map an attributeless tessellation since it doesn’t
204  /// have any vertex attribute.
205  pub fn forbidden_attributeless_mapping() -> Self {
206    TessMapError::ForbiddenAttributelessMapping
207  }
208
209  /// The CPU mapping failed because currently, mapping deinterleaved buffers is not supported via
210  /// a single slice.
211  pub fn forbidden_deinterleaved_mapping() -> Self {
212    TessMapError::ForbiddenDeinterleavedMapping
213  }
214}
215
216impl fmt::Display for TessMapError {
217  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
218    match *self {
219      TessMapError::CannotMap => f.write_str("cannot map on the backend"),
220
221      TessMapError::VertexTypeMismatch(ref a, ref b) => write!(
222        f,
223        "cannot map tessellation: vertex type mismatch between {:?} and {:?}",
224        a, b
225      ),
226
227      TessMapError::IndexTypeMismatch(ref a, ref b) => write!(
228        f,
229        "cannot map tessellation: index type mismatch between {:?} and {:?}",
230        a, b
231      ),
232
233      TessMapError::ForbiddenAttributelessMapping => {
234        f.write_str("cannot map an attributeless buffer")
235      }
236
237      TessMapError::ForbiddenDeinterleavedMapping => {
238        f.write_str("cannot map a deinterleaved buffer as interleaved")
239      }
240    }
241  }
242}
243
244impl error::Error for TessMapError {}
245
246/// Possible errors that might occur when dealing with [`Tess`].
247#[non_exhaustive]
248#[derive(Debug, Eq, PartialEq)]
249pub enum TessError {
250  /// Cannot create a tessellation.
251  CannotCreate(String),
252  /// Error related to attributeless tessellation and/or render.
253  AttributelessError(String),
254  /// Length incoherency in vertex, index or instance buffers.
255  LengthIncoherency(usize),
256  /// Forbidden primitive mode by hardware.
257  ForbiddenPrimitiveMode(Mode),
258  /// No data provided and empty tessellation.
259  NoData,
260}
261
262impl TessError {
263  /// Cannot create a tessellation.
264  pub fn cannot_create(e: impl Into<String>) -> Self {
265    TessError::CannotCreate(e.into())
266  }
267
268  /// Error related to attributeless tessellation and/or render.
269  pub fn attributeless_error(e: impl Into<String>) -> Self {
270    TessError::AttributelessError(e.into())
271  }
272
273  /// Length incoherency in vertex, index or instance buffers.
274  pub fn length_incoherency(len: usize) -> Self {
275    TessError::LengthIncoherency(len)
276  }
277
278  /// Forbidden primitive mode by hardware.
279  pub fn forbidden_primitive_mode(mode: Mode) -> Self {
280    TessError::ForbiddenPrimitiveMode(mode)
281  }
282
283  /// No data or empty tessellation.
284  pub fn no_data() -> Self {
285    TessError::NoData
286  }
287}
288
289impl fmt::Display for TessError {
290  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
291    match *self {
292      TessError::CannotCreate(ref s) => write!(f, "Creation error: {}", s),
293      TessError::AttributelessError(ref s) => write!(f, "Attributeless error: {}", s),
294      TessError::LengthIncoherency(ref s) => {
295        write!(f, "Incoherent size for internal buffers: {}", s)
296      }
297      TessError::ForbiddenPrimitiveMode(ref e) => write!(f, "forbidden primitive mode: {}", e),
298      TessError::NoData => f.write_str("no data or empty tessellation"),
299    }
300  }
301}
302
303impl error::Error for TessError {}
304
305/// Possible tessellation index types.
306#[derive(Copy, Clone, Debug, Eq, PartialEq)]
307pub enum TessIndexType {
308  /// 8-bit unsigned integer.
309  U8,
310  /// 16-bit unsigned integer.
311  U16,
312  /// 32-bit unsigned integer.
313  U32,
314}
315
316impl TessIndexType {
317  /// Get the number of bytes that are needed to represent a type described by the variant.
318  pub fn bytes(self) -> usize {
319    match self {
320      TessIndexType::U8 => 1,
321      TessIndexType::U16 => 2,
322      TessIndexType::U32 => 4,
323    }
324  }
325}
326
327/// Class of tessellation indices.
328///
329/// Values which types implement this trait are allowed to be used to index tessellation in *indexed
330/// draw commands*.
331///
332/// You shouldn’t have to worry too much about that trait. Have a look at the current implementors
333/// for an exhaustive list of types you can use.
334///
335/// > Implementing this trait is `unsafe`.
336pub unsafe trait TessIndex: Copy {
337  /// Type of the underlying index.
338  ///
339  /// You are limited in which types you can use as indexes. Feel free to have a look at the
340  /// documentation of the [`TessIndexType`] trait for further information.
341  ///
342  /// `None` means that you disable indexing.
343  const INDEX_TYPE: Option<TessIndexType>;
344
345  /// Get and convert the index to [`u32`], if possible.
346  fn try_into_u32(self) -> Option<u32>;
347}
348
349unsafe impl TessIndex for () {
350  const INDEX_TYPE: Option<TessIndexType> = None;
351
352  fn try_into_u32(self) -> Option<u32> {
353    None
354  }
355}
356
357/// Boop.
358unsafe impl TessIndex for u8 {
359  const INDEX_TYPE: Option<TessIndexType> = Some(TessIndexType::U8);
360
361  fn try_into_u32(self) -> Option<u32> {
362    Some(self.into())
363  }
364}
365
366/// Boop.
367unsafe impl TessIndex for u16 {
368  const INDEX_TYPE: Option<TessIndexType> = Some(TessIndexType::U16);
369
370  fn try_into_u32(self) -> Option<u32> {
371    Some(self.into())
372  }
373}
374
375/// Wuuuuuuha.
376unsafe impl TessIndex for u32 {
377  const INDEX_TYPE: Option<TessIndexType> = Some(TessIndexType::U32);
378
379  fn try_into_u32(self) -> Option<u32> {
380    Some(self.into())
381  }
382}
383
384/// Interleaved memory marker.
385#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
386pub enum Interleaved {}
387
388/// Deinterleaved memory marker.
389#[derive(Copy, Clone, Debug, Eq, Hash, PartialEq)]
390pub enum Deinterleaved {}
391
392/// Vertex input data of a [`TessBuilder`].
393///
394/// This trait defines the _storage_ of vertices that a [`TessBuilder`] will use to build its internal storage on the
395/// backend.
396///
397/// There are two implementors of this trait:
398///
399/// - `impl<V> TessVertexData<Interleaved> for V where V: Vertex`
400/// - `impl<V> TessVertexData<Deinterleaved> for V where V: Vertex`
401///
402/// For the situation where `S` is [`Interleaved`], this trait associates the data (with [`TessVertexData::Data`]) to be
403/// a `Vec<V>`. What it means is that the [`TessBuilder`] will build the vertices as a `Vec<V>`, where `V: Vertex`,
404/// implementing an _interleaved memory layout_.
405///
406/// For the situation where `S` is [`Deinterleaved`], this trait associates the data to be a `Vec<DeinterleavedData>`.
407/// [`DeinterleavedData`] is a special type used to store a collection of one of the attributes of a `V: Vertex`. For
408/// instance, if `V: Vertex` has two attributes, vertices will end up in two [`DeinterleavedData`]: the first one for
409/// the first attribute, the second one for the second attribute. The [`TessBuilder`] will handle that logic for you
410/// when you will use the [`TessBuilder::set_vertices`] by tracking at the type-level which set of attributes you are setting.
411///
412/// # Parametricity
413///
414/// - `S` is the storage marker. It will be set to either [`Interleaved`] or [`Deinterleaved`].
415pub trait TessVertexData<S>: Vertex
416where
417  S: ?Sized,
418{
419  /// Vertex storage type.
420  type Data;
421
422  /// Coherent length of the vertices.
423  ///
424  /// Vertices length can be incoherent for some implementations of [`TessVertexData::Data`],
425  /// especially with deinterleaved memory. For this reason, this method can fail with [`TessError`].
426  fn coherent_len(data: &Self::Data) -> Result<usize, TessError>;
427}
428
429impl<V> TessVertexData<Interleaved> for V
430where
431  V: Vertex,
432{
433  type Data = Vec<V>;
434
435  fn coherent_len(data: &Self::Data) -> Result<usize, TessError> {
436    Ok(data.len())
437  }
438}
439
440impl<V> TessVertexData<Deinterleaved> for V
441where
442  V: Vertex,
443{
444  type Data = Vec<DeinterleavedData>;
445
446  fn coherent_len(data: &Self::Data) -> Result<usize, TessError> {
447    if data.is_empty() {
448      Ok(0)
449    } else {
450      let len = data[0].len;
451
452      if data[1..].iter().any(|a| a.len != len) {
453        Err(TessError::length_incoherency(len))
454      } else {
455        Ok(len)
456      }
457    }
458  }
459}
460
461/// Deinterleaved data.
462///
463/// [`DeinterleavedData`] represents a collection of one type of attributes of a set of vertices, for each vertex
464/// implements [`Vertex`]. End-users shouldn’t need to know about this type as it’s only used internally.
465#[derive(Debug, Clone)]
466pub struct DeinterleavedData {
467  raw: Vec<u8>,
468  len: usize,
469}
470
471impl DeinterleavedData {
472  fn new() -> Self {
473    DeinterleavedData {
474      raw: Vec::new(),
475      len: 0,
476    }
477  }
478
479  /// Turn the [`DeinterleavedData`] into its raw representation.
480  pub fn into_vec(self) -> Vec<u8> {
481    self.raw
482  }
483}
484
485/// [`Tess`] builder object.
486///
487/// This type allows to create [`Tess`] via a _builder pattern_. You have several flavors of
488/// possible _vertex storages_, as well as _data encoding_, described below.
489///
490/// # Vertex storage
491///
492/// ## Interleaved
493///
494/// You can pass around interleaved vertices and indices. Those are encoded in `Vec<T>`. You
495/// typically want to use this when you already have the vertices and/or indices allocated somewhere,
496/// as the interface will use the input vector as a source of truth for lengths.
497///
498/// ## Deinterleaved
499///
500/// This is the same as interleaved data in terms of interface, but the `T` type is interpreted
501/// a bit differently. Here, the encoding is `(Vec<Field0>, Vec<Field1>, …)`, where `Field0`,
502/// `Field1` etc. are all the ordered fieds in `T`. This logic is hidden behind `Vec<DeinterleavedData>`.
503///
504/// That representation allows field-based operations on [`Tess`], while it would be impossible
505/// with the interleaved version (you would need to get all the fields at once, since
506/// you would work on `T` directly and each of its fields).
507///
508/// # Data encoding
509///
510/// - Vectors: you can pass vectors as input data for both vertices and indices. Those will be
511///   interpreted differently based on the vertex storage you chose for vertices / instances. For indices, there is no
512///   difference.
513/// - Disabled: disabling means that no data will be passed to the GPU. You can disable independently
514///   vertex data and/or index data by using the unit `()` type.
515///
516/// # Indexed vertex sets
517///
518/// It is possible to _index_ the geometry via the use of indices. Indices are stored in contiguous
519/// regions of memory (`Vec<T>`), where `T` satisfies [`TessIndex`]. When using an indexed tessellation,
520/// the meaning of its attributes slightly changes. First, the vertices are not used as input source for
521/// the vertex stream. In order to provide vertices that will go through the vertex stream, the indices
522/// reference the vertex set to provide the order in which they should appear in the stream.
523///
524/// When rendering with a [`TessView`], the number of vertices to render must be provided or inferred
525/// based on the [`Tess`] the view was made from. That number will refer to either the vertex set or
526/// index set, depending on the kind of tessellation. Asking to render a [`Tess`] with 3 vertices will
527/// pick 3 vertices from the vertex set for direct tessellations and 3 indices to index the vertex set
528/// for indexed tessellations.
529///
530/// # Primitive mode
531///
532/// By default, a [`TessBuilder`] will build _points_. Each vertex in the vertex stream will be independently rendered
533/// from the others, resulting in a _point cloud_. This logic is encoded with [`Mode::Point`]. You can change how
534/// vertices are interpreted by changing the [`Mode`].
535///
536/// # Parametricity
537///
538/// - `B` is the backend type
539/// - `V` is the vertex type.
540/// - `I` is the index type.
541/// - `W` is the vertex instance type.
542/// - `S` is the storage type.
543#[derive(Debug)]
544pub struct TessBuilder<'a, B, V, I = (), W = (), S = Interleaved>
545where
546  B: ?Sized,
547  V: TessVertexData<S>,
548  W: TessVertexData<S>,
549  S: ?Sized,
550{
551  backend: &'a mut B,
552  vertex_data: Option<V::Data>,
553  index_data: Vec<I>,
554  instance_data: Option<W::Data>,
555  mode: Mode,
556  render_vert_nb: usize,
557  render_inst_nb: usize,
558  restart_index: Option<I>,
559  _phantom: PhantomData<&'a mut ()>,
560}
561
562impl<'a, B, V, I, W, S> TessBuilder<'a, B, V, I, W, S>
563where
564  B: ?Sized,
565  V: TessVertexData<S>,
566  I: TessIndex,
567  W: TessVertexData<S>,
568  S: ?Sized,
569{
570  /// Set the [`Mode`] to connect vertices.
571  ///
572  /// Calling that function twice replaces the previously set value.
573  pub fn set_mode(mut self, mode: Mode) -> Self {
574    self.mode = mode;
575    self
576  }
577
578  /// Set the default number of vertices to render.
579  ///
580  /// Calling that function twice replaces the previously set value. This method changes the number of vertices to pick:
581  ///
582  /// - From the vertex set for regular geometries.
583  /// - From the index set, using the picked indices to reference the vertex set.
584  pub fn set_render_vertex_nb(mut self, vert_nb: usize) -> Self {
585    self.render_vert_nb = vert_nb;
586    self
587  }
588
589  /// Set the default number of instances to render.
590  ///
591  /// Calling that function twice replaces the previously set value.
592  pub fn set_render_instance_nb(mut self, inst_nb: usize) -> Self {
593    self.render_inst_nb = inst_nb;
594    self
595  }
596
597  /// Set the primitive restart index.
598  ///
599  /// Calling that function twice replaces the previously set value.
600  pub fn set_primitive_restart_index(mut self, restart_index: I) -> Self {
601    self.restart_index = Some(restart_index);
602    self
603  }
604}
605
606impl<'a, B, V, I, W, S> TessBuilder<'a, B, V, I, W, S>
607where
608  B: ?Sized,
609  V: TessVertexData<S>,
610  I: TessIndex,
611  W: TessVertexData<S>,
612  S: ?Sized,
613{
614  /// Create a new default [`TessBuilder`].
615  ///
616  /// # Notes
617  ///
618  /// Feel free to use the [`GraphicsContext::new_tess`] method for a simpler method.
619  ///
620  /// [`GraphicsContext::new_tess`]: crate::context::GraphicsContext::new_tess
621  pub fn new<C>(ctx: &'a mut C) -> Self
622  where
623    C: GraphicsContext<Backend = B>,
624  {
625    TessBuilder {
626      backend: ctx.backend(),
627      vertex_data: None,
628      index_data: Vec::new(),
629      instance_data: None,
630      mode: Mode::Point,
631      render_vert_nb: 0,
632      render_inst_nb: 0,
633      restart_index: None,
634      _phantom: PhantomData,
635    }
636  }
637}
638
639// set_indices, which works only if I = ()
640impl<'a, B, V, W, S> TessBuilder<'a, B, V, (), W, S>
641where
642  B: ?Sized,
643  V: TessVertexData<S>,
644  W: TessVertexData<S>,
645  S: ?Sized,
646{
647  /// Add indices to be bundled in the [`Tess`].
648  ///
649  /// Every time you call that function, the set of indices is replaced by the one you provided.
650  /// The type of expected indices is ruled by the `II` type variable you chose.
651  pub fn set_indices<I, X>(self, indices: X) -> TessBuilder<'a, B, V, I, W, S>
652  where
653    X: Into<Vec<I>>,
654  {
655    TessBuilder {
656      backend: self.backend,
657      vertex_data: self.vertex_data,
658      index_data: indices.into(),
659      instance_data: self.instance_data,
660      mode: self.mode,
661      render_vert_nb: self.render_vert_nb,
662      render_inst_nb: self.render_inst_nb,
663      restart_index: None,
664      _phantom: PhantomData,
665    }
666  }
667}
668
669// set_vertices, interleaved version; works only for V = ()
670impl<'a, B, I, W> TessBuilder<'a, B, (), I, W, Interleaved>
671where
672  B: ?Sized,
673  I: TessIndex,
674  W: TessVertexData<Interleaved>,
675{
676  /// Add vertices to be bundled in the [`Tess`].
677  ///
678  /// Every time you call that function, the set of vertices is replaced by the one you provided.
679  pub fn set_vertices<V, X>(self, vertices: X) -> TessBuilder<'a, B, V, I, W, Interleaved>
680  where
681    X: Into<Vec<V>>,
682    V: TessVertexData<Interleaved, Data = Vec<V>>,
683  {
684    TessBuilder {
685      backend: self.backend,
686      vertex_data: Some(vertices.into()),
687      index_data: self.index_data,
688      instance_data: self.instance_data,
689      mode: self.mode,
690      render_vert_nb: self.render_vert_nb,
691      render_inst_nb: self.render_inst_nb,
692      restart_index: self.restart_index,
693      _phantom: PhantomData,
694    }
695  }
696}
697
698impl<'a, B, I, V> TessBuilder<'a, B, V, I, (), Interleaved>
699where
700  B: ?Sized,
701  I: TessIndex,
702  V: TessVertexData<Interleaved>,
703{
704  /// Add instances to be bundled in the [`Tess`].
705  ///
706  /// Every time you call that function, the set of instances is replaced by the one you provided.
707  pub fn set_instances<W, X>(self, instances: X) -> TessBuilder<'a, B, V, I, W, Interleaved>
708  where
709    X: Into<Vec<W>>,
710    W: TessVertexData<Interleaved, Data = Vec<W>>,
711  {
712    TessBuilder {
713      backend: self.backend,
714      vertex_data: self.vertex_data,
715      index_data: self.index_data,
716      instance_data: Some(instances.into()),
717      mode: self.mode,
718      render_vert_nb: self.render_vert_nb,
719      render_inst_nb: self.render_inst_nb,
720      restart_index: self.restart_index,
721      _phantom: PhantomData,
722    }
723  }
724}
725
726impl<'a, B, V, I, W> TessBuilder<'a, B, V, I, W, Deinterleaved>
727where
728  B: ?Sized,
729  V: TessVertexData<Deinterleaved, Data = Vec<DeinterleavedData>>,
730  I: TessIndex,
731  W: TessVertexData<Deinterleaved, Data = Vec<DeinterleavedData>>,
732{
733  /// Add vertices to be bundled in the [`Tess`].
734  ///
735  /// Every time you call that function, the set of vertices is replaced by the one you provided.
736  pub fn set_attributes<A, X>(mut self, attributes: X) -> Self
737  where
738    X: Into<Vec<A>>,
739    V: Deinterleave<A>,
740  {
741    let build_raw = |deinterleaved: &mut Vec<DeinterleavedData>| {
742      // turn the attribute into a raw vector (Vec<u8>)
743      let boxed_slice = attributes.into().into_boxed_slice();
744      let len = boxed_slice.len();
745      let len_bytes = len * std::mem::size_of::<A>();
746      let ptr = Box::into_raw(boxed_slice);
747      // please Dog pardon me
748      let raw = unsafe { Vec::from_raw_parts(ptr as _, len_bytes, len_bytes) };
749
750      deinterleaved[V::RANK] = DeinterleavedData { raw, len };
751    };
752
753    match self.vertex_data {
754      Some(ref mut deinterleaved) => {
755        build_raw(deinterleaved);
756      }
757
758      None => {
759        let attrs = V::vertex_desc();
760        let mut deinterleaved = vec![DeinterleavedData::new(); attrs.len()];
761        build_raw(&mut deinterleaved);
762
763        self.vertex_data = Some(deinterleaved);
764      }
765    }
766
767    self
768  }
769
770  /// Add instances to be bundled in the [`Tess`].
771  ///
772  /// Every time you call that function, the set of instances is replaced by the one you provided.
773  pub fn set_instance_attributes<A, X>(mut self, attributes: X) -> Self
774  where
775    X: Into<Vec<A>>,
776    W: Deinterleave<A>,
777  {
778    let build_raw = |deinterleaved: &mut Vec<DeinterleavedData>| {
779      // turn the attribute into a raw vector (Vec<u8>)
780      let boxed_slice = attributes.into().into_boxed_slice();
781      let len = boxed_slice.len();
782      let len_bytes = len * std::mem::size_of::<A>();
783      let ptr = Box::into_raw(boxed_slice);
784      // please Dog pardon me
785      let raw = unsafe { Vec::from_raw_parts(ptr as _, len_bytes, len_bytes) };
786
787      deinterleaved[W::RANK] = DeinterleavedData { raw, len };
788    };
789
790    match self.instance_data {
791      None => {
792        let attrs = W::vertex_desc();
793        let mut deinterleaved = vec![DeinterleavedData::new(); attrs.len()];
794        build_raw(&mut deinterleaved);
795
796        self.instance_data = Some(deinterleaved);
797      }
798
799      Some(ref mut deinterleaved) => {
800        build_raw(deinterleaved);
801      }
802    }
803
804    self
805  }
806}
807
808impl<'a, B, V, I, W, S> TessBuilder<'a, B, V, I, W, S>
809where
810  B: ?Sized + TessBackend<V, I, W, S>,
811  V: TessVertexData<S>,
812  I: TessIndex,
813  W: TessVertexData<S>,
814{
815  /// Build a [`Tess`] if the [`TessBuilder`] has enough data and is in a valid state. What is
816  /// needed is backend-dependent but most of the time, you will want to:
817  ///
818  /// - Set a [`Mode`].
819  /// - Give vertex data and optionally indices, or give none of them but only a number of vertices
820  ///   (attributeless objects).
821  /// - If you provide vertex data by submitting several sets with [`TessBuilder::set_attributes`]
822  ///   and/or [`TessBuilder::set_instances`], do not forget that you must submit sets with the
823  ///   same size. Otherwise, the GPU will not know what values use for missing attributes in
824  ///   vertices.
825  pub fn build(self) -> Result<Tess<B, V, I, W, S>, TessError> {
826    // validate input data before giving it to the backend
827    let render_vert_nb = self.guess_render_vertex_len()?;
828    let render_inst_nb = self.guess_render_instance_len()?;
829
830    unsafe {
831      self
832        .backend
833        .build(
834          self.vertex_data,
835          self.index_data,
836          self.instance_data,
837          self.mode,
838          self.restart_index,
839        )
840        .map(|repr| Tess {
841          repr,
842          render_vert_nb,
843          render_inst_nb,
844          _phantom: PhantomData,
845        })
846    }
847  }
848
849  /// Guess how many vertices we want to render by default.
850  fn guess_render_vertex_len(&self) -> Result<usize, TessError> {
851    // if we don’t have an explicit number of vertex to render, we rely on the vertex data coherent
852    // length
853    if self.render_vert_nb == 0 {
854      // if we don’t have index data, get the length from the vertex data; otherwise, get it from
855      // the index data
856      if self.index_data.is_empty() {
857        match self.vertex_data {
858          Some(ref data) => V::coherent_len(data),
859          None => Err(TessError::NoData),
860        }
861      } else {
862        Ok(self.index_data.len())
863      }
864    } else {
865      // ensure the length is okay regarding what we have in the index / vertex data
866      if self.index_data.is_empty() {
867        match self.vertex_data {
868          Some(ref data) => {
869            let coherent_len = V::coherent_len(data)?;
870
871            if self.render_vert_nb <= coherent_len {
872              Ok(self.render_vert_nb)
873            } else {
874              Err(TessError::length_incoherency(self.render_vert_nb))
875            }
876          }
877
878          // attributeless render, always accept
879          None => Ok(self.render_vert_nb),
880        }
881      } else {
882        if self.render_vert_nb <= self.index_data.len() {
883          Ok(self.render_vert_nb)
884        } else {
885          Err(TessError::length_incoherency(self.render_vert_nb))
886        }
887      }
888    }
889  }
890
891  fn guess_render_instance_len(&self) -> Result<usize, TessError> {
892    // as with vertex length, we first check for an explicit number, and if none, we deduce it
893    if self.render_inst_nb == 0 {
894      match self.instance_data {
895        Some(ref data) => W::coherent_len(data),
896        None => Ok(0),
897      }
898    } else {
899      let coherent_len = self
900        .instance_data
901        .as_ref()
902        .ok_or_else(|| TessError::attributeless_error("missing number of instances"))
903        .and_then(W::coherent_len)?;
904
905      if self.render_inst_nb <= coherent_len {
906        Ok(self.render_inst_nb)
907      } else {
908        Err(TessError::length_incoherency(self.render_inst_nb))
909      }
910    }
911  }
912}
913
914/// A GPU vertex set.
915///
916/// Vertex set are the only way to represent space data. The dimension you choose is up to you, but
917/// people will typically want to represent objects in 2D or 3D. A _vertex_ is a point in such
918/// space and it carries _properties_ — called _“vertex attributes_”. Those attributes are
919/// completely free to use. They must, however, be compatible with the [`Semantics`] and [`Vertex`]
920/// traits.
921///
922/// [`Tess`] are built with a [`TessBuilder`] and can be _sliced_ to edit their content in-line —
923/// by mapping the GPU memory region and access data via slices.
924///
925/// [`Semantics`]: crate::vertex::Semantics
926/// [`TessGate`]: crate::tess_gate::TessGate
927#[derive(Debug)]
928pub struct Tess<B, V, I = (), W = (), S = Interleaved>
929where
930  B: ?Sized + TessBackend<V, I, W, S>,
931  V: TessVertexData<S>,
932  I: TessIndex,
933  W: TessVertexData<S>,
934  S: ?Sized,
935{
936  // backend representation of the tessellation
937  pub(crate) repr: B::TessRepr,
938
939  // default number of vertices to render
940  render_vert_nb: usize,
941
942  // default number of instances to render
943  render_inst_nb: usize,
944
945  _phantom: PhantomData<*const S>,
946}
947
948impl<B, V, I, W, S> Tess<B, V, I, W, S>
949where
950  B: ?Sized + TessBackend<V, I, W, S>,
951  V: TessVertexData<S>,
952  I: TessIndex,
953  W: TessVertexData<S>,
954  S: ?Sized,
955{
956  /// Get the number of vertices.
957  pub fn vert_nb(&self) -> usize {
958    unsafe { B::tess_vertices_nb(&self.repr) }
959  }
960
961  /// Get the number of vertex indices.
962  pub fn idx_nb(&self) -> usize {
963    unsafe { B::tess_indices_nb(&self.repr) }
964  }
965
966  /// Get the number of instances.
967  pub fn inst_nb(&self) -> usize {
968    unsafe { B::tess_instances_nb(&self.repr) }
969  }
970
971  /// Default number of vertices to render.
972  ///
973  /// This number represents the number of vertices that will be rendered when not explicitly asked to render a given
974  /// amount of vertices.
975  pub fn render_vert_nb(&self) -> usize {
976    self.render_vert_nb
977  }
978
979  /// Default number of vertex instances to render.
980  ///
981  /// This number represents the number of vertex instances that will be rendered when not explicitly asked to render a
982  /// given amount of instances.
983  pub fn render_inst_nb(&self) -> usize {
984    self.render_inst_nb
985  }
986
987  /// Slice the [`Tess`] in order to read its content via usual slices.
988  ///
989  /// This method gives access to the underlying _index storage_.
990  pub fn indices<'a>(&'a mut self) -> Result<Indices<'a, B, V, I, W, S>, TessMapError>
991  where
992    B: IndexSliceBackend<'a, V, I, W, S>,
993  {
994    unsafe { B::indices(&mut self.repr).map(|repr| Indices { repr }) }
995  }
996
997  /// Slice the [`Tess`] in order to read its content via usual slices.
998  ///
999  /// This method gives access to the underlying _index storage_.
1000  pub fn indices_mut<'a>(&'a mut self) -> Result<IndicesMut<'a, B, V, I, W, S>, TessMapError>
1001  where
1002    B: IndexSliceBackend<'a, V, I, W, S>,
1003  {
1004    unsafe { B::indices_mut(&mut self.repr).map(|repr| IndicesMut { repr }) }
1005  }
1006}
1007
1008impl<B, V, I, W> Tess<B, V, I, W, Interleaved>
1009where
1010  B: ?Sized + TessBackend<V, I, W, Interleaved>,
1011  V: TessVertexData<Interleaved>,
1012  I: TessIndex,
1013  W: TessVertexData<Interleaved>,
1014{
1015  /// Slice the [`Tess`] in order to read its content via usual slices.
1016  ///
1017  /// This method gives access to the underlying _vertex storage_.
1018  pub fn vertices<'a>(
1019    &'a mut self,
1020  ) -> Result<Vertices<'a, B, V, I, W, Interleaved, V>, TessMapError>
1021  where
1022    B: VertexSliceBackend<'a, V, I, W, Interleaved, V>,
1023  {
1024    unsafe { B::vertices(&mut self.repr).map(|repr| Vertices { repr }) }
1025  }
1026
1027  /// Slice the [`Tess`] in order to read its content via usual slices.
1028  ///
1029  /// This method gives access to the underlying _vertex storage_.
1030  pub fn vertices_mut<'a>(
1031    &'a mut self,
1032  ) -> Result<VerticesMut<'a, B, V, I, W, Interleaved, V>, TessMapError>
1033  where
1034    B: VertexSliceBackend<'a, V, I, W, Interleaved, V>,
1035  {
1036    unsafe { B::vertices_mut(&mut self.repr).map(|repr| VerticesMut { repr }) }
1037  }
1038
1039  /// Slice the [`Tess`] in order to read its content via usual slices.
1040  ///
1041  /// This method gives access to the underlying _instance storage_.
1042  pub fn instances<'a>(
1043    &'a mut self,
1044  ) -> Result<Instances<'a, B, V, I, W, Interleaved, W>, TessMapError>
1045  where
1046    B: InstanceSliceBackend<'a, V, I, W, Interleaved, W>,
1047  {
1048    unsafe { B::instances(&mut self.repr).map(|repr| Instances { repr }) }
1049  }
1050
1051  /// Slice the [`Tess`] in order to read its content via usual slices.
1052  ///
1053  /// This method gives access to the underlying _instance storage_.
1054  pub fn instances_mut<'a>(
1055    &'a mut self,
1056  ) -> Result<InstancesMut<'a, B, V, I, W, Interleaved, W>, TessMapError>
1057  where
1058    B: InstanceSliceBackend<'a, V, I, W, Interleaved, W>,
1059  {
1060    unsafe { B::instances_mut(&mut self.repr).map(|repr| InstancesMut { repr }) }
1061  }
1062}
1063
1064impl<B, V, I, W> Tess<B, V, I, W, Deinterleaved>
1065where
1066  B: ?Sized + TessBackend<V, I, W, Deinterleaved>,
1067  V: TessVertexData<Deinterleaved>,
1068  I: TessIndex,
1069  W: TessVertexData<Deinterleaved>,
1070{
1071  /// Slice the [`Tess`] in order to read its content via usual slices.
1072  ///
1073  /// This method gives access to the underlying _vertex storage_.
1074  pub fn vertices<'a, T>(
1075    &'a mut self,
1076  ) -> Result<Vertices<'a, B, V, I, W, Deinterleaved, T>, TessMapError>
1077  where
1078    B: VertexSliceBackend<'a, V, I, W, Deinterleaved, T>,
1079    V: Deinterleave<T>,
1080  {
1081    unsafe { B::vertices(&mut self.repr).map(|repr| Vertices { repr }) }
1082  }
1083
1084  /// Slice the [`Tess`] in order to read its content via usual slices.
1085  ///
1086  /// This method gives access to the underlying _vertex storage_.
1087  pub fn vertices_mut<'a, T>(
1088    &'a mut self,
1089  ) -> Result<VerticesMut<'a, B, V, I, W, Deinterleaved, T>, TessMapError>
1090  where
1091    B: VertexSliceBackend<'a, V, I, W, Deinterleaved, T>,
1092    V: Deinterleave<T>,
1093  {
1094    unsafe { B::vertices_mut(&mut self.repr).map(|repr| VerticesMut { repr }) }
1095  }
1096
1097  /// Slice the [`Tess`] in order to read its content via usual slices.
1098  ///
1099  /// This method gives access to the underlying _instance storage_.
1100  pub fn instances<'a, T>(
1101    &'a mut self,
1102  ) -> Result<Instances<'a, B, V, I, W, Deinterleaved, T>, TessMapError>
1103  where
1104    B: InstanceSliceBackend<'a, V, I, W, Deinterleaved, T>,
1105    W: Deinterleave<T>,
1106  {
1107    unsafe { B::instances(&mut self.repr).map(|repr| Instances { repr }) }
1108  }
1109
1110  /// Slice the [`Tess`] in order to read its content via usual slices.
1111  ///
1112  /// This method gives access to the underlying _instance storage_.
1113  pub fn instances_mut<'a, T>(
1114    &'a mut self,
1115  ) -> Result<InstancesMut<'a, B, V, I, W, Deinterleaved, T>, TessMapError>
1116  where
1117    B: InstanceSliceBackend<'a, V, I, W, Deinterleaved, T>,
1118    W: Deinterleave<T>,
1119  {
1120    unsafe { B::instances_mut(&mut self.repr).map(|repr| InstancesMut { repr }) }
1121  }
1122}
1123
1124/// TODO
1125#[derive(Debug)]
1126pub struct Vertices<'a, B, V, I, W, S, T>
1127where
1128  B: ?Sized + TessBackend<V, I, W, S> + VertexSliceBackend<'a, V, I, W, S, T>,
1129  V: TessVertexData<S>,
1130  I: TessIndex,
1131  W: TessVertexData<S>,
1132  S: ?Sized,
1133{
1134  repr: B::VertexSliceRepr,
1135}
1136
1137impl<'a, B, V, I, W, S, T> Deref for Vertices<'a, B, V, I, W, S, T>
1138where
1139  B: ?Sized + TessBackend<V, I, W, S> + VertexSliceBackend<'a, V, I, W, S, T>,
1140  V: TessVertexData<S>,
1141  I: TessIndex,
1142  W: TessVertexData<S>,
1143  S: ?Sized,
1144{
1145  type Target = [T];
1146
1147  fn deref(&self) -> &Self::Target {
1148    self.repr.deref()
1149  }
1150}
1151
1152/// TODO
1153#[derive(Debug)]
1154pub struct VerticesMut<'a, B, V, I, W, S, T>
1155where
1156  B: ?Sized + TessBackend<V, I, W, S> + VertexSliceBackend<'a, V, I, W, S, T>,
1157  V: TessVertexData<S>,
1158  I: TessIndex,
1159  W: TessVertexData<S>,
1160  S: ?Sized,
1161{
1162  repr: B::VertexSliceMutRepr,
1163}
1164
1165impl<'a, B, V, I, W, S, T> Deref for VerticesMut<'a, B, V, I, W, S, T>
1166where
1167  B: ?Sized + TessBackend<V, I, W, S> + VertexSliceBackend<'a, V, I, W, S, T>,
1168  V: TessVertexData<S>,
1169  I: TessIndex,
1170  W: TessVertexData<S>,
1171  S: ?Sized,
1172{
1173  type Target = [T];
1174
1175  fn deref(&self) -> &Self::Target {
1176    self.repr.deref()
1177  }
1178}
1179
1180impl<'a, B, V, I, W, S, T> DerefMut for VerticesMut<'a, B, V, I, W, S, T>
1181where
1182  B: ?Sized + TessBackend<V, I, W, S> + VertexSliceBackend<'a, V, I, W, S, T>,
1183  V: TessVertexData<S>,
1184  I: TessIndex,
1185  W: TessVertexData<S>,
1186  S: ?Sized,
1187{
1188  fn deref_mut(&mut self) -> &mut Self::Target {
1189    self.repr.deref_mut()
1190  }
1191}
1192
1193/// TODO
1194#[derive(Debug)]
1195pub struct Indices<'a, B, V, I, W, S>
1196where
1197  B: ?Sized + TessBackend<V, I, W, S> + IndexSliceBackend<'a, V, I, W, S>,
1198  V: TessVertexData<S>,
1199  I: TessIndex,
1200  W: TessVertexData<S>,
1201  S: ?Sized,
1202{
1203  repr: B::IndexSliceRepr,
1204}
1205
1206impl<'a, B, V, I, W, S> Deref for Indices<'a, B, V, I, W, S>
1207where
1208  B: ?Sized + TessBackend<V, I, W, S> + IndexSliceBackend<'a, V, I, W, S>,
1209  V: TessVertexData<S>,
1210  I: TessIndex,
1211  W: TessVertexData<S>,
1212  S: ?Sized,
1213{
1214  type Target = [I];
1215
1216  fn deref(&self) -> &Self::Target {
1217    self.repr.deref()
1218  }
1219}
1220
1221/// TODO
1222#[derive(Debug)]
1223pub struct IndicesMut<'a, B, V, I, W, S>
1224where
1225  B: ?Sized + TessBackend<V, I, W, S> + IndexSliceBackend<'a, V, I, W, S>,
1226  V: TessVertexData<S>,
1227  I: TessIndex,
1228  W: TessVertexData<S>,
1229  S: ?Sized,
1230{
1231  repr: B::IndexSliceMutRepr,
1232}
1233
1234impl<'a, B, V, I, W, S> Deref for IndicesMut<'a, B, V, I, W, S>
1235where
1236  B: ?Sized + TessBackend<V, I, W, S> + IndexSliceBackend<'a, V, I, W, S>,
1237  V: TessVertexData<S>,
1238  I: TessIndex,
1239  W: TessVertexData<S>,
1240  S: ?Sized,
1241{
1242  type Target = [I];
1243
1244  fn deref(&self) -> &Self::Target {
1245    self.repr.deref()
1246  }
1247}
1248
1249impl<'a, B, V, I, W, S> DerefMut for IndicesMut<'a, B, V, I, W, S>
1250where
1251  B: ?Sized + TessBackend<V, I, W, S> + IndexSliceBackend<'a, V, I, W, S>,
1252  V: TessVertexData<S>,
1253  I: TessIndex,
1254  W: TessVertexData<S>,
1255  S: ?Sized,
1256{
1257  fn deref_mut(&mut self) -> &mut Self::Target {
1258    self.repr.deref_mut()
1259  }
1260}
1261
1262/// TODO
1263#[derive(Debug)]
1264pub struct Instances<'a, B, V, I, W, S, T>
1265where
1266  B: ?Sized + TessBackend<V, I, W, S> + InstanceSliceBackend<'a, V, I, W, S, T>,
1267  V: TessVertexData<S>,
1268  I: TessIndex,
1269  W: TessVertexData<S>,
1270  S: ?Sized,
1271{
1272  repr: B::InstanceSliceRepr,
1273}
1274
1275impl<'a, B, V, I, W, S, T> Deref for Instances<'a, B, V, I, W, S, T>
1276where
1277  B: ?Sized + TessBackend<V, I, W, S> + InstanceSliceBackend<'a, V, I, W, S, T>,
1278  V: TessVertexData<S>,
1279  I: TessIndex,
1280  W: TessVertexData<S>,
1281  S: ?Sized,
1282{
1283  type Target = [T];
1284
1285  fn deref(&self) -> &Self::Target {
1286    self.repr.deref()
1287  }
1288}
1289
1290/// TODO
1291#[derive(Debug)]
1292pub struct InstancesMut<'a, B, V, I, W, S, T>
1293where
1294  B: ?Sized + TessBackend<V, I, W, S> + InstanceSliceBackend<'a, V, I, W, S, T>,
1295  V: TessVertexData<S>,
1296  I: TessIndex,
1297  W: TessVertexData<S>,
1298  S: ?Sized,
1299{
1300  repr: B::InstanceSliceMutRepr,
1301}
1302
1303impl<'a, B, V, I, W, S, T> Deref for InstancesMut<'a, B, V, I, W, S, T>
1304where
1305  B: ?Sized + TessBackend<V, I, W, S> + InstanceSliceBackend<'a, V, I, W, S, T>,
1306  S: ?Sized,
1307  V: TessVertexData<S>,
1308  I: TessIndex,
1309  W: TessVertexData<S>,
1310{
1311  type Target = [T];
1312
1313  fn deref(&self) -> &Self::Target {
1314    self.repr.deref()
1315  }
1316}
1317
1318impl<'a, B, V, I, W, S, T> DerefMut for InstancesMut<'a, B, V, I, W, S, T>
1319where
1320  B: ?Sized + TessBackend<V, I, W, S> + InstanceSliceBackend<'a, V, I, W, S, T>,
1321  V: TessVertexData<S>,
1322  I: TessIndex,
1323  W: TessVertexData<S>,
1324  S: ?Sized,
1325{
1326  fn deref_mut(&mut self) -> &mut Self::Target {
1327    self.repr.deref_mut()
1328  }
1329}
1330
1331/// Possible error that might occur while dealing with [`TessView`] objects.
1332#[non_exhaustive]
1333#[derive(Debug, Eq, PartialEq)]
1334pub enum TessViewError {
1335  /// The view has incorrect size.
1336  ///
1337  /// data.
1338  IncorrectViewWindow {
1339    /// Capacity of data in the [`Tess`].
1340    capacity: usize,
1341    /// Requested start.
1342    start: usize,
1343    /// Requested number.
1344    nb: usize,
1345  },
1346}
1347
1348impl fmt::Display for TessViewError {
1349  fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
1350    match self {
1351      TessViewError::IncorrectViewWindow {
1352        capacity,
1353        start,
1354        nb,
1355      } => {
1356        write!(f, "TessView incorrect window error: requested slice size {} starting at {}, but capacity is only {}",
1357          nb, start, capacity)
1358      }
1359    }
1360  }
1361}
1362
1363impl error::Error for TessViewError {}
1364
1365/// A _view_ into a GPU tessellation.
1366#[derive(Clone)]
1367pub struct TessView<'a, B, V, I, W, S>
1368where
1369  B: ?Sized + TessBackend<V, I, W, S>,
1370  V: TessVertexData<S>,
1371  I: TessIndex,
1372  W: TessVertexData<S>,
1373  S: ?Sized,
1374{
1375  /// Tessellation to render.
1376  pub(crate) tess: &'a Tess<B, V, I, W, S>,
1377  /// Start index (vertex) in the tessellation.
1378  pub(crate) start_index: usize,
1379  /// Number of vertices to pick from the tessellation.
1380  pub(crate) vert_nb: usize,
1381  /// Number of instances to render.
1382  pub(crate) inst_nb: usize,
1383}
1384
1385impl<'a, B, V, I, W, S> TessView<'a, B, V, I, W, S>
1386where
1387  B: ?Sized + TessBackend<V, I, W, S>,
1388  V: TessVertexData<S>,
1389  I: TessIndex,
1390  W: TessVertexData<S>,
1391  S: ?Sized,
1392{
1393  /// Create a view that is using the whole input [`Tess`].
1394  pub fn whole(tess: &'a Tess<B, V, I, W, S>) -> Self {
1395    TessView {
1396      tess,
1397      start_index: 0,
1398      vert_nb: tess.render_vert_nb(),
1399      inst_nb: tess.render_inst_nb(),
1400    }
1401  }
1402
1403  /// Create a view that is using the whole input [`Tess`] with `inst_nb` instances.
1404  pub fn inst_whole(tess: &'a Tess<B, V, I, W, S>, inst_nb: usize) -> Self {
1405    TessView {
1406      tess,
1407      start_index: 0,
1408      vert_nb: tess.render_vert_nb(),
1409      inst_nb,
1410    }
1411  }
1412
1413  /// Create a view that is using only a subpart of the input [`Tess`], starting from the beginning
1414  /// of the vertices.
1415  pub fn sub(tess: &'a Tess<B, V, I, W, S>, vert_nb: usize) -> Result<Self, TessViewError> {
1416    let capacity = tess.render_vert_nb();
1417
1418    if vert_nb > capacity {
1419      return Err(TessViewError::IncorrectViewWindow {
1420        capacity,
1421        start: 0,
1422        nb: vert_nb,
1423      });
1424    }
1425
1426    Ok(TessView {
1427      tess,
1428      start_index: 0,
1429      vert_nb,
1430      inst_nb: tess.render_inst_nb(),
1431    })
1432  }
1433
1434  /// Create a view that is using only a subpart of the input [`Tess`], starting from the beginning
1435  /// of the vertices, with `inst_nb` instances.
1436  pub fn inst_sub(
1437    tess: &'a Tess<B, V, I, W, S>,
1438    vert_nb: usize,
1439    inst_nb: usize,
1440  ) -> Result<Self, TessViewError> {
1441    let capacity = tess.render_vert_nb();
1442
1443    if vert_nb > capacity {
1444      return Err(TessViewError::IncorrectViewWindow {
1445        capacity,
1446        start: 0,
1447        nb: vert_nb,
1448      });
1449    }
1450
1451    Ok(TessView {
1452      tess,
1453      start_index: 0,
1454      vert_nb,
1455      inst_nb,
1456    })
1457  }
1458
1459  /// Create a view that is using only a subpart of the input [`Tess`], starting from `start`, with
1460  /// `nb` vertices.
1461  pub fn slice(
1462    tess: &'a Tess<B, V, I, W, S>,
1463    start: usize,
1464    nb: usize,
1465  ) -> Result<Self, TessViewError> {
1466    let capacity = tess.render_vert_nb();
1467
1468    if start > capacity || nb + start > capacity {
1469      return Err(TessViewError::IncorrectViewWindow {
1470        capacity,
1471        start,
1472        nb,
1473      });
1474    }
1475
1476    Ok(TessView {
1477      tess,
1478      start_index: start,
1479      vert_nb: nb,
1480      inst_nb: tess.render_inst_nb(),
1481    })
1482  }
1483
1484  /// Create a view that is using only a subpart of the input [`Tess`], starting from `start`, with
1485  /// `nb` vertices and `inst_nb` instances.
1486  pub fn inst_slice(
1487    tess: &'a Tess<B, V, I, W, S>,
1488    start: usize,
1489    nb: usize,
1490    inst_nb: usize,
1491  ) -> Result<Self, TessViewError> {
1492    let capacity = tess.render_vert_nb();
1493
1494    if start > capacity || nb + start > capacity {
1495      return Err(TessViewError::IncorrectViewWindow {
1496        capacity,
1497        start,
1498        nb,
1499      });
1500    }
1501
1502    Ok(TessView {
1503      tess,
1504      start_index: start,
1505      vert_nb: nb,
1506      inst_nb,
1507    })
1508  }
1509}
1510
1511impl<'a, B, V, I, W, S> From<&'a Tess<B, V, I, W, S>> for TessView<'a, B, V, I, W, S>
1512where
1513  B: ?Sized + TessBackend<V, I, W, S>,
1514  V: TessVertexData<S>,
1515  I: TessIndex,
1516  W: TessVertexData<S>,
1517  S: ?Sized,
1518{
1519  fn from(tess: &'a Tess<B, V, I, W, S>) -> Self {
1520    TessView::whole(tess)
1521  }
1522}
1523
1524/// [`TessView`] helper trait.
1525///
1526/// This trait helps to create [`TessView`] by allowing using the Rust range operators, such as
1527///
1528/// - [`..`](https://doc.rust-lang.org/std/ops/struct.RangeFull.html); the full range operator.
1529/// - [`a .. b`](https://doc.rust-lang.org/std/ops/struct.Range.html); the range operator.
1530/// - [`a ..`](https://doc.rust-lang.org/std/ops/struct.RangeFrom.html); the range-from operator.
1531/// - [`.. b`](https://doc.rust-lang.org/std/ops/struct.RangeTo.html); the range-to operator.
1532/// - [`..= b`](https://doc.rust-lang.org/std/ops/struct.RangeToInclusive.html); the inclusive range-to operator.
1533pub trait View<B, V, I, W, S, Idx>
1534where
1535  B: ?Sized + TessBackend<V, I, W, S>,
1536  V: TessVertexData<S>,
1537  I: TessIndex,
1538  W: TessVertexData<S>,
1539  S: ?Sized,
1540{
1541  /// Slice a tessellation object and yields a [`TessView`] according to the index range.
1542  fn view(&self, idx: Idx) -> Result<TessView<B, V, I, W, S>, TessViewError>;
1543
1544  /// Slice a tesselation object and yields a [`TessView`] according to the index range with as
1545  /// many instances as specified.
1546  fn inst_view(&self, idx: Idx, inst_nb: usize) -> Result<TessView<B, V, I, W, S>, TessViewError>;
1547}
1548
1549impl<B, V, I, W, S> View<B, V, I, W, S, RangeFull> for Tess<B, V, I, W, S>
1550where
1551  B: ?Sized + TessBackend<V, I, W, S>,
1552  V: TessVertexData<S>,
1553  I: TessIndex,
1554  W: TessVertexData<S>,
1555  S: ?Sized,
1556{
1557  fn view(&self, _: RangeFull) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1558    Ok(TessView::whole(self))
1559  }
1560
1561  fn inst_view(
1562    &self,
1563    _: RangeFull,
1564    inst_nb: usize,
1565  ) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1566    Ok(TessView::inst_whole(self, inst_nb))
1567  }
1568}
1569
1570impl<B, V, I, W, S> View<B, V, I, W, S, RangeTo<usize>> for Tess<B, V, I, W, S>
1571where
1572  B: ?Sized + TessBackend<V, I, W, S>,
1573  V: TessVertexData<S>,
1574  I: TessIndex,
1575  W: TessVertexData<S>,
1576  S: ?Sized,
1577{
1578  fn view(&self, to: RangeTo<usize>) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1579    TessView::sub(self, to.end)
1580  }
1581
1582  fn inst_view(
1583    &self,
1584    to: RangeTo<usize>,
1585    inst_nb: usize,
1586  ) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1587    TessView::inst_sub(self, to.end, inst_nb)
1588  }
1589}
1590
1591impl<B, V, I, W, S> View<B, V, I, W, S, RangeFrom<usize>> for Tess<B, V, I, W, S>
1592where
1593  B: ?Sized + TessBackend<V, I, W, S>,
1594  V: TessVertexData<S>,
1595  I: TessIndex,
1596  W: TessVertexData<S>,
1597  S: ?Sized,
1598{
1599  fn view(&self, from: RangeFrom<usize>) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1600    TessView::slice(self, from.start, self.render_vert_nb() - from.start)
1601  }
1602
1603  fn inst_view(
1604    &self,
1605    from: RangeFrom<usize>,
1606    inst_nb: usize,
1607  ) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1608    TessView::inst_slice(
1609      self,
1610      from.start,
1611      self.render_vert_nb() - from.start,
1612      inst_nb,
1613    )
1614  }
1615}
1616
1617impl<B, V, I, W, S> View<B, V, I, W, S, Range<usize>> for Tess<B, V, I, W, S>
1618where
1619  B: ?Sized + TessBackend<V, I, W, S>,
1620  V: TessVertexData<S>,
1621  I: TessIndex,
1622  W: TessVertexData<S>,
1623  S: ?Sized,
1624{
1625  fn view(&self, range: Range<usize>) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1626    TessView::slice(self, range.start, range.end - range.start)
1627  }
1628
1629  fn inst_view(
1630    &self,
1631    range: Range<usize>,
1632    inst_nb: usize,
1633  ) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1634    TessView::inst_slice(self, range.start, range.end - range.start, inst_nb)
1635  }
1636}
1637
1638impl<B, V, I, W, S> View<B, V, I, W, S, RangeInclusive<usize>> for Tess<B, V, I, W, S>
1639where
1640  B: ?Sized + TessBackend<V, I, W, S>,
1641  V: TessVertexData<S>,
1642  I: TessIndex,
1643  W: TessVertexData<S>,
1644  S: ?Sized,
1645{
1646  fn view(&self, range: RangeInclusive<usize>) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1647    let start = *range.start();
1648    let end = *range.end();
1649    TessView::slice(self, start, end - start + 1)
1650  }
1651
1652  fn inst_view(
1653    &self,
1654    range: RangeInclusive<usize>,
1655    inst_nb: usize,
1656  ) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1657    let start = *range.start();
1658    let end = *range.end();
1659    TessView::inst_slice(self, start, end - start + 1, inst_nb)
1660  }
1661}
1662
1663impl<B, V, I, W, S> View<B, V, I, W, S, RangeToInclusive<usize>> for Tess<B, V, I, W, S>
1664where
1665  B: ?Sized + TessBackend<V, I, W, S>,
1666  V: TessVertexData<S>,
1667  I: TessIndex,
1668  W: TessVertexData<S>,
1669  S: ?Sized,
1670{
1671  fn view(&self, to: RangeToInclusive<usize>) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1672    TessView::sub(self, to.end + 1)
1673  }
1674
1675  fn inst_view(
1676    &self,
1677    to: RangeToInclusive<usize>,
1678    inst_nb: usize,
1679  ) -> Result<TessView<B, V, I, W, S>, TessViewError> {
1680    TessView::inst_sub(self, to.end + 1, inst_nb)
1681  }
1682}