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) {
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 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
106pub trait GenericMesh: Debug {
108 fn get_primitive(&self) -> PrimitiveMode;
110
111 fn get_vertex_buffer(&self) -> &Buffer;
113
114 fn get_element_buffer(&self) -> Option<&Buffer>;
116
117 fn get_element_type(&self) -> ElementType;
119
120 fn get_instance_buffer(&self) -> Option<&Buffer>;
122
123 fn get_command_buffer(&self) -> Option<&Buffer>;
125
126 fn get_vertex_stride(&self) -> usize;
128
129 fn get_instance_stride(&self) -> usize;
131
132 fn get_vertex_count(&self) -> usize;
134
135 fn get_element_count(&self) -> usize;
137
138 fn get_instance_count(&self) -> usize;
140
141 fn get_command_count(&self) -> usize;
143
144 fn flush(&mut self) {}
146
147 fn bind_vertex_buffer<'a>(&'a self) -> BufferBind<'a> {
149 self.get_vertex_buffer().bind_to(BufferTarget::ArrayBuffer)
150 }
151
152 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 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 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
358pub 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}