Skip to main content

easy_gpu/assets/render/
material.rs

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