luminance/
depth_stencil.rs

1//! Depth test related features.
2
3/// Comparison to perform for depth / stencil operations. `a` is the incoming fragment’s data and b is the fragment’s
4/// data that is already stored.
5#[derive(Copy, Clone, Debug, Eq, PartialEq)]
6pub enum Comparison {
7  /// Test never succeeds.
8  Never,
9  /// Test always succeeds.
10  Always,
11  /// Test succeeds if `a == b`.
12  Equal,
13  /// Test succeeds if `a != b`.
14  NotEqual,
15  /// Test succeeds if `a < b`.
16  Less,
17  /// Test succeeds if `a <= b`.
18  LessOrEqual,
19  /// Test succeeds if `a > b`.
20  Greater,
21  /// Test succeeds if `a >= b`.
22  GreaterOrEqual,
23}
24
25/// Whether or not writes should be performed when rendering.
26#[derive(Copy, Clone, Debug, Eq, PartialEq)]
27pub enum Write {
28  /// Write values.
29  On,
30  /// Do not write values.
31  Off,
32}
33
34/// The stencil test is a bit weird. It’s a [`Comparison`] as well as the « stencil mask ».
35#[derive(Copy, Clone, Debug, Eq, PartialEq)]
36pub struct StencilTest {
37  /// Comparison to apply to make a fragment pass the test.
38  pub comparison: Comparison,
39
40  /// Reference value for the comparison.
41  pub reference: u8,
42
43  /// The mask to apply on the fragment stencil value.
44  pub mask: u8,
45}
46
47impl StencilTest {
48  /// Create a new [`StencilTest`] from the comparison, reference and mask values.
49  pub fn new(comparison: Comparison, reference: u8, mask: u8) -> Self {
50    Self {
51      comparison,
52      reference,
53      mask,
54    }
55  }
56}
57
58/// The stencil operations are executed whenever a stencil test passes.
59#[derive(Copy, Clone, Debug, Eq, PartialEq)]
60pub struct StencilOperations {
61  /// Action to take when the depth test passes but not the stencil test.
62  pub depth_passes_stencil_fails: StencilOp,
63
64  /// Action to take when the stencil test passes but not the depth test.
65  pub depth_fails_stencil_passes: StencilOp,
66
67  /// Action to take when both the depth and stencil tests pass.
68  pub depth_stencil_pass: StencilOp,
69}
70
71impl StencilOperations {
72  /// Create [`Default`] [`StencilOperations`].
73  pub fn new() -> Self {
74    Self::default()
75  }
76
77  /// Set the [`StencilOp`] to do when the depth test passes but stencil test fails:
78  pub fn on_depth_passes_stencil_fails(self, op: StencilOp) -> Self {
79    Self {
80      depth_passes_stencil_fails: op,
81      ..self
82    }
83  }
84
85  /// Set the [`StencilOp`] to do when the depth test fails but stencil test passes:
86  pub fn on_depth_fails_stencil_passes(self, op: StencilOp) -> Self {
87    Self {
88      depth_fails_stencil_passes: op,
89      ..self
90    }
91  }
92
93  /// Set the [`StencilOp`] to do when both the depth test and stencil test pass:
94  pub fn on_depth_stencil_pass(self, op: StencilOp) -> Self {
95    Self {
96      depth_stencil_pass: op,
97      ..self
98    }
99  }
100}
101
102/// Default implementation for [`StencilOperations`]:
103///
104/// - when depth test passes but stencil fail: [`StencilOp::Keep`].
105/// - when depth test fails but stencil passes: [`StencilOp::Keep`].
106/// - when both depth test and stencil test pass: [`StencilOp::Keep`].
107impl Default for StencilOperations {
108  fn default() -> Self {
109    Self {
110      depth_passes_stencil_fails: StencilOp::Keep,
111      depth_fails_stencil_passes: StencilOp::Keep,
112      depth_stencil_pass: StencilOp::Keep,
113    }
114  }
115}
116
117/// Possible stencil operations.
118#[derive(Copy, Clone, Debug, Eq, PartialEq)]
119pub enum StencilOp {
120  /// Keep the current value.
121  Keep,
122
123  /// Set the stencil value to zero.
124  Zero,
125
126  /// Replace the stencil value.
127  Replace,
128
129  /// Increment the stencil value.
130  ///
131  /// If the stencil value reaches the maximum possible value, it is clamped.
132  Increment,
133
134  /// Increment the stencil value.
135  ///
136  /// If the stencil value reaches the maximum possible value, it wraps around back to `0`.
137  IncrementWrap,
138
139  /// Decrement the stencil value.
140  ///
141  /// If the stencil value reaches 0, it is clamped.
142  Decrement,
143
144  /// Decrement the stencil value.
145  ///
146  /// If the stencil value reaches 0, it wraps back to the maximum value.
147  DecrementWrap,
148
149  /// Bit-wise inversion.
150  Invert,
151}