1use crate::{assets::upload::Asset, wgpu::backend::WGPUBackend};
2
3#[repr(C)]
12#[derive(Copy, Clone, Default, bytemuck::Pod, bytemuck::Zeroable)]
13pub struct Vertex {
14 pub position: glam::Vec3,
15 pub tex_coords: glam::Vec2,
16 pub normal: glam::Vec3,
17 pub tangent: glam::Vec4,
18}
19
20impl Vertex {
21 pub fn new(
22 position: glam::Vec3,
23 tex_coords: glam::Vec2,
24 normal: glam::Vec3,
25 tangent: glam::Vec4,
26 ) -> Self {
27 Self {
28 position,
29 tex_coords,
30 normal,
31 tangent,
32 }
33 }
34
35 pub fn layout() -> wgpu::VertexBufferLayout<'static> {
36 const ATTRS: &[wgpu::VertexAttribute] = &wgpu::vertex_attr_array![
37 0 => Float32x3, 1 => Float32x2, 2 => Float32x3, 3 => Float32x4, ];
42 wgpu::VertexBufferLayout {
43 array_stride: std::mem::size_of::<Vertex>() as wgpu::BufferAddress,
44 step_mode: wgpu::VertexStepMode::Vertex,
45 attributes: ATTRS,
46 }
47 }
48}
49
50#[repr(C)]
53#[derive(Copy, Clone, Default, bytemuck::Pod, bytemuck::Zeroable)]
54pub struct InstanceVertex {
55 pub model: glam::Mat4,
56}
57
58impl InstanceVertex {
59 pub fn new(model: glam::Mat4) -> Self {
60 Self { model }
61 }
62
63 pub fn layout() -> wgpu::VertexBufferLayout<'static> {
64 const ATTRS: &[wgpu::VertexAttribute] = &wgpu::vertex_attr_array![
65 4 => Float32x4, 5 => Float32x4, 6 => Float32x4, 7 => Float32x4, ];
70 wgpu::VertexBufferLayout {
71 array_stride: std::mem::size_of::<InstanceVertex>() as wgpu::BufferAddress,
72 step_mode: wgpu::VertexStepMode::Instance,
73 attributes: ATTRS,
74 }
75 }
76}
77
78pub struct MeshDescriptor {
80 pub vertices: Vec<Vertex>,
81 pub indices: Vec<u32>,
82}
83
84pub struct GPUMesh {
89 pub vertex_buffer: wgpu::Buffer,
90 pub index_buffer: wgpu::Buffer,
91 pub index_count: u32,
92}
93
94impl Asset<WGPUBackend> for GPUMesh {
95 type Source = MeshDescriptor;
96 type Deps<'a> = ();
97
98 fn upload<'a>(source: &MeshDescriptor, backend: &WGPUBackend, _deps: &()) -> Option<Self> {
99 use wgpu::util::DeviceExt;
100 let vertex_buffer = backend
101 .device
102 .create_buffer_init(&wgpu::util::BufferInitDescriptor {
103 label: Some("Mesh Vertex Buffer"),
104 contents: bytemuck::cast_slice(source.vertices.as_slice()),
105 usage: wgpu::BufferUsages::VERTEX,
106 });
107 let index_buffer = backend
108 .device
109 .create_buffer_init(&wgpu::util::BufferInitDescriptor {
110 label: Some("Mesh Index Buffer"),
111 contents: bytemuck::cast_slice(&source.indices),
112 usage: wgpu::BufferUsages::INDEX,
113 });
114 Some(Self {
115 vertex_buffer,
116 index_buffer,
117 index_count: source.indices.len() as u32,
118 })
119 }
120}
121
122crate::wgpu::plugin_macros::asset_plugin! {
123 MeshPlugin, GPUMesh
128}