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