1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
//! Tessellation features. //! //! # Tessellation mode //! //! Tessellation is geometric information. Currently, several kinds of tessellation are supported: //! //! - *point clouds*; //! - *lines*; //! - *line strips*; //! - *triangles*; //! - *triangle fans*; //! - *triangle strips*. //! //! Those kinds of tessellation are designated by the `Mode` type. //! //! # Tessellation abstraction //! //! The tessellation is an abstract concept that depends on the backend. That’s why tessellation is an //! associated type found in the `HasTess` trait. //! //! You create a new tessellation with the `new` function. use buffer::{BufferError, BufferSlice, BufferSliceMut, HasBuffer}; use vertex::{Vertex, VertexFormat}; /// Vertices can be connected via several modes. #[derive(Copy, Clone, Debug)] pub enum Mode { /// A single point. Point, /// A line, defined by two points. Line, /// A strip line, defined by at least two points and zero or many other ones. LineStrip, /// A triangle, defined by three points. Triangle, /// A triangle fan, defined by at least three points and zero or many other ones. TriangleFan, /// A triangle strip, defined by at least three points and zero or many other ones. TriangleStrip } /// Trait to implement to provide tessellation features. pub trait HasTess: HasBuffer { /// A type representing tessellation on GPU. type Tess; /// Create a tessellation from its vertices and a `Mode`. /// /// If `indices == None`, the `vertices` represent an array of vertices that are connected to each /// others in the order they appear. If you want to connect them in another way, you can index /// them with `Some(indices)`. fn new_tess<T>(mode: Mode, vertices: &[T], indices: Option<&[u32]>) -> Self::Tess where T: Vertex; /// Destroy a tessellation. fn destroy_tess(tessellation: &mut Self::Tess); /// Create a tessellation that will procedurally generate its vertices (i.e. *attribute-less*). /// /// You just have to give the `Mode` to use and the number of vertices the tessellation must /// have. You’ll be handed back a tessellation object that doesn’t actually hold anything. You /// will have to generate the vertices on the fly in your shaders. fn attributeless(mode: Mode, vert_nb: usize) -> Self::Tess; /// Retrieve the vertex format the tessellation was created with. fn vertex_format(tessellation: &Self::Tess) -> &VertexFormat; /// Get a reference to the vertex buffer and the number of elements in it. fn get_vertex_buffer_ref_mut(tessellation: &mut Self::Tess) -> Option<(&mut Self::ABuffer, usize)>; } /// GPU tessellation. #[derive(Debug)] pub struct Tess<C> where C: HasTess { pub repr: C::Tess } impl<C> Tess<C> where C: HasTess { /// Create a new tessellation. /// /// The `mode` argument gives the type of the primitives and how to interpret the `vertices` and /// `indices` slices. If `indices` is set to `None`, the tessellation will use the `vertices` /// as-is. pub fn new<T>(mode: Mode, vertices: &[T], indices: Option<&[u32]>) -> Tess<C> where T: Vertex { Tess { repr: C::new_tess(mode, vertices, indices) } } /// Create a tessellation that will procedurally generate its vertices (i.e. *attribute-less*). /// /// You just have to give the `Mode` to use and the number of vertices the tessellation must /// have. You’ll be handed back a tessellation object that doesn’t actually hold anything. You /// will have to generate the vertices on the fly in your shaders. pub fn attributeless(mode: Mode, vert_nb: usize) -> Tess<C> { Tess { repr: C::attributeless(mode, vert_nb) } } fn get_vertex_buffer<T>(&mut self) -> Result<(&mut C::ABuffer, usize), TessMapError> where T: Vertex { { let live_vf = C::vertex_format(&self.repr); let req_vf = T::vertex_format(); if live_vf != &req_vf { return Err(TessMapError::MismatchVertexFormat(live_vf.clone(), req_vf)); } } match C::get_vertex_buffer_ref_mut(&mut self.repr) { Some(x) => Ok(x), None => Err(TessMapError::ForbiddenAttributelessMapping) } } pub fn get<T>(&mut self) -> Result<BufferSlice<C, T>, TessMapError> where T: Vertex { let (vertex_buffer, len) = self.get_vertex_buffer::<T>()?; BufferSlice::map(vertex_buffer, len).map_err(TessMapError::VertexBufferMapFailed) } pub fn get_mut<T>(&mut self) -> Result<BufferSliceMut<C, T>, TessMapError> where T: Vertex { let (vertex_buffer, len) = self.get_vertex_buffer::<T>()?; BufferSliceMut::map_mut(vertex_buffer, len).map_err(TessMapError::VertexBufferMapFailed) } } impl<C> Drop for Tess<C> where C: HasTess { fn drop(&mut self) { C::destroy_tess(&mut self.repr); } } /// Error that can occur while trying to map GPU tessellation to host code. #[derive(Debug, Eq, PartialEq)] pub enum TessMapError { MismatchVertexFormat(VertexFormat, VertexFormat), VertexBufferMapFailed(BufferError), ForbiddenAttributelessMapping }