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