luminance/
shading_gate.rs

1//! Shading gates.
2//!
3//! A shading gate is a _pipeline node_ that allows to share shader [`Program`] for deeper nodes.
4//!
5//! [`Program`]: crate::shader::Program
6
7use crate::{
8  backend::shading_gate::ShadingGate as ShadingGateBackend,
9  render_gate::RenderGate,
10  shader::{Program, ProgramInterface, UniformInterface},
11  vertex::Semantics,
12};
13
14/// A shading gate.
15///
16/// This is obtained after entering a [`PipelineGate`].
17///
18/// # Parametricity
19///
20/// - `B` is the backend type.
21///
22/// [`PipelineGate`]: crate::pipeline::PipelineGate
23pub struct ShadingGate<'a, B> {
24  pub(crate) backend: &'a mut B,
25}
26
27impl<'a, B> ShadingGate<'a, B>
28where
29  B: ShadingGateBackend,
30{
31  /// Enter a [`ShadingGate`] by using a shader [`Program`].
32  ///
33  /// The argument closure is given two arguments:
34  ///
35  /// - A [`ProgramInterface`], that allows to pass values (via [`ProgramInterface::set`]) to the
36  ///   in-use shader [`Program`] and/or perform dynamic lookup of uniforms.
37  /// - A [`RenderGate`], allowing to create deeper nodes in the graphics pipeline.
38  pub fn shade<E, Sem, Out, Uni, F>(
39    &mut self,
40    program: &mut Program<B, Sem, Out, Uni>,
41    f: F,
42  ) -> Result<(), E>
43  where
44    Sem: Semantics,
45    Uni: UniformInterface<B>,
46    F: for<'b> FnOnce(ProgramInterface<'b, B>, &'b Uni, RenderGate<'b, B>) -> Result<(), E>,
47  {
48    unsafe {
49      self.backend.apply_shader_program(&mut program.repr);
50    }
51
52    let render_gate = RenderGate {
53      backend: self.backend,
54    };
55    let program_interface = ProgramInterface {
56      program: &mut program.repr,
57    };
58
59    f(program_interface, &program.uni, render_gate)
60  }
61}