1use crate::*;
2
3impl PolygonInstance {
4 #[inline(always)]
6 pub fn clone_instance(&self) -> PolygonInstance {
7 PolygonInstance {
8 polygon: self.polygon.clone(),
9 state: self.state.clone(),
10 shaders: self.shaders.clone(),
11 id: RenderId::generate(),
12 }
13 }
14 #[inline(always)]
16 pub const fn instance_state(&self) -> &PolygonState { &self.state }
17 #[inline(always)]
19 pub fn instance_state_mut(&mut self) -> &mut PolygonState { &mut self.state }
20
21 #[inline(always)]
23 pub fn swap_vertex(&mut self, other: &mut PolygonInstance) {
24 std::mem::swap(&mut self.polygon, &mut other.polygon);
25 }
26
27 #[inline(always)]
28 fn non_textured_bdl(&self, device: &Device) -> BindGroupLayout {
29 let entries = [
30 PolygonState::matrix_bgl_entry(),
31 PolygonState::material_bgl_entry(),
32 ];
33 bind_group_util::create_bind_group_layout(device, &entries)
34 }
35
36 #[inline(always)]
37 fn textured_bdl(&self, device: &Device) -> BindGroupLayout {
38 bind_group_util::create_bind_group_layout(
39 device,
40 &[
41 PolygonState::matrix_bgl_entry(),
42 PolygonState::material_bgl_entry(),
43 PolygonState::textureview_bgl_entry(),
44 PolygonState::sampler_bgl_entry(),
45 ],
46 )
47 }
48
49 #[inline(always)]
50 fn non_textured_bg(&self, device: &Device, layout: &BindGroupLayout) -> BindGroup {
51 bind_group_util::create_bind_group(
52 device,
53 layout,
54 vec![
55 self.state.matrix_buffer(device).binding_resource(),
56 self.state.material.buffer(device).binding_resource(),
57 ],
58 )
59 }
60 #[inline(always)]
61 fn textured_bg(&self, device: &Device, layout: &BindGroupLayout) -> BindGroup {
62 let (view, sampler) = self.state.textureview_and_sampler(device);
63 bind_group_util::create_bind_group(
64 device,
65 layout,
66 vec![
67 self.state.matrix_buffer(device).binding_resource(),
68 self.state.material.buffer(device).binding_resource(),
69 BindingResource::TextureView(&view),
70 BindingResource::Sampler(&sampler),
71 ],
72 )
73 }
74}
75
76impl Rendered for PolygonInstance {
77 impl_render_id!(id);
78
79 #[inline(always)]
80 fn vertex_buffer(&self, _: &DeviceHandler) -> (Arc<BufferHandler>, Option<Arc<BufferHandler>>) {
81 let polygon = self.polygon.clone();
82 (polygon.0, Some(polygon.1))
83 }
84 #[inline(always)]
85 fn bind_group_layout(&self, device_handler: &DeviceHandler) -> Arc<BindGroupLayout> {
86 Arc::new(match self.state.texture.is_some() {
87 true => self.textured_bdl(device_handler.device()),
88 false => self.non_textured_bdl(device_handler.device()),
89 })
90 }
91 #[inline(always)]
92 fn bind_group(
93 &self,
94 device_handler: &DeviceHandler,
95 layout: &BindGroupLayout,
96 ) -> Arc<BindGroup> {
97 Arc::new(match self.state.texture.is_some() {
98 true => self.textured_bg(device_handler.device(), layout),
99 false => self.non_textured_bg(device_handler.device(), layout),
100 })
101 }
102 #[inline(always)]
103 fn pipeline(
104 &self,
105 device_handler: &DeviceHandler,
106 layout: &PipelineLayout,
107 scene_desc: &SceneDescriptor,
108 ) -> Arc<RenderPipeline> {
109 let device = device_handler.device();
110 let (fragment_module, fragment_entry) = match self.state.texture.is_some() {
111 true => (
112 &self.shaders.tex_fragment_module,
113 self.shaders.tex_fragment_entry,
114 ),
115 false => (&self.shaders.fragment_module, self.shaders.fragment_entry),
116 };
117 let cull_mode = match self.state.backface_culling {
118 true => Some(Face::Back),
119 false => None,
120 };
121 let blend = match self.state.material.alpha_blend {
122 true => Some(BlendState::ALPHA_BLENDING),
123 false => Some(BlendState::REPLACE),
124 };
125 let depth_stencil = match scene_desc.backend_buffer.depth_test {
126 true => Some(DepthStencilState {
127 format: TextureFormat::Depth32Float,
128 depth_write_enabled: Some(true),
129 depth_compare: Some(CompareFunction::Less),
130 stencil: Default::default(),
131 bias: Default::default(),
132 }),
133 false => None,
134 };
135 let sample_count = scene_desc.backend_buffer.sample_count;
136 let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
137 layout: Some(layout),
138 vertex: VertexState {
139 module: &self.shaders.vertex_module,
140 entry_point: Some(self.shaders.vertex_entry),
141 buffers: &[VertexBufferLayout {
142 array_stride: size_of::<AttrVertex>() as BufferAddress,
143 step_mode: VertexStepMode::Vertex,
144 attributes: &[
145 VertexAttribute {
146 format: VertexFormat::Float32x3,
147 offset: 0,
148 shader_location: 0,
149 },
150 VertexAttribute {
151 format: VertexFormat::Float32x2,
152 offset: 3 * 4,
153 shader_location: 1,
154 },
155 VertexAttribute {
156 format: VertexFormat::Float32x3,
157 offset: 2 * 4 + 3 * 4,
158 shader_location: 2,
159 },
160 ],
161 }],
162 compilation_options: Default::default(),
163 },
164 fragment: Some(FragmentState {
165 module: fragment_module,
166 entry_point: Some(fragment_entry),
167 targets: &[Some(ColorTargetState {
168 format: scene_desc.render_texture.format,
169 blend,
170 write_mask: ColorWrites::ALL,
171 })],
172 compilation_options: Default::default(),
173 }),
174 primitive: PrimitiveState {
175 topology: PrimitiveTopology::TriangleList,
176 front_face: FrontFace::Ccw,
177 cull_mode,
178 polygon_mode: PolygonMode::Fill,
179 ..Default::default()
180 },
181 depth_stencil,
182 multisample: MultisampleState {
183 count: sample_count,
184 mask: !0,
185 alpha_to_coverage_enabled: sample_count > 1,
186 },
187 label: None,
188 multiview_mask: None,
189 cache: None,
190 });
191 Arc::new(pipeline)
192 }
193}