globject_rs/
mesh.rs

1
2use crate::prelude::*;
3use std::{
4	any::type_name,
5	fmt::{self, Debug, Formatter},
6	marker::PhantomData,
7	rc::Rc,
8};
9
10/// The primitive mode of the mesh, indicating how to draw the vertices to which type of the shapes
11#[derive(Clone, Copy, PartialEq)]
12pub enum PrimitiveMode {
13	Points = GL_POINTS as isize,
14	LineStrip = GL_LINE_STRIP as isize,
15	LineLoop = GL_LINE_LOOP as isize,
16	Lines = GL_LINES as isize,
17	LineStripAdjacency = GL_LINE_STRIP_ADJACENCY as isize,
18	LinesAdjacency = GL_LINES_ADJACENCY as isize,
19	TriangleStrip = GL_TRIANGLE_STRIP as isize,
20	TriangleFan = GL_TRIANGLE_FAN as isize,
21	Triangles = GL_TRIANGLES as isize,
22	TriangleStripAdjacency = GL_TRIANGLE_STRIP_ADJACENCY as isize,
23	TrianglesAdjacency = GL_TRIANGLES_ADJACENCY as isize,
24	Patches = GL_PATCHES as isize,
25}
26
27/// The type of the element buffer of the mesh, indicating the vertices were indexed by which type of index
28#[derive(Clone, Copy, PartialEq)]
29pub enum ElementType {
30	U8 = GL_UNSIGNED_BYTE as isize,
31	U16 = GL_UNSIGNED_SHORT as isize,
32	U32 = GL_UNSIGNED_INT as isize,
33}
34
35/// The mesh, every type of buffer is wrapped in a `BufferVec` can be manipulated just like a `Vec`
36#[derive(Debug, Clone)]
37pub struct Mesh<BV, V, BE, E, BI, I, BC, C>
38where
39	BV: BufferVec<V>,
40	BE: BufferVec<E>,
41	BI: BufferVec<I>,
42	BC: BufferVec<C>,
43	V: BufferVecItem,
44	E: BufferVecItem,
45	I: BufferVecItem,
46	C: BufferVecItem {
47	pub primitive: PrimitiveMode,
48	pub vertex_buffer: BV,
49	pub element_buffer: Option<BE>,
50	pub instance_buffer: Option<BI>,
51	pub command_buffer: Option<BC>,
52	_vertex_type: PhantomData<V>,
53	_element_type: PhantomData<E>,
54	_instance_type: PhantomData<I>,
55	_command_type: PhantomData<C>,
56}
57
58/// The most typical static mesh type: use `BufferVecStatic` for vertices and elements(indices), use `BufferVecDynamic` for instances and draw commands
59pub type StaticMesh<V, E, I, C> = Mesh<BufferVecStatic<V>, V, BufferVecStatic<E>, E, BufferVecDynamic<I>, I, BufferVecDynamic<C>, C>;
60
61impl<BV, V, BE, E, BI, I, BC, C> Mesh<BV, V, BE, E, BI, I, BC, C>
62where
63	BV: BufferVec<V>,
64	BE: BufferVec<E>,
65	BI: BufferVec<I>,
66	BC: BufferVec<C>,
67	V: BufferVecItem,
68	E: BufferVecItem,
69	I: BufferVecItem,
70	C: BufferVecItem {
71	/// Create a new dynamic mesh from the buffers
72	pub fn new(primitive: PrimitiveMode, vertex_buffer: BV, element_buffer: Option<BE>, instance_buffer: Option<BI>, command_buffer: Option<BC>) -> Self {
73		Self {
74			primitive,
75			vertex_buffer,
76			element_buffer,
77			instance_buffer,
78			command_buffer,
79			_vertex_type: PhantomData,
80			_element_type: PhantomData,
81			_instance_type: PhantomData,
82			_command_type: PhantomData,
83		}
84	}
85
86	/// Flush all of the buffers' caches to the GPU
87	pub fn flush(&mut self) {
88		self.vertex_buffer.flush();
89		self.element_buffer.as_mut().map(|b|b.flush());
90		self.instance_buffer.as_mut().map(|b|b.flush());
91		self.command_buffer.as_mut().map(|b|b.flush());
92	}
93}
94
95impl ElementType {
96	/// Get the size of each index
97	pub fn get_size(&self) -> usize {
98		match self {
99			Self::U8 => 1,
100			Self::U16 => 2,
101			Self::U32 => 4,
102		}
103	}
104}
105
106/// The `GenericMesh` trait helps the `Mesh` struct to be able to turn into an object
107pub trait GenericMesh: Debug {
108	/// Get the primitive mode of the mesh
109	fn get_primitive(&self) -> PrimitiveMode;
110
111	/// Get the vertex buffer of the mesh
112	fn get_vertex_buffer(&self) -> &Buffer;
113
114	/// Get the element buffer of the mesh
115	fn get_element_buffer(&self) -> Option<&Buffer>;
116
117	/// Get the type of the element buffer
118	fn get_element_type(&self) -> ElementType;
119
120	/// Get the instance buffer of the mesh
121	fn get_instance_buffer(&self) -> Option<&Buffer>;
122
123	/// Get the draw command buffer of the mesh
124	fn get_command_buffer(&self) -> Option<&Buffer>;
125
126	/// Get the size of each vertex
127	fn get_vertex_stride(&self) -> usize;
128
129	/// Get the size of each instance
130	fn get_instance_stride(&self) -> usize;
131
132	/// Get the number of vertices
133	fn get_vertex_count(&self) -> usize;
134
135	/// Get the number of the elements
136	fn get_element_count(&self) -> usize;
137
138	/// Get the number of the instances
139	fn get_instance_count(&self) -> usize;
140
141	/// Get the number of the draw commands
142	fn get_command_count(&self) -> usize;
143
144	/// Flush the cache if the mesh has a caching system
145	fn flush(&mut self) {}
146
147	/// Bind the vertex buffer
148	fn bind_vertex_buffer<'a>(&'a self) -> BufferBind<'a> {
149		self.get_vertex_buffer().bind_to(BufferTarget::ArrayBuffer)
150	}
151
152	/// Bind the element buffer
153	fn bind_element_buffer<'a>(&'a self) -> Option<BufferBind<'a>> {
154		self.get_element_buffer().map(|b|b.bind_to(BufferTarget::ElementArrayBuffer))
155	}
156
157	/// Bind the instance buffer
158	fn bind_instance_buffer<'a>(&'a self) -> Option<BufferBind<'a>> {
159		self.get_instance_buffer().map(|b|b.bind_to(BufferTarget::ArrayBuffer))
160	}
161
162	/// Bind the command buffer
163	fn bind_command_buffer<'a>(&'a self) -> Option<BufferBind<'a>> {
164		self.get_command_buffer().map(|b|b.bind_to(BufferTarget::DrawIndirectBuffer))
165	}
166}
167
168impl<BV, V, BE, E, BI, I, BC, C> GenericMesh for Mesh<BV, V, BE, E, BI, I, BC, C>
169where
170	BV: BufferVec<V>,
171	BE: BufferVec<E>,
172	BI: BufferVec<I>,
173	BC: BufferVec<C>,
174	V: BufferVecItem,
175	E: BufferVecItem,
176	I: BufferVecItem,
177	C: BufferVecItem {
178	fn get_primitive(&self) -> PrimitiveMode {
179		self.primitive
180	}
181
182	fn get_vertex_buffer(&self) -> &Buffer {
183		self.vertex_buffer.get_buffer()
184	}
185	
186	fn get_element_buffer(&self) -> Option<&Buffer> {
187		if let Some(buffer) = &self.element_buffer {
188			Some(buffer.get_buffer())
189		} else {
190			None
191		}
192	}
193
194	fn get_element_type(&self) -> ElementType {
195		match size_of::<E>() {
196			1 => ElementType::U8,
197			2 => ElementType::U16,
198			4 => ElementType::U32,
199			_ => panic!("Unsupported element type: {}", type_name::<E>()),
200		}
201	}
202
203	fn get_instance_buffer(&self) -> Option<&Buffer> {
204		if let Some(buffer) = &self.instance_buffer {
205			Some(buffer.get_buffer())
206		} else {
207			None
208		}
209	}
210
211	fn get_command_buffer(&self) -> Option<&Buffer> {
212		if let Some(buffer) = &self.command_buffer {
213			Some(buffer.get_buffer())
214		} else {
215			None
216		}
217	}
218
219	fn get_vertex_stride(&self) -> usize {
220		size_of::<V>()
221	}
222
223	fn get_instance_stride(&self) -> usize {
224		size_of::<I>()
225	}
226
227	fn get_vertex_count(&self) -> usize {
228		self.vertex_buffer.len()
229	}
230
231	fn get_element_count(&self) -> usize {
232		if let Some(element_buffer) = &self.element_buffer {
233			element_buffer.len()
234		} else {
235			0
236		}
237	}
238
239	fn get_instance_count(&self) -> usize {
240		if let Some(buffer) = &self.instance_buffer {
241			buffer.len()
242		} else {
243			0
244		}
245	}
246
247	fn get_command_count(&self) -> usize {
248		if let Some(buffer) = &self.command_buffer {
249			buffer.len()
250		} else {
251			0
252		}
253	}
254
255	fn flush(&mut self) {
256		Mesh::flush(self);
257	}
258}
259
260impl Debug for PrimitiveMode {
261	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
262		match self {
263			Self::Points => write!(f, "Points"),
264			Self::LineStrip => write!(f, "Line Strip"),
265			Self::LineLoop => write!(f, "Line Loop"),
266			Self::Lines => write!(f, "Lines"),
267			Self::LineStripAdjacency => write!(f, "Line Strip Adjacency"),
268			Self::LinesAdjacency => write!(f, "Lines Adjacency"),
269			Self::TriangleStrip => write!(f, "Triangle Strip"),
270			Self::TriangleFan => write!(f, "Triangle Fan"),
271			Self::Triangles => write!(f, "Triangles"),
272			Self::TriangleStripAdjacency => write!(f, "Triangle Strip Adjacency"),
273			Self::TrianglesAdjacency => write!(f, "Triangles Adjacency"),
274			Self::Patches => write!(f, "Patches"),
275		}
276	}
277}
278
279impl Debug for ElementType {
280	fn fmt(&self, f: &mut Formatter) -> fmt::Result {
281		match self {
282			Self::U8 =>  write!(f, "U8"),
283			Self::U16 => write!(f, "U16"),
284			Self::U32 => write!(f, "U32"),
285		}
286	}
287}
288
289#[derive(Debug, Clone)]
290pub struct MeshWithMaterial<M: GenericMesh, Mat: Material> {
291	material: Rc<Mat>,
292	mesh: M,
293}
294
295impl<M: GenericMesh, Mat: Material> MeshWithMaterial<M, Mat> {
296	pub fn new(mesh: M, material: Rc<Mat>) -> Self {
297		Self {
298			material,
299			mesh,
300		}
301	}
302
303	pub fn get_material(&self) -> &Mat {
304		&self.material
305	}
306}
307
308impl<M: GenericMesh, Mat: Material> GenericMesh for MeshWithMaterial<M, Mat> {
309	fn get_primitive(&self) -> PrimitiveMode {
310		self.mesh.get_primitive()
311	}
312
313	fn get_vertex_buffer(&self) -> &Buffer {
314		self.mesh.get_vertex_buffer()
315	}
316
317	fn get_element_buffer(&self) -> Option<&Buffer> {
318		self.mesh.get_element_buffer()
319	}
320
321	fn get_element_type(&self) -> ElementType {
322		self.mesh.get_element_type()
323	}
324
325	fn get_instance_buffer(&self) -> Option<&Buffer> {
326		self.mesh.get_instance_buffer()
327	}
328
329	fn get_command_buffer(&self) -> Option<&Buffer> {
330		self.mesh.get_command_buffer()
331	}
332
333	fn get_vertex_stride(&self) -> usize {
334		self.mesh.get_vertex_stride()
335	}
336
337	fn get_instance_stride(&self) -> usize {
338		self.mesh.get_instance_stride()
339	}
340
341	fn get_vertex_count(&self) -> usize {
342		self.mesh.get_vertex_count()
343	}
344
345	fn get_element_count(&self) -> usize {
346		self.mesh.get_element_count()
347	}
348
349	fn get_instance_count(&self) -> usize {
350		self.mesh.get_instance_count()
351	}
352
353	fn get_command_count(&self) -> usize {
354		self.mesh.get_command_count()
355	}
356}
357
358/// The `GenericMeshWithMaterial` trait helps the `MeshWithMaterial` struct to be able to turn into an object
359pub trait GenericMeshWithMaterial: GenericMesh {
360	fn get_material(&self) -> Option<&dyn Material>;
361}
362
363impl<BV, V, BE, E, BI, I, BC, C> GenericMeshWithMaterial for Mesh<BV, V, BE, E, BI, I, BC, C>
364where
365	BV: BufferVec<V>,
366	BE: BufferVec<E>,
367	BI: BufferVec<I>,
368	BC: BufferVec<C>,
369	V: BufferVecItem,
370	E: BufferVecItem,
371	I: BufferVecItem,
372	C: BufferVecItem {
373	fn get_material(&self) -> Option<&dyn Material> {
374		None
375	}
376}
377
378impl<M: GenericMesh, Mat: Material> GenericMeshWithMaterial for MeshWithMaterial<M, Mat> {
379	fn get_material(&self) -> Option<&dyn Material> {
380		Some(&*self.material)
381	}
382}