1use crate::{
2 assets::upload::Asset,
3 wgpu::{
4 backend::WGPUBackend,
5 buffer::Buffer,
6 buffers::BufferBuilder,
7 flags::BufferUsages,
8 vertex_format::{VertexAttribute, VertexBufferLayout, VertexFormat, VertexStepMode},
9 },
10};
11
12#[repr(C)]
21#[derive(Copy, Clone, Default, bytemuck::Pod, bytemuck::Zeroable)]
22pub struct Vertex {
23 pub position: glam::Vec3,
24 pub tex_coords: glam::Vec2,
25 pub normal: glam::Vec3,
26 pub tangent: glam::Vec4,
27}
28
29impl Vertex {
30 pub fn new(
31 position: glam::Vec3,
32 tex_coords: glam::Vec2,
33 normal: glam::Vec3,
34 tangent: glam::Vec4,
35 ) -> Self {
36 Self {
37 position,
38 tex_coords,
39 normal,
40 tangent,
41 }
42 }
43
44 pub fn layout() -> VertexBufferLayout {
45 VertexBufferLayout {
46 array_stride: std::mem::size_of::<Vertex>() as u64,
47 step_mode: VertexStepMode::Vertex,
48 attributes: vec![
49 VertexAttribute { format: VertexFormat::Float32x3, offset: 0, shader_location: 0 }, VertexAttribute { format: VertexFormat::Float32x2, offset: 12, shader_location: 1 }, VertexAttribute { format: VertexFormat::Float32x3, offset: 20, shader_location: 2 }, VertexAttribute { format: VertexFormat::Float32x4, offset: 32, shader_location: 3 }, ],
54 }
55 }
56}
57
58#[repr(C)]
61#[derive(Copy, Clone, Default, bytemuck::Pod, bytemuck::Zeroable)]
62pub struct InstanceVertex {
63 pub model: glam::Mat4,
64}
65
66impl InstanceVertex {
67 pub fn new(model: glam::Mat4) -> Self {
68 Self { model }
69 }
70
71 pub fn layout() -> VertexBufferLayout {
72 VertexBufferLayout {
73 array_stride: std::mem::size_of::<InstanceVertex>() as u64,
74 step_mode: VertexStepMode::Instance,
75 attributes: vec![
76 VertexAttribute { format: VertexFormat::Float32x4, offset: 0, shader_location: 4 }, VertexAttribute { format: VertexFormat::Float32x4, offset: 16, shader_location: 5 }, VertexAttribute { format: VertexFormat::Float32x4, offset: 32, shader_location: 6 }, VertexAttribute { format: VertexFormat::Float32x4, offset: 48, shader_location: 7 }, ],
81 }
82 }
83}
84
85pub struct MeshDescriptor {
87 pub vertices: Vec<Vertex>,
88 pub indices: Vec<u32>,
89}
90
91pub struct GPUMesh {
96 pub vertex_buffer: Buffer,
97 pub index_buffer: Buffer,
98 pub index_count: u32,
99}
100
101impl Asset<WGPUBackend> for GPUMesh {
102 type Source = MeshDescriptor;
103 type Deps<'a> = ();
104
105 fn upload<'a>(source: &MeshDescriptor, backend: &WGPUBackend, _deps: &()) -> Option<Self> {
106 let vertex_buffer = BufferBuilder::new()
107 .label("Mesh Vertex Buffer")
108 .usage(BufferUsages::VERTEX)
109 .data(bytemuck::cast_slice(source.vertices.as_slice()))
110 .build(backend);
111 let index_buffer = BufferBuilder::new()
112 .label("Mesh Index Buffer")
113 .usage(BufferUsages::INDEX)
114 .data(bytemuck::cast_slice(&source.indices))
115 .build(backend);
116 Some(Self {
117 vertex_buffer,
118 index_buffer,
119 index_count: source.indices.len() as u32,
120 })
121 }
122}
123
124crate::wgpu::plugin_macros::asset_plugin! {
125 MeshPlugin, GPUMesh
130}