use device;
use device::Resources;
use device::draw::Gamma;
use device::tex::Size;
use draw_state::target::{Layer, Level, Mask};
#[derive(Clone, PartialEq, Debug)]
pub enum Plane<R: Resources> {
Surface(device::handle::Surface<R>),
Texture(device::handle::Texture<R>, Level, Option<Layer>),
}
impl<R: Resources> Plane<R> {
pub fn get_surface_info(&self) -> device::tex::SurfaceInfo {
match *self {
Plane::Surface(ref suf) => *suf.get_info(),
Plane::Texture(ref tex, _, _) => tex.get_info().to_surface_info(),
}
}
pub fn get_format(&self) -> device::tex::Format {
match *self {
Plane::Surface(ref suf) => suf.get_info().format,
Plane::Texture(ref tex, _, _) => tex.get_info().format,
}
}
}
pub trait Output<R: Resources> {
fn get_handle(&self) -> Option<&device::handle::FrameBuffer<R>> { None }
fn get_size(&self) -> (Size, Size);
fn get_colors(&self) -> &[Plane<R>] { &[] }
fn get_depth(&self) -> Option<&Plane<R>> { None }
fn get_stencil(&self) -> Option<&Plane<R>> { None }
fn get_gamma(&self) -> Gamma { Gamma::Original }
fn get_mask(&self) -> Mask {
use draw_state::target as t;
let mut mask = match self.get_colors().len() {
0 => Mask::empty(),
1 => t::COLOR0,
2 => t::COLOR0 | t::COLOR1,
3 => t::COLOR0 | t::COLOR1 | t::COLOR2,
_ => t::COLOR0 | t::COLOR1 | t::COLOR2 | t::COLOR3,
};
if self.get_depth().is_some() {
mask.insert(t::DEPTH);
}
if self.get_stencil().is_some() {
mask.insert(t::STENCIL);
}
mask
}
}
impl<R: Resources> Output<R> for Plane<R> {
fn get_size(&self) -> (Size, Size) {
let info = self.get_surface_info();
(info.width, info.height)
}
#[cfg(unstable)]
fn get_colors(&self) -> &[Plane<R>] {
use std::slice::ref_slice;
if self.get_format().is_color() {
ref_slice(self)
}else {
&[]
}
}
#[cfg(not(unstable))]
fn get_colors(&self) -> &[Plane<R>] {
if self.get_format().is_color() {
unimplemented!()
}else {
&[]
}
}
fn get_depth(&self) -> Option<&Plane<R>> {
if self.get_format().has_depth() {
Some(self)
}else {
None
}
}
fn get_stencil(&self) -> Option<&Plane<R>> {
if self.get_format().has_stencil() {
Some(self)
}else {
None
}
}
}
#[derive(Clone, PartialEq, Debug)]
pub struct Frame<R: Resources> {
pub width: Size,
pub height: Size,
pub colors: Vec<Plane<R>>,
pub depth: Option<Plane<R>>,
pub stencil: Option<Plane<R>>,
pub gamma: Gamma,
}
impl<R: Resources> Frame<R> {
pub fn empty(width: Size, height: Size) -> Frame<R> {
Frame {
width: width,
height: height,
colors: Vec::new(),
depth: None,
stencil: None,
gamma: Gamma::Original,
}
}
}
impl<R: Resources> Output<R> for Frame<R> {
fn get_size(&self) -> (Size, Size) {
(self.width, self.height)
}
fn get_colors(&self) -> &[Plane<R>] {
&self.colors
}
fn get_depth(&self) -> Option<&Plane<R>> {
self.depth.as_ref()
}
fn get_stencil(&self) -> Option<&Plane<R>> {
self.stencil.as_ref()
}
fn get_gamma(&self) -> Gamma {
self.gamma
}
}