three_d/core/render_target/
depth_target_multisample.rs

1use crate::core::*;
2
3///
4/// A multisample render target for depth data. Use this if you want to avoid aliasing, ie. jagged edges, when rendering to a [DepthTarget].
5///
6/// After rendering into this target, it needs to be resolved to a non-multisample texture to be able to sample it in a shader.
7/// To do this, use the [DepthTargetMultisample::resolve] or [DepthTargetMultisample::resolve_to] methods.
8///
9/// Also see [RenderTargetMultisample] and [ColorTargetMultisample].
10///
11pub struct DepthTargetMultisample<D: DepthTextureDataType> {
12    pub(crate) context: Context,
13    depth: DepthTexture2DMultisample,
14    _d: std::marker::PhantomData<D>,
15}
16
17impl<D: DepthTextureDataType> DepthTargetMultisample<D> {
18    ///
19    /// Constructs a new multisample depth target with the given dimensions and number of samples.
20    /// The number of samples must be larger than 0, less than or equal to the maximum number of samples supported by the hardware and power of two.
21    ///
22    pub fn new(context: &Context, width: u32, height: u32, number_of_samples: u32) -> Self {
23        #[cfg(debug_assertions)]
24        super::multisample_sanity_check(context, number_of_samples);
25        Self {
26            context: context.clone(),
27            depth: DepthTexture2DMultisample::new::<D>(context, width, height, number_of_samples),
28            _d: std::marker::PhantomData,
29        }
30    }
31
32    ///
33    /// Clears the color and depth of this target as defined by the given clear state.
34    ///
35    pub fn clear(&self, clear_state: ClearState) -> &Self {
36        self.clear_partially(self.scissor_box(), clear_state)
37    }
38
39    ///
40    /// Clears the color and depth of the part of this target that is inside the given scissor box.
41    ///
42    pub fn clear_partially(&self, scissor_box: ScissorBox, clear_state: ClearState) -> &Self {
43        self.as_render_target().clear_partially(
44            scissor_box,
45            ClearState {
46                depth: clear_state.depth,
47                ..ClearState::none()
48            },
49        );
50        self
51    }
52
53    ///
54    /// Writes whatever rendered in the `render` closure into this target.
55    ///
56    pub fn write<E: std::error::Error>(
57        &self,
58        render: impl FnOnce() -> Result<(), E>,
59    ) -> Result<&Self, E> {
60        self.write_partially(self.scissor_box(), render)
61    }
62
63    ///
64    /// Writes whatever rendered in the `render` closure into the part of this target defined by the scissor box.
65    ///
66    pub fn write_partially<E: std::error::Error>(
67        &self,
68        scissor_box: ScissorBox,
69        render: impl FnOnce() -> Result<(), E>,
70    ) -> Result<&Self, E> {
71        self.as_render_target()
72            .write_partially(scissor_box, render)?;
73        Ok(self)
74    }
75
76    /// The width of this target.
77    pub fn width(&self) -> u32 {
78        self.depth.width()
79    }
80
81    /// The height of this target.
82    pub fn height(&self) -> u32 {
83        self.depth.height()
84    }
85
86    /// The number of samples for each fragment.
87    pub fn number_of_samples(&self) -> u32 {
88        self.depth.number_of_samples()
89    }
90
91    fn as_render_target(&self) -> RenderTarget<'_> {
92        DepthTarget::new_texture_2d_multisample(&self.context, &self.depth).as_render_target()
93    }
94
95    ///
96    /// Resolves the multisample depth target into the given non-multisample depth target.
97    /// The target must have the same width, height and [DepthTextureDataType] as this target.
98    ///
99    pub fn resolve_to(&self, target: &DepthTarget<'_>) {
100        self.as_render_target().blit_to(&target.as_render_target());
101    }
102
103    ///
104    /// Resolves the multisample depth target to a default non-multisample [DepthTexture2D].
105    /// Use [DepthTargetMultisample::resolve_to] to resolve to a custom non-multisample texture.
106    ///
107    pub fn resolve(&self) -> DepthTexture2D {
108        let mut depth_texture = DepthTexture2D::new::<D>(
109            &self.context,
110            self.width(),
111            self.height(),
112            Wrapping::ClampToEdge,
113            Wrapping::ClampToEdge,
114        );
115        self.resolve_to(&depth_texture.as_depth_target());
116        depth_texture
117    }
118}