pebble/graphics/render/
targets.rs1use crate::graphics::pipeline::texture_view::TextureView;
2
3pub struct ColorTarget<'a> {
7 pub(crate) attachment: Option<&'a TextureView>,
8 pub(crate) clear: Option<[f32; 4]>
10}
11
12pub struct ColorTargetBuilder<'a> {
13 target: ColorTarget<'a>
14}
15
16impl<'a> ColorTargetBuilder<'a> {
17 pub fn new() -> Self {
18 Self {
19 target: ColorTarget {
20 attachment: None,
21 clear: Some([0.0, 0.0, 0.0, 1.0])
22 }
23 }
24 }
25
26 pub fn with_attachment(mut self, view: &'a TextureView) -> Self {
27 self.target.attachment = Some(view);
28 self
29 }
30
31 pub fn with_clear(mut self, clear: [f32; 4]) -> Self {
33 self.target.clear = Some(clear);
34 self
35 }
36
37 pub fn without_clear(mut self) -> Self {
40 self.target.clear = None;
41 self
42 }
43
44 pub fn build(self) -> ColorTarget<'a> {
45 self.target
46 }
47}
48
49pub struct DepthTarget<'a> {
52 pub(crate) attachment: &'a TextureView,
53 pub(crate) clear: Option<f32>,
54}
55
56pub struct DepthTargetBuilder<'a> {
57 target: DepthTarget<'a>
58}
59
60impl<'a> DepthTargetBuilder<'a> {
61 pub fn new(view: &'a TextureView) -> Self {
62 Self {
63 target: DepthTarget {
64 attachment: view,
65 clear: Some(1.0)
66 }
67 }
68 }
69
70 pub fn with_clear(mut self, clear: f32) -> Self {
72 self.target.clear = Some(clear);
73 self
74 }
75
76 pub fn without_clear(mut self) -> Self {
79 self.target.clear = None;
80 self
81 }
82
83 pub fn build(self) -> DepthTarget<'a> {
84 self.target
85 }
86}
87
88pub struct Pass<'a> {
92 pub(crate) colors: Vec<ColorTarget<'a>>,
93 pub(crate) depth: Option<DepthTarget<'a>>
94}
95
96pub struct PassBuilder<'a> {
97 targets: Vec<ColorTarget<'a>>,
98 depth: Option<DepthTarget<'a>>,
99}
100
101impl<'a> PassBuilder<'a> {
102 pub fn new() -> Self {
103 Self { targets: Vec::new(), depth: None }
104 }
105
106 pub fn with_target(mut self, target: ColorTarget<'a>) -> Self {
107 self.targets.push(target);
108 self
109 }
110
111 pub fn with_depth(mut self, depth: DepthTarget<'a>) -> Self {
112 self.depth = Some(depth);
113 self
114 }
115
116 pub fn build(self) -> Pass<'a> {
117 Pass {
118 colors: self.targets,
119 depth: self.depth,
120 }
121 }
122}
123
124#[cfg(test)]
125mod tests {
126 use super::*;
127
128 #[test]
132 fn a_color_target_clears_to_opaque_black_by_default() {
133 let target = ColorTargetBuilder::new().build();
134 assert_eq!(target.clear, Some([0.0, 0.0, 0.0, 1.0]));
135 }
136
137 #[test]
138 fn with_clear_sets_the_clear_color() {
139 let target = ColorTargetBuilder::new().with_clear([0.0, 0.0, 0.0, 0.0]).build();
140 assert_eq!(target.clear, Some([0.0, 0.0, 0.0, 0.0]));
141 }
142
143 #[test]
144 fn without_clear_loads_existing_contents() {
145 let target = ColorTargetBuilder::new().without_clear().build();
146 assert_eq!(target.clear, None);
147 }
148
149 #[test]
150 fn the_last_clear_setting_wins() {
151 assert_eq!(ColorTargetBuilder::new().with_clear([1.0; 4]).without_clear().build().clear, None);
152 assert_eq!(
153 ColorTargetBuilder::new().without_clear().with_clear([1.0; 4]).build().clear,
154 Some([1.0; 4])
155 );
156 }
157}