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
use crate::rendering::*;
use crate::ecs;
use std::rc::Rc;
use crate::Instance;
use wgpu;
use wgpu::util::DeviceExt;
/// Any type that may be used as a vertex in a mesh.
pub trait Vertex: Copy + Clone + bytemuck::Pod + bytemuck::Zeroable {
/// The [wgpu::VertexBufferLayout] of the data in the vertex.
const LAYOUT: wgpu::VertexBufferLayout<'static>;
}
/// An [ecs::Component] that allows rendering of an indexed triangle mesh.
pub struct RenderMesh {
renderer: Rc<RenderPipeline>,
vertex_buffer: wgpu::Buffer,
num_vertices: usize,
index_buffer: wgpu::Buffer,
num_indices: usize
}
impl ecs::Component for RenderMesh {}
impl RenderMesh {
/// Creates a new [RenderMesh] using the specified [Instance], [RenderPipeline], vertex and index buffer.
///
/// # Type Parameters
///
/// * `V` - the [Vertex] type to use.
///
/// # Arguments
///
/// * `instance` - the [Instance] to use when creating WGPU objects. Borrowed for the duration of the function call.
/// * `renderer` - a handle to the [RenderPipeline] to be used for rendering.
/// * `vertices` - a [Vec] of the vertices in the mesh.
/// * `indices` - a [Vec] of indices into the vertex buffer, every 3 form a triangle.
///
/// # Returns
///
/// The [RenderMesh] component, which may be added to an [ecs::Entity] for rendering.
pub fn new<V: Vertex>(instance: &Instance, renderer: Rc<RenderPipeline>, vertices: &Vec<V>, indices: &Vec<u32>) -> Self {
let vert_slice = vertices.as_slice();
let ind_slice = indices.as_slice();
let vertex_buffer = instance.raw_device().create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Ebb Builtin RenderMesh - Vertex Buffer"),
contents: bytemuck::cast_slice(vert_slice),
usage: wgpu::BufferUsages::VERTEX
});
let index_buffer = instance.raw_device().create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Ebb Builtin RenderMesh - Index Buffer"),
contents: bytemuck::cast_slice(ind_slice),
usage: wgpu::BufferUsages::INDEX
});
Self { renderer, vertex_buffer, num_vertices: vertices.len(), index_buffer, num_indices: indices.len() }
}
/// Creates a new entity with a [RenderMesh] component using the specified [Instance], [RenderPipeline], vertex and index buffer.
///
/// # Type Parameters
///
/// * `V` - the [Vertex] type to use.
///
/// # Arguments
///
/// * `instance` - the [Instance] to use when creating WGPU objects. Borrowed for the duration of the function call.
/// * `renderer` - a handle to the [RenderPipeline] to be used for rendering.
/// * `vertices` - a [Vec] of the vertices in the mesh.
/// * `indices` - a [Vec] of indices into the vertex buffer, every 3 form a triangle.
///
/// # Returns
///
/// An [ecs::Entity] with a [RenderMesh] component, which may be added to an [ecs::World].
pub fn entity<V: Vertex>(instance: &Instance, renderer: Rc<RenderPipeline>, vertices: &Vec<V>, indices: &Vec<u32>) -> ecs::Entity {
let mut e = ecs::Entity::new();
e.add_component(Self::new(instance, renderer, vertices, indices));
e
}
/// Gets a handle to the internal [RenderPipeline].
///
/// # Returns
///
/// A handle to the internal [RenderPipeline].
pub fn get_renderer(&self) -> Rc<RenderPipeline> {
self.renderer.clone()
}
/// Gets a handle to the internal vertex buffer.
///
/// # Returns
///
/// A handle to the internal [wgpu::Buffer] (vertex buffer).
pub fn get_vertex_buffer(&self) -> &wgpu::Buffer {
&self.vertex_buffer
}
/// Gets the number of vertices in the vertex buffer.
///
/// # Returns
///
/// The number of vertices in the vertex buffer.
pub fn get_num_vertices(&self) -> usize {
self.num_vertices
}
/// Gets a handle to the internal index buffer.
///
/// # Returns
///
/// A handle to the internal [wgpu::Buffer] (index buffer).
pub fn get_index_buffer(&self) -> &wgpu::Buffer {
&self.index_buffer
}
/// Gets the number of indices in the index buffer.
///
/// # Returns
///
/// The number of indices in the index buffer.
pub fn get_num_indices(&self) -> usize {
self.num_indices
}
}