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
use crate::core::*;
use crate::renderer::*;
///
/// Forward render pipeline which can render objects (implementing the [Object] trait).
/// Forward rendering directly draws to the given render target (for example the screen) and is therefore the same as calling [Object::render] directly.
///
pub struct ForwardPipeline {
context: Context,
}
impl ForwardPipeline {
///
/// Constructor.
///
pub fn new(context: &Context) -> ThreeDResult<Self> {
Ok(Self {
context: context.clone(),
})
}
///
/// Render the objects. Also avoids rendering objects outside the camera frustum and render the objects in the order given by [cmp_render_order].
/// Must be called in a render target render function, for example in the callback function of [Screen::write].
///
pub fn render_pass(
&self,
camera: &Camera,
objects: &[&dyn Object],
lights: &[&dyn Light],
) -> ThreeDResult<()> {
render_pass(camera, objects, lights)
}
///
/// Render the distance from the camera to the objects in each pixel into a depth texture. Also, do not render transparent objects and objects outside the camera frustum.
/// Must be called in a render target render function, where a depth texture is bound, for example in the callback function of [Screen::write] or [DepthTargetTexture2D::write].
///
pub fn depth_pass(&self, camera: &Camera, objects: &[&dyn Object]) -> ThreeDResult<()> {
let depth_material = DepthMaterial {
render_states: RenderStates {
write_mask: WriteMask::DEPTH,
..Default::default()
},
..Default::default()
};
for object in objects
.iter()
.filter(|o| !o.is_transparent() && camera.in_frustum(&o.aabb()))
{
object.render_with_material(&depth_material, camera, &[])?;
}
Ok(())
}
///
/// Creates a new [DepthTargetTexture2D], applies a [ForwardPipeline::depth_pass] and returns the texture.
///
pub fn depth_pass_texture(
&self,
camera: &Camera,
objects: &[&dyn Object],
) -> ThreeDResult<DepthTargetTexture2D> {
let mut depth_texture = DepthTargetTexture2D::new(
&self.context,
camera.viewport().width,
camera.viewport().height,
Wrapping::ClampToEdge,
Wrapping::ClampToEdge,
DepthFormat::Depth32F,
)?;
depth_texture.write(Some(1.0), || self.depth_pass(&camera, objects))?;
Ok(depth_texture)
}
}