truck_rendimpl/
polygon_instance.rs

1use crate::*;
2
3impl PolygonInstance {
4    /// Clone the instance as another drawn element.
5    #[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    /// Returns a reference to the instance descriptor.
15    #[inline(always)]
16    pub const fn instance_state(&self) -> &PolygonState { &self.state }
17    /// Returns the mutable reference to instance descriptor.
18    #[inline(always)]
19    pub fn instance_state_mut(&mut self) -> &mut PolygonState { &mut self.state }
20
21    /// swap vertex buffers and index buffers
22    #[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}