1
2use crate::prelude::*;
3use std::{
4 any::type_name,
5 fmt::{self, Debug, Formatter},
6 marker::PhantomData,
7 rc::Rc,
8};
9
10#[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#[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#[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
58pub 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 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 pub fn flush(&mut self) -> Result<(), GLCoreError> {
88 self.vertex_buffer.flush()?;
89 if let Some(element_buffer) = &mut self.element_buffer {
90 element_buffer.flush()?;
91 }
92 if let Some(instance_buffer) = &mut self.instance_buffer {
93 instance_buffer.flush()?;
94 }
95 if let Some(command_buffer) = &mut self.command_buffer {
96 command_buffer.flush()?;
97 }
98 Ok(())
99 }
100}
101
102impl ElementType {
103 pub fn get_size(&self) -> usize {
105 match self {
106 Self::U8 => 1,
107 Self::U16 => 2,
108 Self::U32 => 4,
109 }
110 }
111}
112
113pub trait GenericMesh: Debug {
115 fn get_primitive(&self) -> PrimitiveMode;
117
118 fn get_vertex_buffer(&self) -> &Buffer;
120
121 fn get_element_buffer(&self) -> Option<&Buffer>;
123
124 fn get_element_type(&self) -> ElementType;
126
127 fn get_instance_buffer(&self) -> Option<&Buffer>;
129
130 fn get_command_buffer(&self) -> Option<&Buffer>;
132
133 fn get_vertex_stride(&self) -> usize;
135
136 fn get_instance_stride(&self) -> usize;
138
139 fn get_vertex_count(&self) -> usize;
141
142 fn get_element_count(&self) -> usize;
144
145 fn get_instance_count(&self) -> usize;
147
148 fn get_command_count(&self) -> usize;
150
151 fn flush(&mut self) -> Result<(), GLCoreError> {Ok(())}
153
154 fn bind_vertex_buffer<'a>(&'a self) -> Result<BufferBind<'a>, GLCoreError> {
156 self.get_vertex_buffer().bind_to(BufferTarget::ArrayBuffer)
157 }
158
159 fn bind_element_buffer<'a>(&'a self) -> Result<Option<BufferBind<'a>>, GLCoreError> {
161 if let Some(element_buffer) = self.get_element_buffer() {
162 Ok(Some(element_buffer.bind_to(BufferTarget::ElementArrayBuffer)?))
163 } else {
164 Ok(None)
165 }
166 }
167
168 fn bind_instance_buffer<'a>(&'a self) -> Result<Option<BufferBind<'a>>, GLCoreError> {
170 if let Some(instance_buffer) = self.get_instance_buffer() {
171 Ok(Some(instance_buffer.bind_to(BufferTarget::ArrayBuffer)?))
172 } else {
173 Ok(None)
174 }
175 }
176
177 fn bind_command_buffer<'a>(&'a self) -> Result<Option<BufferBind<'a>>, GLCoreError> {
179 if let Some(command_buffer) = self.get_command_buffer() {
180 Ok(Some(command_buffer.bind_to(BufferTarget::DrawIndirectBuffer)?))
181 } else {
182 Ok(None)
183 }
184 }
185}
186
187impl<BV, V, BE, E, BI, I, BC, C> GenericMesh for Mesh<BV, V, BE, E, BI, I, BC, C>
188where
189 BV: BufferVec<V>,
190 BE: BufferVec<E>,
191 BI: BufferVec<I>,
192 BC: BufferVec<C>,
193 V: BufferVecItem,
194 E: BufferVecItem,
195 I: BufferVecItem,
196 C: BufferVecItem {
197 fn get_primitive(&self) -> PrimitiveMode {
198 self.primitive
199 }
200
201 fn get_vertex_buffer(&self) -> &Buffer {
202 self.vertex_buffer.get_buffer()
203 }
204
205 fn get_element_buffer(&self) -> Option<&Buffer> {
206 if let Some(buffer) = &self.element_buffer {
207 Some(buffer.get_buffer())
208 } else {
209 None
210 }
211 }
212
213 fn get_element_type(&self) -> ElementType {
214 match size_of::<E>() {
215 1 => ElementType::U8,
216 2 => ElementType::U16,
217 4 => ElementType::U32,
218 _ => panic!("Unsupported element type: {}", type_name::<E>()),
219 }
220 }
221
222 fn get_instance_buffer(&self) -> Option<&Buffer> {
223 if let Some(buffer) = &self.instance_buffer {
224 Some(buffer.get_buffer())
225 } else {
226 None
227 }
228 }
229
230 fn get_command_buffer(&self) -> Option<&Buffer> {
231 if let Some(buffer) = &self.command_buffer {
232 Some(buffer.get_buffer())
233 } else {
234 None
235 }
236 }
237
238 fn get_vertex_stride(&self) -> usize {
239 size_of::<V>()
240 }
241
242 fn get_instance_stride(&self) -> usize {
243 size_of::<I>()
244 }
245
246 fn get_vertex_count(&self) -> usize {
247 self.vertex_buffer.len()
248 }
249
250 fn get_element_count(&self) -> usize {
251 if let Some(element_buffer) = &self.element_buffer {
252 element_buffer.len()
253 } else {
254 0
255 }
256 }
257
258 fn get_instance_count(&self) -> usize {
259 if let Some(buffer) = &self.instance_buffer {
260 buffer.len()
261 } else {
262 0
263 }
264 }
265
266 fn get_command_count(&self) -> usize {
267 if let Some(buffer) = &self.command_buffer {
268 buffer.len()
269 } else {
270 0
271 }
272 }
273
274 fn flush(&mut self) -> Result<(), GLCoreError> {
275 Mesh::flush(self)
276 }
277}
278
279impl Debug for PrimitiveMode {
280 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
281 match self {
282 Self::Points => write!(f, "Points"),
283 Self::LineStrip => write!(f, "Line Strip"),
284 Self::LineLoop => write!(f, "Line Loop"),
285 Self::Lines => write!(f, "Lines"),
286 Self::LineStripAdjacency => write!(f, "Line Strip Adjacency"),
287 Self::LinesAdjacency => write!(f, "Lines Adjacency"),
288 Self::TriangleStrip => write!(f, "Triangle Strip"),
289 Self::TriangleFan => write!(f, "Triangle Fan"),
290 Self::Triangles => write!(f, "Triangles"),
291 Self::TriangleStripAdjacency => write!(f, "Triangle Strip Adjacency"),
292 Self::TrianglesAdjacency => write!(f, "Triangles Adjacency"),
293 Self::Patches => write!(f, "Patches"),
294 }
295 }
296}
297
298impl Debug for ElementType {
299 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
300 match self {
301 Self::U8 => write!(f, "U8"),
302 Self::U16 => write!(f, "U16"),
303 Self::U32 => write!(f, "U32"),
304 }
305 }
306}
307
308#[derive(Debug, Clone)]
309pub struct MeshWithMaterial<M: GenericMesh, Mat: Material> {
310 material: Rc<Mat>,
311 mesh: M,
312}
313
314impl<M: GenericMesh, Mat: Material> MeshWithMaterial<M, Mat> {
315 pub fn new(mesh: M, material: Rc<Mat>) -> Self {
316 Self {
317 material,
318 mesh,
319 }
320 }
321
322 pub fn get_material(&self) -> &Mat {
323 &self.material
324 }
325}
326
327impl<M: GenericMesh, Mat: Material> GenericMesh for MeshWithMaterial<M, Mat> {
328 fn get_primitive(&self) -> PrimitiveMode {
329 self.mesh.get_primitive()
330 }
331
332 fn get_vertex_buffer(&self) -> &Buffer {
333 self.mesh.get_vertex_buffer()
334 }
335
336 fn get_element_buffer(&self) -> Option<&Buffer> {
337 self.mesh.get_element_buffer()
338 }
339
340 fn get_element_type(&self) -> ElementType {
341 self.mesh.get_element_type()
342 }
343
344 fn get_instance_buffer(&self) -> Option<&Buffer> {
345 self.mesh.get_instance_buffer()
346 }
347
348 fn get_command_buffer(&self) -> Option<&Buffer> {
349 self.mesh.get_command_buffer()
350 }
351
352 fn get_vertex_stride(&self) -> usize {
353 self.mesh.get_vertex_stride()
354 }
355
356 fn get_instance_stride(&self) -> usize {
357 self.mesh.get_instance_stride()
358 }
359
360 fn get_vertex_count(&self) -> usize {
361 self.mesh.get_vertex_count()
362 }
363
364 fn get_element_count(&self) -> usize {
365 self.mesh.get_element_count()
366 }
367
368 fn get_instance_count(&self) -> usize {
369 self.mesh.get_instance_count()
370 }
371
372 fn get_command_count(&self) -> usize {
373 self.mesh.get_command_count()
374 }
375}
376
377pub trait GenericMeshWithMaterial: GenericMesh {
379 fn get_material(&self) -> Option<&dyn Material>;
380}
381
382impl<BV, V, BE, E, BI, I, BC, C> GenericMeshWithMaterial for Mesh<BV, V, BE, E, BI, I, BC, C>
383where
384 BV: BufferVec<V>,
385 BE: BufferVec<E>,
386 BI: BufferVec<I>,
387 BC: BufferVec<C>,
388 V: BufferVecItem,
389 E: BufferVecItem,
390 I: BufferVecItem,
391 C: BufferVecItem {
392 fn get_material(&self) -> Option<&dyn Material> {
393 None
394 }
395}
396
397impl<M: GenericMesh, Mat: Material> GenericMeshWithMaterial for MeshWithMaterial<M, Mat> {
398 fn get_material(&self) -> Option<&dyn Material> {
399 Some(&*self.material)
400 }
401}