three_d/core/render_target/
depth_target.rs

1use super::*;
2
3///
4/// Adds additional functionality to clear, read from and write to a texture.
5/// Use the `as_depth_target` function directly on the texture structs (for example [DepthTexture2D]) to construct a depth target.
6/// Combine this together with a [ColorTarget] with [RenderTarget::new] to be able to write to both a depth and color target at the same time.
7/// A depth target purely adds functionality, so it can be created each time it is needed, the actual data is saved in the texture.
8///
9#[derive(Clone)]
10pub struct DepthTarget<'a> {
11    pub(crate) context: Context,
12    target: Option<DepthTexture<'a>>,
13    multisample_target: Option<&'a DepthTexture2DMultisample>,
14}
15
16impl<'a> DepthTarget<'a> {
17    pub(in crate::core) fn new_texture2d(context: &Context, texture: &'a DepthTexture2D) -> Self {
18        Self {
19            context: context.clone(),
20            target: Some(DepthTexture::Single(texture)),
21            multisample_target: None,
22        }
23    }
24
25    pub(in crate::core) fn new_texture_cube_map(
26        context: &Context,
27        texture: &'a DepthTextureCubeMap,
28        side: CubeMapSide,
29    ) -> Self {
30        Self {
31            context: context.clone(),
32            target: Some(DepthTexture::CubeMap { texture, side }),
33            multisample_target: None,
34        }
35    }
36
37    pub(in crate::core) fn new_texture_2d_array(
38        context: &Context,
39        texture: &'a DepthTexture2DArray,
40        layer: u32,
41    ) -> Self {
42        Self {
43            context: context.clone(),
44            target: Some(DepthTexture::Array { texture, layer }),
45            multisample_target: None,
46        }
47    }
48
49    pub(in crate::core) fn new_texture_2d_multisample(
50        context: &Context,
51        texture: &'a DepthTexture2DMultisample,
52    ) -> Self {
53        Self {
54            context: context.clone(),
55            target: None,
56            multisample_target: Some(texture),
57        }
58    }
59
60    ///
61    /// Clears the depth of this depth target as defined by the given clear state.
62    ///
63    pub fn clear(&self, clear_state: ClearState) -> &Self {
64        self.clear_partially(self.scissor_box(), clear_state)
65    }
66
67    ///
68    /// Clears the depth of the part of this depth target that is inside the given scissor box.
69    ///
70    pub fn clear_partially(&self, scissor_box: ScissorBox, clear_state: ClearState) -> &Self {
71        self.as_render_target().clear_partially(
72            scissor_box,
73            ClearState {
74                depth: clear_state.depth,
75                ..ClearState::none()
76            },
77        );
78        self
79    }
80
81    ///
82    /// Writes whatever rendered in the `render` closure into this depth target.
83    ///
84    pub fn write<E: std::error::Error>(
85        &self,
86        render: impl FnOnce() -> Result<(), E>,
87    ) -> Result<&Self, E> {
88        self.write_partially(self.scissor_box(), render)
89    }
90
91    ///
92    /// Writes whatever rendered in the `render` closure into the part of this depth target defined by the scissor box.
93    ///
94    pub fn write_partially<E: std::error::Error>(
95        &self,
96        scissor_box: ScissorBox,
97        render: impl FnOnce() -> Result<(), E>,
98    ) -> Result<&Self, E> {
99        self.as_render_target()
100            .write_partially(scissor_box, render)?;
101        Ok(self)
102    }
103
104    ///
105    /// Returns the depth values in this depth target.
106    ///
107    #[cfg(not(target_arch = "wasm32"))]
108    pub fn read(&self) -> Vec<f32> {
109        self.read_partially(self.scissor_box())
110    }
111
112    ///
113    /// Returns the depth values in this depth target inside the given scissor box.
114    ///
115    #[cfg(not(target_arch = "wasm32"))]
116    pub fn read_partially(&self, scissor_box: ScissorBox) -> Vec<f32> {
117        self.as_render_target().read_depth_partially(scissor_box)
118    }
119
120    pub(super) fn as_render_target(&self) -> RenderTarget<'a> {
121        RenderTarget::new_depth(self.clone())
122    }
123
124    ///
125    /// Returns the width of the depth target in texels, which is simply the width of the underlying texture.
126    ///
127    pub fn width(&self) -> u32 {
128        if let Some(target) = &self.target {
129            match target {
130                DepthTexture::Single(texture) => texture.width(),
131                DepthTexture::Array { texture, .. } => texture.width(),
132                DepthTexture::CubeMap { texture, .. } => texture.width(),
133            }
134        } else {
135            self.multisample_target.as_ref().unwrap().width()
136        }
137    }
138
139    ///
140    /// Returns the height of the depth target in texels, which is simply the height of the underlying texture.
141    ///
142    pub fn height(&self) -> u32 {
143        if let Some(target) = &self.target {
144            match target {
145                DepthTexture::Single(texture) => texture.height(),
146                DepthTexture::Array { texture, .. } => texture.height(),
147                DepthTexture::CubeMap { texture, .. } => texture.height(),
148            }
149        } else {
150            self.multisample_target.as_ref().unwrap().height()
151        }
152    }
153
154    pub(super) fn bind(&self) {
155        if let Some(target) = &self.target {
156            match target {
157                DepthTexture::Single(texture) => {
158                    texture.bind_as_depth_target();
159                }
160                DepthTexture::Array { texture, layer } => {
161                    texture.bind_as_depth_target(*layer);
162                }
163                DepthTexture::CubeMap { texture, side } => {
164                    texture.bind_as_depth_target(*side);
165                }
166            }
167        } else {
168            self.multisample_target
169                .as_ref()
170                .unwrap()
171                .bind_as_depth_target()
172        }
173    }
174}