Skip to main content

easy_gpu/assets/render/
material.rs

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