truck_rendimpl/
wireframe_instance.rs

1use crate::*;
2
3impl Default for WireFrameState {
4    #[inline(always)]
5    fn default() -> WireFrameState {
6        WireFrameState {
7            matrix: Matrix4::identity(),
8            color: Vector4::new(1.0, 1.0, 1.0, 1.0),
9        }
10    }
11}
12
13impl WireFrameInstance {
14    /// Clone the instance as another drawn element.
15    #[inline(always)]
16    pub fn clone_instance(&self) -> Self {
17        Self {
18            vertices: Arc::clone(&self.vertices),
19            strips: Arc::clone(&self.strips),
20            state: self.state.clone(),
21            shaders: self.shaders.clone(),
22            id: RenderID::gen(),
23        }
24    }
25    /// Returns the wireframe state
26    #[inline(always)]
27    pub const fn instance_state(&self) -> &WireFrameState { &self.state }
28    /// Returns the mutable reference to wireframe state
29    #[inline(always)]
30    pub fn instance_state_mut(&mut self) -> &mut WireFrameState { &mut self.state }
31    /// swap vertex buffers and index buffers
32    #[inline(always)]
33    pub fn swap_vertex(&mut self, other: &mut WireFrameInstance) {
34        std::mem::swap(&mut self.vertices, &mut other.vertices);
35        std::mem::swap(&mut self.strips, &mut other.strips);
36    }
37}
38
39impl Instance for WireFrameInstance {
40    type Shaders = WireShaders;
41    fn standard_shaders(creator: &InstanceCreator) -> WireShaders { creator.wire_shaders.clone() }
42}
43
44impl Rendered for WireFrameInstance {
45    impl_render_id!(id);
46    fn vertex_buffer(&self, _: &DeviceHandler) -> (Arc<BufferHandler>, Option<Arc<BufferHandler>>) {
47        (self.vertices.clone(), Some(self.strips.clone()))
48    }
49    fn bind_group_layout(&self, handler: &DeviceHandler) -> Arc<BindGroupLayout> {
50        Arc::new(bind_group_util::create_bind_group_layout(
51            handler.device(),
52            &[
53                // matrix
54                PreBindGroupLayoutEntry {
55                    visibility: ShaderStages::VERTEX,
56                    ty: BindingType::Buffer {
57                        ty: BufferBindingType::Uniform,
58                        has_dynamic_offset: false,
59                        min_binding_size: None,
60                    },
61                    count: None,
62                },
63                // color
64                PreBindGroupLayoutEntry {
65                    visibility: ShaderStages::FRAGMENT,
66                    ty: BindingType::Buffer {
67                        ty: BufferBindingType::Uniform,
68                        has_dynamic_offset: false,
69                        min_binding_size: None,
70                    },
71                    count: None,
72                },
73            ],
74        ))
75    }
76    fn bind_group(&self, handler: &DeviceHandler, layout: &BindGroupLayout) -> Arc<BindGroup> {
77        let device = handler.device();
78        let matrix_data: [[f32; 4]; 4] = self.state.matrix.cast::<f32>().unwrap().into();
79        let matrix_buffer = BufferHandler::from_slice(&matrix_data, device, BufferUsages::UNIFORM);
80        let color_data: [f32; 4] = self.state.color.cast::<f32>().unwrap().into();
81        let color_buffer = BufferHandler::from_slice(&color_data, device, BufferUsages::UNIFORM);
82        Arc::new(bind_group_util::create_bind_group(
83            device,
84            layout,
85            vec![
86                matrix_buffer.binding_resource(),
87                color_buffer.binding_resource(),
88            ],
89        ))
90    }
91    fn pipeline(
92        &self,
93        handler: &DeviceHandler,
94        layout: &PipelineLayout,
95        scene_desc: &SceneDescriptor,
96    ) -> Arc<RenderPipeline> {
97        let device = handler.device();
98        let sample_count = scene_desc.backend_buffer.sample_count;
99        let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
100            layout: Some(layout),
101            vertex: VertexState {
102                module: &self.shaders.vertex_module,
103                entry_point: self.shaders.vertex_entry,
104                buffers: &[VertexBufferLayout {
105                    array_stride: size_of::<[f32; 3]>() as BufferAddress,
106                    step_mode: VertexStepMode::Vertex,
107                    attributes: &[VertexAttribute {
108                        format: VertexFormat::Float32x3,
109                        offset: 0,
110                        shader_location: 0,
111                    }],
112                }],
113                compilation_options: Default::default(),
114            },
115            fragment: Some(FragmentState {
116                module: &self.shaders.fragment_module,
117                entry_point: self.shaders.fragment_entry,
118                targets: &[Some(ColorTargetState {
119                    format: scene_desc.render_texture.format,
120                    blend: Some(BlendState::REPLACE),
121                    write_mask: ColorWrites::ALL,
122                })],
123                compilation_options: Default::default(),
124            }),
125            primitive: PrimitiveState {
126                topology: PrimitiveTopology::LineList,
127                ..Default::default()
128            },
129            depth_stencil: Some(DepthStencilState {
130                format: TextureFormat::Depth32Float,
131                depth_write_enabled: true,
132                depth_compare: CompareFunction::Less,
133                stencil: Default::default(),
134                bias: Default::default(),
135            }),
136            multisample: MultisampleState {
137                count: sample_count,
138                mask: !0,
139                alpha_to_coverage_enabled: sample_count > 1,
140            },
141            label: None,
142            multiview: None,
143            cache: None,
144        });
145        Arc::new(pipeline)
146    }
147}
148
149impl ToInstance<WireFrameInstance> for Vec<(Point3, Point3)> {
150    type State = WireFrameState;
151    fn to_instance(
152        &self,
153        handler: &DeviceHandler,
154        shaders: &WireShaders,
155        state: &WireFrameState,
156    ) -> WireFrameInstance {
157        let device = handler.device();
158        let positions: Vec<[f32; 3]> = self
159            .iter()
160            .flat_map(|p| vec![p.0, p.1])
161            .map(|p| p.cast().unwrap().into())
162            .collect();
163        let strips: Vec<u32> = (0..2 * self.len()).map(|i| i as u32).collect();
164        let vb = BufferHandler::from_slice(&positions, device, BufferUsages::VERTEX);
165        let ib = BufferHandler::from_slice(&strips, device, BufferUsages::INDEX);
166        WireFrameInstance {
167            vertices: Arc::new(vb),
168            strips: Arc::new(ib),
169            state: state.clone(),
170            shaders: shaders.clone(),
171            id: RenderID::gen(),
172        }
173    }
174}