Skip to main content

easy_gpu/assets/render/
material.rs

1use wgpu::Device;
2use crate::assets::buffer::Buffer;
3use crate::assets_manager::handle::Handle;
4use crate::assets::render::pipeline::RenderPipeline;
5use crate::assets::texture::Texture;
6use crate::assets_manager::asset_manager::AssetManager;
7
8pub struct Material {
9    pub bind_group: wgpu::BindGroup,
10    pub pipeline: Handle<RenderPipeline>,
11}
12
13pub struct MaterialBuilder {
14    textures: Vec<(u32,u32, Handle<Texture>)>,
15    uniforms: Vec<(u32,Handle<Buffer>)>,
16    pipeline: Handle<RenderPipeline>,
17}
18
19impl MaterialBuilder {
20    pub fn new(
21        pipeline: Handle<RenderPipeline>,
22    ) -> Self {
23        Self {
24            textures: Vec::new(),
25            uniforms: Vec::new(),
26            pipeline,
27        }
28    }
29
30    pub fn texture(
31        mut self,
32        texture_binding: u32,
33        sampler_binding: u32,
34        texture: Handle<Texture>,
35    ) -> Self {
36        self.textures.push((texture_binding,sampler_binding, texture));
37        self
38    }
39
40
41    pub fn uniform(
42        mut self,
43        binding: u32,
44        buffer: Handle<Buffer>,
45    ) -> Self {
46        self.uniforms.push((binding, buffer));
47        self
48    }
49
50    pub fn build(self,device:&Device, asset_manager: &AssetManager) -> Material {
51        let pipeline = asset_manager.render_pipelines.get(self.pipeline.clone()).unwrap();
52
53        let mut entries = Vec::new();
54
55        for (binding,handle) in self.uniforms {
56            let uniform = asset_manager.buffers.get(handle).unwrap();
57            entries.push(wgpu::BindGroupEntry {
58                binding,
59                resource: uniform.buffer.as_entire_binding(),
60            });
61        }
62
63        for (tex_binding,sampler_binding,handle) in self.textures {
64            let texture = asset_manager.textures.get(handle).unwrap();
65        entries.push(wgpu::BindGroupEntry {
66                 binding: tex_binding,
67                 resource: wgpu::BindingResource::TextureView(&texture.view),
68             });
69            entries.push(wgpu::BindGroupEntry {
70                binding: sampler_binding,
71                resource: wgpu::BindingResource::Sampler(&texture.sampler),
72            });
73        }
74
75        let bind_group = device.create_bind_group(
76            &wgpu::BindGroupDescriptor {
77                label: Some("material bind group"),
78                layout: &pipeline.material_layout,
79                entries: &entries,
80            }
81        );
82
83        Material {
84            bind_group,
85            pipeline: self.pipeline,
86        }
87    }
88}