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}