use crate::prelude::*;
use crate::core::{Texture, Color, TextureFilter, Rect, Point2};
use crate::backends::backend;
pub const NO_FRAME_PREPARED: &'static str = "Failed to get frame: None prepared.";
pub trait AsRenderTarget {
fn as_render_target(self: &Self) -> RenderTarget;
}
#[derive(Clone)]
pub struct RenderTarget(pub(crate) RenderTargetInner);
impl RenderTarget {
pub(crate) fn frame(frame: &Rc<RefCell<Option<backend::Frame>>>) -> RenderTarget {
RenderTarget(RenderTargetInner::Frame(frame.clone()))
}
pub(crate) fn texture(texture: &Texture) -> RenderTarget{
RenderTarget(RenderTargetInner::Texture(texture.clone()))
}
pub fn none() -> RenderTarget{
RenderTarget(RenderTargetInner::None)
}
}
impl AsRenderTarget for RenderTarget {
fn as_render_target(self: &Self) -> RenderTarget {
self.clone()
}
}
impl Debug for RenderTarget {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let inner = match &self.0 {
&RenderTargetInner::None => "None".to_string(),
&RenderTargetInner::Frame(_) => "Frame".to_string(),
&RenderTargetInner::Texture(ref texture) => format!("{:?}", texture)
};
write!(f, "RenderTarget {{ {:?} }}", inner)
}
}
#[derive(Clone)]
pub enum RenderTargetInner {
None,
Frame(Rc<RefCell<Option<backend::Frame>>>),
Texture(Texture),
}
impl RenderTargetInner {
pub fn clear(self: &Self, color: Color) {
match *self {
RenderTargetInner::Frame(ref display) => {
let mut frame = display.borrow_mut();
frame.as_mut().expect(NO_FRAME_PREPARED).clear(color);
},
RenderTargetInner::Texture(ref texture) => {
texture.clear(color);
}
RenderTargetInner::None => { }
}
}
pub fn dimensions(self: &Self) -> Point2<u32> {
match *self {
RenderTargetInner::Frame(ref display) => {
let mut frame = display.borrow_mut();
frame.as_mut().expect(NO_FRAME_PREPARED).dimensions()
},
RenderTargetInner::Texture(ref texture) => {
texture.dimensions()
}
RenderTargetInner::None => {
(0, 0)
}
}
}
pub fn blit_rect(self: &Self, source: &RenderTarget, source_rect: Rect<i32>, target_rect: Rect<i32>, filter: TextureFilter) {
match *self {
RenderTargetInner::Frame(ref target_display) => {
match source.0 {
RenderTargetInner::Frame(_) => {
let mut frame = target_display.borrow_mut();
frame.as_mut().expect(NO_FRAME_PREPARED).copy_rect(source_rect, target_rect, filter);
},
RenderTargetInner::Texture(ref src_texture) => {
let mut frame = target_display.borrow_mut();
frame.as_mut().expect(NO_FRAME_PREPARED).copy_rect_from_texture(src_texture, source_rect, target_rect, filter);
}
RenderTargetInner::None => { }
}
},
RenderTargetInner::Texture(ref target_texture) => {
match source.0 {
RenderTargetInner::Frame(ref src_display) => {
let mut frame = src_display.borrow_mut();
target_texture.handle.copy_rect_from_frame(frame.as_mut().expect(NO_FRAME_PREPARED), source_rect, target_rect, filter);
},
RenderTargetInner::Texture(ref src_texture) => {
target_texture.handle.copy_rect_from(src_texture, source_rect, target_rect, filter);
}
RenderTargetInner::None => { }
}
}
RenderTargetInner::None => { }
}
}
pub fn blit(self: &Self, source: &RenderTarget, filter: TextureFilter) {
match *self {
RenderTargetInner::Frame(ref target_display) => {
match source.0 {
RenderTargetInner::Frame(_) => { },
RenderTargetInner::Texture(ref src_texture) => {
let mut frame = target_display.borrow_mut();
frame.as_mut().expect(NO_FRAME_PREPARED).copy_from_texture(src_texture, filter);
}
RenderTargetInner::None => { }
}
},
RenderTargetInner::Texture(ref target_texture) => {
match source.0 {
RenderTargetInner::Frame(ref src_display) => {
let mut frame = src_display.borrow_mut();
target_texture.handle.copy_from_frame(frame.as_mut().expect(NO_FRAME_PREPARED), filter);
},
RenderTargetInner::Texture(ref src_texture) => {
target_texture.handle.copy_from(src_texture, filter);
}
RenderTargetInner::None => { }
}
}
RenderTargetInner::None => { }
}
}
}