Skip to main content

ursus_core/render/gfx/
technique.rs

1use crate::assets::ShaderHandle;
2use crate::render::gfx::types::{BlendState, CullMode};
3use std::collections::HashMap;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
6pub struct TechniqueId(pub u32);
7
8/// Declarative description of the technique, registered once when building the pipeline.
9#[derive(Debug, Clone)]
10pub struct TechniqueDesc {
11    pub name: String,
12    pub shader: ShaderHandle,
13    pub cull_mode: CullMode,
14    pub blend: Option<BlendState>,
15}
16
17impl TechniqueDesc {
18    pub fn new(name: impl Into<String>, shader: ShaderHandle) -> Self {
19        Self { name: name.into(), shader, cull_mode: CullMode::Back, blend: None }
20    }
21
22    pub fn with_cull_mode(mut self, mode: CullMode) -> Self {
23        self.cull_mode = mode;
24        self
25    }
26
27    pub fn with_blend(mut self, blend: BlendState) -> Self {
28        self.blend = Some(blend);
29        self
30    }
31}
32
33#[derive(Default)]
34pub struct TechniqueRegistry {
35    techniques: Vec<TechniqueDesc>,
36    by_name: HashMap<String, TechniqueId>,
37}
38
39impl TechniqueRegistry {
40    pub fn register(&mut self, desc: TechniqueDesc) -> TechniqueId {
41        if let Some(&id) = self.by_name.get(&desc.name) {
42            log::warn!("TechniqueRegistry: Technique '{}' is already registered, returning old id", desc.name);
43            return id;
44        }
45        let id = TechniqueId(self.techniques.len() as u32);
46        self.by_name.insert(desc.name.clone(), id);
47        self.techniques.push(desc);
48        id
49    }
50
51    pub fn by_name(&self, name: &str) -> Option<TechniqueId> {
52        self.by_name.get(name).copied()
53    }
54
55    pub fn get(&self, id: TechniqueId) -> &TechniqueDesc {
56        &self.techniques[id.0 as usize]
57    }
58
59    pub fn iter(&self) -> impl Iterator<Item = (TechniqueId, &TechniqueDesc)> {
60        self.techniques.iter().enumerate().map(|(i, d)| (TechniqueId(i as u32), d))
61    }
62}