Skip to main content

wde_pbr_outline/
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 OutlineMaterialUniform {
10    color: [f32; 4],
11    thickness: f32,
12    _padding: [f32; 3]
13}
14
15#[derive(Asset, TypePath, Clone)]
16pub struct OutlineMaterial {
17    pub label: String,
18    pub color: Color,
19    /// Outline width, as a fraction of the view depth (constant width on screen).
20    pub thickness: f32,
21    pub uniform_buffer: Option<Handle<Buffer>>
22}
23impl Default for OutlineMaterial {
24    fn default() -> Self {
25        Self {
26            label: "outline-material".to_string(),
27            color: Color::LinearRgba(1.0, 1.0, 1.0, 0.6),
28            thickness: 0.004,
29            uniform_buffer: None
30        }
31    }
32}
33impl RenderBinding for OutlineMaterial {
34    type Params = SRes<AssetServer>;
35
36    fn describe(
37        &mut self,
38        asset_server: &SystemParamItem<Self::Params>,
39        builder: &mut RenderBindingBuilder
40    ) {
41        let uniform = OutlineMaterialUniform {
42            color: [
43                self.color.r(),
44                self.color.g(),
45                self.color.b(),
46                self.color.a()
47            ],
48            thickness: self.thickness,
49            _padding: [0.0, 0.0, 0.0]
50        };
51
52        if self.uniform_buffer.is_none() {
53            self.uniform_buffer = Some(asset_server.add(Buffer {
54                label: format!("{}-uniform", self.label),
55                size: std::mem::size_of::<OutlineMaterialUniform>(),
56                usage: BufferUsage::UNIFORM | BufferUsage::COPY_DST,
57                content: Some(bytemuck::cast_slice(&[uniform]).to_vec())
58            }));
59        }
60
61        builder.add_buffer_from_id(Some(self.uniform_buffer.as_ref().unwrap().id()));
62    }
63
64    fn label(&self) -> &str {
65        &self.label
66    }
67}