use device::state;
use device::state::{BlendValue, CullMode, Equation, InverseFlag, RasterMethod, StencilOp, WindingOrder};
use device::target::{Rect, Stencil};
#[derive(Copy, Clone, PartialEq, Debug)]
pub struct DrawState {
pub primitive: state::Primitive,
pub multi_sample: Option<state::MultiSample>,
pub scissor: Option<Rect>,
pub stencil: Option<state::Stencil>,
pub depth: Option<state::Depth>,
pub blend: Option<state::Blend>,
pub color_mask: state::ColorMask,
}
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum BlendPreset {
Additive,
Alpha,
}
impl DrawState {
pub fn new() -> DrawState {
DrawState {
primitive: state::Primitive {
front_face: WindingOrder::CounterClockwise,
method: RasterMethod::Fill(CullMode::Back),
offset: None,
},
multi_sample: None,
scissor: None,
stencil: None,
depth: None,
blend: None,
color_mask: state::MASK_ALL,
}
}
pub fn multi_sample(mut self) -> DrawState {
self.multi_sample = Some(state::MultiSample);
self
}
pub fn stencil(mut self, fun: state::Comparison, value: Stencil) -> DrawState {
let side = state::StencilSide {
fun: fun,
value: value,
mask_read: -1,
mask_write: -1,
op_fail: StencilOp::Keep,
op_depth_fail: StencilOp::Keep,
op_pass: StencilOp::Keep,
};
self.stencil = Some(state::Stencil {
front: side,
back: side,
});
self
}
pub fn depth(mut self, fun: state::Comparison, write: bool) -> DrawState {
self.depth = Some(state::Depth {
fun: fun,
write: write,
});
self
}
pub fn blend(mut self, preset: BlendPreset) -> DrawState {
self.blend = Some(match preset {
BlendPreset::Additive => state::Blend {
color: state::BlendChannel {
equation: Equation::Add,
source: state::Factor(InverseFlag::Inverse, BlendValue::Zero),
destination: state::Factor(InverseFlag::Inverse, BlendValue::Zero),
},
alpha: state::BlendChannel {
equation: Equation::Add,
source: state::Factor(InverseFlag::Inverse, BlendValue::Zero),
destination: state::Factor(InverseFlag::Inverse, BlendValue::Zero),
},
value: [0.0, 0.0, 0.0, 0.0],
},
BlendPreset::Alpha => state::Blend {
color: state::BlendChannel {
equation: Equation::Add,
source: state::Factor(InverseFlag::Normal, BlendValue::SourceAlpha),
destination: state::Factor(InverseFlag::Inverse, BlendValue::SourceAlpha),
},
alpha: state::BlendChannel {
equation: Equation::Add,
source: state::Factor(InverseFlag::Inverse, BlendValue::Zero),
destination: state::Factor(InverseFlag::Inverse, BlendValue::Zero),
},
value: [0.0, 0.0, 0.0, 0.0],
},
});
self
}
}