Skip to main content

radiant_rs/core/
rendertarget.rs

1use crate::prelude::*;
2use crate::core::{Texture, Color, TextureFilter, Rect, Point2};
3use crate::backends::backend;
4
5pub const NO_FRAME_PREPARED: &'static str = "Failed to get frame: None prepared.";
6
7/// A target for rendering.
8pub trait AsRenderTarget {
9    /// Returns a RenderTarget representing a texture or a frame.
10    fn as_render_target(self: &Self) -> RenderTarget;
11}
12
13/// An opaque type representing rendering targets like Display or Texture.
14#[derive(Clone)]
15pub struct RenderTarget(pub(crate) RenderTargetInner);
16
17impl RenderTarget {
18    /// Creates a new frame rendertarget.
19    pub(crate) fn frame(frame: &Rc<RefCell<Option<backend::Frame>>>) -> RenderTarget {
20        RenderTarget(RenderTargetInner::Frame(frame.clone()))
21    }
22    /// Creates a new texture rendertarget.
23    pub(crate) fn texture(texture: &Texture) -> RenderTarget{
24        RenderTarget(RenderTargetInner::Texture(texture.clone()))
25    }
26    /// Creates a null rendertarget.
27    pub fn none() -> RenderTarget{
28        RenderTarget(RenderTargetInner::None)
29    }
30}
31
32impl AsRenderTarget for RenderTarget {
33    fn as_render_target(self: &Self) -> RenderTarget {
34        self.clone()
35    }
36}
37
38impl Debug for RenderTarget {
39    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
40        let inner = match &self.0 {
41            &RenderTargetInner::None => "None".to_string(),
42            &RenderTargetInner::Frame(_) => "Frame".to_string(),
43            &RenderTargetInner::Texture(ref texture) => format!("{:?}", texture)
44        };
45        write!(f, "RenderTarget {{ {:?} }}", inner)
46    }
47}
48
49/// An enum of render target type instances.
50#[derive(Clone)]
51pub enum RenderTargetInner {
52    None,
53    Frame(Rc<RefCell<Option<backend::Frame>>>),
54    Texture(Texture),
55}
56
57impl RenderTargetInner {
58    /// Clears the target.
59    pub fn clear(self: &Self, color: Color) {
60        match *self {
61            RenderTargetInner::Frame(ref display) => {
62                let mut frame = display.borrow_mut();
63                frame.as_mut().expect(NO_FRAME_PREPARED).clear(color);
64            },
65            RenderTargetInner::Texture(ref texture) => {
66                texture.clear(color);
67            }
68            RenderTargetInner::None => { }
69        }
70    }
71    /// Returns the dimensions of the target.
72    pub fn dimensions(self: &Self) -> Point2<u32> {
73        match *self {
74            RenderTargetInner::Frame(ref display) => {
75                let mut frame = display.borrow_mut();
76                frame.as_mut().expect(NO_FRAME_PREPARED).dimensions()
77            },
78            RenderTargetInner::Texture(ref texture) => {
79                texture.dimensions()
80            }
81            RenderTargetInner::None => {
82                (0, 0)
83            }
84        }
85    }
86    /// Blits a source rect to a rect on the target.
87    pub fn blit_rect(self: &Self, source: &RenderTarget, source_rect: Rect<i32>, target_rect: Rect<i32>, filter: TextureFilter) {
88        match *self {
89            RenderTargetInner::Frame(ref target_display) => {
90                match source.0 {
91                    RenderTargetInner::Frame(_) => {
92                        let mut frame = target_display.borrow_mut();
93                        frame.as_mut().expect(NO_FRAME_PREPARED).copy_rect(source_rect, target_rect, filter);
94                    },
95                    RenderTargetInner::Texture(ref src_texture) => {
96                        let mut frame = target_display.borrow_mut();
97                        frame.as_mut().expect(NO_FRAME_PREPARED).copy_rect_from_texture(src_texture, source_rect, target_rect, filter);
98                    }
99                    RenderTargetInner::None => { }
100                }
101            },
102            RenderTargetInner::Texture(ref target_texture) => {
103                match source.0 {
104                    RenderTargetInner::Frame(ref src_display) => {
105                        let mut frame = src_display.borrow_mut();
106                        target_texture.handle.copy_rect_from_frame(frame.as_mut().expect(NO_FRAME_PREPARED), source_rect, target_rect, filter);
107                    },
108                    RenderTargetInner::Texture(ref src_texture) => {
109                        target_texture.handle.copy_rect_from(src_texture, source_rect, target_rect, filter);
110                    }
111                    RenderTargetInner::None => { }
112                }
113            }
114            RenderTargetInner::None => { }
115        }
116    }
117    /// Blits to the target.
118    pub fn blit(self: &Self, source: &RenderTarget, filter: TextureFilter) {
119        match *self {
120            RenderTargetInner::Frame(ref target_display) => {
121                match source.0 {
122                    RenderTargetInner::Frame(_) => { /* blitting entire frame to entire frame makes no sense */ },
123                    RenderTargetInner::Texture(ref src_texture) => {
124                        let mut frame = target_display.borrow_mut();
125                        frame.as_mut().expect(NO_FRAME_PREPARED).copy_from_texture(src_texture, filter);
126                    }
127                    RenderTargetInner::None => { }
128                }
129            },
130            RenderTargetInner::Texture(ref target_texture) => {
131                match source.0 {
132                    RenderTargetInner::Frame(ref src_display) => {
133                        let mut frame = src_display.borrow_mut();
134                        target_texture.handle.copy_from_frame(frame.as_mut().expect(NO_FRAME_PREPARED), filter);
135                    },
136                    RenderTargetInner::Texture(ref src_texture) => {
137                        target_texture.handle.copy_from(src_texture, filter);
138                    }
139                    RenderTargetInner::None => { }
140                }
141            }
142            RenderTargetInner::None => { }
143        }
144    }
145}