fyrox_graphics/
geometry_buffer.rs

1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! Geometry buffer is a mesh buffer, that could contain multiple vertex buffers and only one
22//! element buffer.
23
24#![warn(missing_docs)]
25
26use crate::{
27    buffer::BufferUsage,
28    core::{array_as_u8_slice, math::TriangleDefinition, Downcast},
29    ElementKind,
30};
31use bytemuck::Pod;
32use std::mem::size_of;
33
34/// Attribute kind of a vertex.
35#[derive(Copy, Clone)]
36#[allow(dead_code)]
37pub enum AttributeKind {
38    /// Floating point 32-bit number.
39    Float,
40    /// Integer unsigned 8-bit number.
41    UnsignedByte,
42    /// Integer unsigned 16-bit number.
43    UnsignedShort,
44    /// Integer unsigned 32-bit number.
45    UnsignedInt,
46}
47
48/// Vertex attribute definition.
49pub struct AttributeDefinition {
50    /// Binding point of the vertex attribute.
51    pub location: u32,
52    /// Vertex attribute kind. See [`AttributeKind`] docs for more info.
53    pub kind: AttributeKind,
54    /// Component count in the vertex. This could be 1,2,3 or 4.
55    pub component_count: usize,
56    /// A flag, that defines whether the attribute is normalized or not. Normalized attributes
57    /// are always real numbers in `[-1.0; 1.0]` range (or `[0.0; 1.0]` for unsigned attributes).
58    pub normalized: bool,
59    /// Defines feed rate of the vertex attribute. 0 - means that the attribute will be unique per
60    /// vertex, 1 - per each drawn instance, 2 - per two instances and so on.
61    pub divisor: u32,
62}
63
64impl AttributeKind {
65    /// Returns attribute size in bytes.
66    pub fn size(self) -> usize {
67        match self {
68            AttributeKind::Float => size_of::<f32>(),
69            AttributeKind::UnsignedByte => size_of::<u8>(),
70            AttributeKind::UnsignedShort => size_of::<u16>(),
71            AttributeKind::UnsignedInt => size_of::<u32>(),
72        }
73    }
74}
75
76/// Untyped vertex buffer data.
77pub struct VertexBufferData<'a> {
78    /// Vertex size.
79    pub element_size: usize,
80    /// Vertex buffer data.
81    pub bytes: Option<&'a [u8]>,
82}
83
84impl<'a> VertexBufferData<'a> {
85    /// Creates a new untyped vertex buffer data from a typed slice. Underlying type must implement
86    /// [`Pod`] trait!
87    pub fn new<T: Pod>(vertices: Option<&'a [T]>) -> Self {
88        Self {
89            element_size: size_of::<T>(),
90            bytes: vertices.map(|v| array_as_u8_slice(v)),
91        }
92    }
93}
94
95/// Vertex buffer descriptor contains information about vertex buffer layout and content usage as
96/// well as the data that will be uploaded to GPU.
97pub struct VertexBufferDescriptor<'a> {
98    /// Vertex buffer usage. See [`BufferUsage`] docs for more info.
99    pub usage: BufferUsage,
100    /// Attributes of the vertex buffer.
101    pub attributes: &'a [AttributeDefinition],
102    /// Data of the vertex buffer. See [`VertexBufferData`] docs for more info.
103    pub data: VertexBufferData<'a>,
104}
105
106/// Describes elements for the geometry buffer.
107pub enum ElementsDescriptor<'a> {
108    /// Triangles are formed by a triple of vertex indices.
109    Triangles(&'a [TriangleDefinition]),
110    /// Lines are formed by a pair of vertex indices.
111    Lines(&'a [[u32; 2]]),
112    /// Points are just straight vertex indices.
113    Points(&'a [u32]),
114}
115
116impl ElementsDescriptor<'_> {
117    /// Returns element kind of the elements' descriptor.
118    pub fn element_kind(&self) -> ElementKind {
119        match self {
120            ElementsDescriptor::Triangles(_) => ElementKind::Triangle,
121            ElementsDescriptor::Lines(_) => ElementKind::Line,
122            ElementsDescriptor::Points(_) => ElementKind::Point,
123        }
124    }
125}
126
127/// Descriptor of the geometry buffer. It essentially binds multiple vertex buffers and one element
128/// buffer.
129pub struct GeometryBufferDescriptor<'a> {
130    /// Vertex buffers of the buffer. There must be at least one vertex buffer.
131    pub buffers: &'a [VertexBufferDescriptor<'a>],
132    /// Usage of the geometry buffer. See [`BufferUsage`] docs for more info.
133    pub usage: BufferUsage,
134    /// Elements of the geometry buffer.
135    pub elements: ElementsDescriptor<'a>,
136}
137
138/// Geometry buffer is a mesh buffer, that could contain multiple vertex buffers and only one
139/// element buffer. Element could be either a line or triangle (the most commonly used one).
140///
141/// ## Examples
142///
143/// The simplest possible example shows how to create a geometry buffer that has a single triangle:
144///
145/// ```rust
146/// use fyrox_graphics::{
147///     buffer::BufferUsage,
148///     core::{algebra::Vector3, math::TriangleDefinition},
149///     error::FrameworkError,
150///     geometry_buffer::{
151///         AttributeDefinition, AttributeKind, ElementsDescriptor, GeometryBuffer,
152///         GeometryBufferDescriptor, VertexBufferData, VertexBufferDescriptor,
153///     },
154///     server::GraphicsServer,
155/// };
156/// use bytemuck::{Pod, Zeroable};
157///
158/// // Vertex type must implement a bunch of traits, that guarantees that the data will be tightly
159/// // packed with expected order of elements.
160/// #[derive(Pod, Copy, Clone, Zeroable)]
161/// #[repr(C)]
162/// struct Vertex {
163///     position: Vector3<f32>,
164/// }
165///
166/// fn create_geometry_buffer(
167///     server: &dyn GraphicsServer,
168/// ) -> Result<Box<dyn GeometryBuffer>, FrameworkError> {
169///     let vertices = [
170///         Vertex {
171///             position: Vector3::new(0.0, 0.0, 0.0),
172///         },
173///         Vertex {
174///             position: Vector3::new(0.0, 1.0, 0.0),
175///         },
176///         Vertex {
177///             position: Vector3::new(1.0, 0.0, 0.0),
178///         },
179///     ];
180///
181///     let triangles = [TriangleDefinition([0, 1, 2])];
182///
183///     server.create_geometry_buffer(GeometryBufferDescriptor {
184///         buffers: &[VertexBufferDescriptor {
185///             usage: BufferUsage::StaticDraw,
186///             attributes: &[AttributeDefinition {
187///                 location: 0,
188///                 kind: AttributeKind::Float,
189///                 component_count: 3,
190///                 normalized: false,
191///                 divisor: 0,
192///             }],
193///             data: VertexBufferData::new(Some(&vertices)),
194///         }],
195///         usage: BufferUsage::StaticDraw,
196///         elements: ElementsDescriptor::Triangles(&triangles),
197///     })
198/// }
199/// ```
200pub trait GeometryBuffer: Downcast {
201    /// Write untyped data to a vertex buffer with the given index.
202    fn set_buffer_data(&self, buffer: usize, data: &[u8]);
203
204    /// Returns total number of elements in the geometry buffer.
205    fn element_count(&self) -> usize;
206
207    /// Writes triangles to the buffer. Each triangle definition contains triangle indices, that
208    /// forms the triangle.
209    fn set_triangles(&self, triangles: &[TriangleDefinition]);
210
211    /// Writes lines to the buffer. Each pair defines starting and ending vertex index of the line.
212    fn set_lines(&self, lines: &[[u32; 2]]);
213
214    /// Writes points to the buffer. Each index in the slice defines vertex index.
215    fn set_points(&self, points: &[u32]);
216}
217
218impl dyn GeometryBuffer {
219    /// Writes a typed data to a vertex buffer with the given index. Underlying type must implement
220    /// [`Pod`] trait!
221    pub fn set_buffer_data_of_type<T: Pod>(&mut self, buffer: usize, data: &[T]) {
222        self.set_buffer_data(buffer, array_as_u8_slice(data))
223    }
224}