graphics/draw_state.rs
1//! Graphics draw state.
2
3/// Graphics draw state used for blending, clipping and stencil rendering.
4#[derive(Copy, Clone, PartialEq, Debug, PartialOrd)]
5pub struct DrawState {
6 /// Scissor mask to use. If set, no pixel outside of this
7 /// rectangle (in screen space) will be written to as a result of rendering.
8 pub scissor: Option<[u32; 4]>,
9 /// Stencil test to use. If None, no stencil testing is done.
10 pub stencil: Option<Stencil>,
11 /// Blend function to use. If None, blending is disabled.
12 pub blend: Option<Blend>,
13}
14
15impl Default for DrawState {
16 fn default() -> Self {
17 DrawState::new_alpha()
18 }
19}
20
21impl DrawState {
22 /// Uses alpha blending.
23 pub fn new_alpha() -> DrawState {
24 DrawState {
25 blend: Some(Blend::Alpha),
26 stencil: None,
27 scissor: None,
28 }
29 }
30
31 /// Draws to stencil buffer with value 255.
32 /// This can be used for clipping.
33 ///
34 /// For nested clipping, clear the stencil buffer and use `DrawState::new_increment`.
35 pub fn new_clip() -> DrawState {
36 DrawState {
37 blend: Some(Blend::Alpha),
38 stencil: Some(Stencil::Clip(255)),
39 scissor: None,
40 }
41 }
42
43 /// Increases stencil buffer.
44 /// This can be used for nested clipping.
45 pub fn new_increment() -> DrawState {
46 DrawState {
47 blend: Some(Blend::Alpha),
48 stencil: Some(Stencil::Increment),
49 scissor: None,
50 }
51 }
52
53 /// Tests against stencil buffer with value 255.
54 /// Draws inside the shape defined by stencil buffer.
55 pub fn new_inside() -> DrawState {
56 DrawState {
57 blend: Some(Blend::Alpha),
58 stencil: Some(Stencil::Inside(255)),
59 scissor: None,
60 }
61 }
62
63 /// Tests against stencil buffer with value 255.
64 /// Draws outside the shape defined by stencil buffer.
65 pub fn new_outside() -> DrawState {
66 DrawState {
67 blend: Some(Blend::Alpha),
68 stencil: Some(Stencil::Outside(255)),
69 scissor: None,
70 }
71 }
72
73 /// Sets blending.
74 pub fn blend(mut self, blend: Blend) -> DrawState {
75 self.blend = Some(blend);
76 self
77 }
78
79 /// Sets scissor `[x, y, w, h]`.
80 pub fn scissor(mut self, scissor: [u32; 4]) -> DrawState {
81 self.scissor = Some(scissor);
82 self
83 }
84}
85
86/// The blend setting to use when drawing.
87///
88/// Using presets since some backends need one pipeline state object instance
89/// per blending technique.
90#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
91pub enum Blend {
92 /// Alpha blending (allows semi-transparent pixels).
93 ///
94 /// ```not_rust
95 /// new_dest_color = src_color * src_alpha + dest_color * (1 - src_alpha)
96 /// new_dest_alpha = src_alpha + dest_alpha
97 /// ```
98 Alpha,
99 /// Additive blending.
100 ///
101 /// ```not_rust
102 /// new_dest_color = src_color + dest_color
103 /// new_dest_alpha = src_alpha + dest_alpha
104 /// ```
105 Add,
106 /// Additive blending with alpha channel.
107 ///
108 /// ```not_rust
109 /// new_dest_color = src_color * src_alpha + dest_color
110 /// new_dest_alpha = dest_alpha
111 /// ```
112 Lighter,
113 /// Multiply color components.
114 ///
115 /// ```not_rust
116 /// new_dest_color = src_color * dest_color
117 /// new_dest_alpha = src_alpha * dest_alpha
118 /// ```
119 Multiply,
120 /// Invert colors when rendering a white shape.
121 ///
122 /// ```not_rust
123 /// new_dest_color = ref_color - src_color
124 /// new_dest_alpha = dest_alpha
125 /// ```
126 ///
127 /// When combining two fragments, subtract the destination color from a constant color
128 /// using the source color as weight. Has an invert effect with the constant color
129 /// as base and source color controlling displacement from the base color.
130 /// A white source color and a white value results in plain invert.
131 /// The output alpha is same as destination alpha.
132 Invert,
133}
134
135/// Stencil buffer settings.
136#[derive(Copy, Clone, Debug, PartialEq, PartialOrd)]
137pub enum Stencil {
138 /// Draw to stencil buffer.
139 Clip(u8),
140 /// Draw pixels that have stencil value.
141 Inside(u8),
142 /// Draw pixels that does not have stencil value.
143 Outside(u8),
144 /// Increment stencil buffer.
145 Increment,
146}