librashader_runtime/
render_target.rs

1use crate::quad::{DEFAULT_MVP, IDENTITY_MVP};
2use librashader_common::{GetSize, Size, Viewport};
3use num_traits::{zero, AsPrimitive, Num};
4use std::borrow::Borrow;
5
6/// An internal render target to which pass colour attachments are made.
7#[derive(Debug, Clone)]
8pub struct RenderTarget<'a, T, C = f32>
9where
10    C: Num,
11{
12    /// The x-coordinate of the viewport to render to.
13    pub x: C,
14    /// The y-coordinate of the viewport to render to.
15    pub y: C,
16    /// The MVP to pass to the shader for this render pass.
17    pub mvp: &'a [f32; 16],
18    /// The output surface for the pass.
19    pub output: &'a T,
20    /// The extent of the render target, starting from the origin defined
21    /// by x and y.
22    pub size: Size<u32>,
23}
24
25impl<'a, T: GetSize<u32>, C: Num> RenderTarget<'a, T, C> {
26    /// Create a new render target.
27    pub fn new(output: &'a T, mvp: &'a [f32; 16], x: C, y: C) -> Result<Self, T::Error> {
28        Ok(RenderTarget {
29            output,
30            mvp,
31            x,
32            y,
33            size: output.size()?,
34        })
35    }
36
37    /// Create a render target with the identity MVP.
38    pub fn identity(output: &'a T) -> Result<Self, T::Error> {
39        Self::offscreen(output, IDENTITY_MVP)
40    }
41
42    /// Create an offscreen render target with the given MVP.
43    pub fn offscreen(output: &'a T, mvp: &'a [f32; 16]) -> Result<Self, T::Error> {
44        Self::new(output, mvp, zero(), zero())
45    }
46}
47
48impl<'a, T, C: Num + Copy + 'static> RenderTarget<'a, T, C>
49where
50    f32: AsPrimitive<C>,
51{
52    /// Create a viewport render target.
53    pub fn viewport(viewport: &'a Viewport<'a, impl Borrow<T>>) -> Self {
54        RenderTarget {
55            output: viewport.output.borrow(),
56            mvp: viewport.mvp.unwrap_or(DEFAULT_MVP),
57            x: viewport.x.as_(),
58            y: viewport.y.as_(),
59            size: viewport.size,
60        }
61    }
62
63    /// Create a viewport render target with the given output.
64    pub fn viewport_with_output<S>(output: &'a T, viewport: &'a Viewport<'a, S>) -> Self {
65        RenderTarget {
66            output,
67            mvp: viewport.mvp.unwrap_or(DEFAULT_MVP),
68            x: viewport.x.as_(),
69            y: viewport.y.as_(),
70            size: viewport.size,
71        }
72    }
73}