easy_gpu/assets/render/
material.rs1use 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}