Skip to main content

wde_pbr_outline/selection_area/
material.rs

1use bevy::{
2    ecs::system::{SystemParamItem, lifetimeless::SRes},
3    prelude::*
4};
5use wde_renderer::prelude::{Color, *};
6
7#[repr(C)]
8#[derive(Default, Copy, Clone, bytemuck::Pod, bytemuck::Zeroable)]
9struct SelectionAreaMaterialUniform {
10    color: [f32; 4]
11}
12
13/// A flat, alpha-blended material used to draw the RTS-style ground selection decal
14/// (the drag-rectangle highlight) on top of the terrain.
15#[derive(Asset, TypePath, Clone)]
16pub struct SelectionAreaMaterial {
17    pub label: String,
18    pub color: Color,
19    pub uniform_buffer: Option<Handle<Buffer>>
20}
21impl Default for SelectionAreaMaterial {
22    fn default() -> Self {
23        Self {
24            label: "selection-area-material".to_string(),
25            color: Color::LinearRgba(1.0, 0.85, 0.0, 0.25),
26            uniform_buffer: None
27        }
28    }
29}
30impl RenderBinding for SelectionAreaMaterial {
31    type Params = SRes<AssetServer>;
32
33    fn describe(
34        &mut self,
35        asset_server: &SystemParamItem<Self::Params>,
36        builder: &mut RenderBindingBuilder
37    ) {
38        let uniform = SelectionAreaMaterialUniform {
39            color: [
40                self.color.r(),
41                self.color.g(),
42                self.color.b(),
43                self.color.a()
44            ]
45        };
46
47        if self.uniform_buffer.is_none() {
48            self.uniform_buffer = Some(asset_server.add(Buffer {
49                label: format!("{}-uniform", self.label),
50                size: std::mem::size_of::<SelectionAreaMaterialUniform>(),
51                usage: BufferUsage::UNIFORM | BufferUsage::COPY_DST,
52                content: Some(bytemuck::cast_slice(&[uniform]).to_vec())
53            }));
54        }
55
56        builder.add_buffer_from_id(Some(self.uniform_buffer.as_ref().unwrap().id()));
57    }
58
59    fn label(&self) -> &str {
60        &self.label
61    }
62}