use gfx_hal::pso;
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug)]
pub enum BlendFactor {
Zero,
One,
SrcColor,
OneMinusSrcColor,
DstColor,
OneMinusDstColor,
SrcAlpha,
OneMinusSrcAlpha,
DstAlpha,
OneMinusDstAlpha,
ConstColor,
OneMinusConstColor,
ConstAlpha,
OneMinusConstAlpha,
SrcAlphaSaturate,
Src1Color,
OneMinusSrc1Color,
Src1Alpha,
OneMinusSrc1Alpha,
}
impl BlendFactor {
fn to_gfx_blend_factor(self) -> pso::Factor {
match self {
BlendFactor::Zero => pso::Factor::Zero,
BlendFactor::One => pso::Factor::One,
BlendFactor::SrcColor => pso::Factor::SrcColor,
BlendFactor::OneMinusSrcColor => pso::Factor::OneMinusSrcColor,
BlendFactor::DstColor => pso::Factor::DstColor,
BlendFactor::OneMinusDstColor => pso::Factor::OneMinusDstColor,
BlendFactor::SrcAlpha => pso::Factor::SrcAlpha,
BlendFactor::OneMinusSrcAlpha => pso::Factor::OneMinusSrcAlpha,
BlendFactor::DstAlpha => pso::Factor::DstAlpha,
BlendFactor::OneMinusDstAlpha => pso::Factor::OneMinusDstAlpha,
BlendFactor::ConstColor => pso::Factor::ConstColor,
BlendFactor::OneMinusConstColor => pso::Factor::OneMinusConstColor,
BlendFactor::ConstAlpha => pso::Factor::ConstAlpha,
BlendFactor::OneMinusConstAlpha => pso::Factor::OneMinusConstAlpha,
BlendFactor::SrcAlphaSaturate => pso::Factor::SrcAlphaSaturate,
BlendFactor::Src1Color => pso::Factor::Src1Color,
BlendFactor::OneMinusSrc1Color => pso::Factor::OneMinusSrc1Color,
BlendFactor::Src1Alpha => pso::Factor::Src1Alpha,
BlendFactor::OneMinusSrc1Alpha => pso::Factor::OneMinusSrc1Alpha,
}
}
}
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug)]
pub enum LogicOp {
Clear,
And,
AndReverse,
Copy,
AndInverted,
NoOp,
Xor,
Or,
Nor,
Equivalent,
Invert,
OrReverse,
CopyInverted,
OrInverted,
Nand,
Set,
}
impl LogicOp {
fn to_gfx_logic_op(self) -> pso::LogicOp {
match self {
LogicOp::Clear => pso::LogicOp::Clear,
LogicOp::And => pso::LogicOp::And,
LogicOp::AndReverse => pso::LogicOp::AndReverse,
LogicOp::Copy => pso::LogicOp::Copy,
LogicOp::AndInverted => pso::LogicOp::AndInverted,
LogicOp::NoOp => pso::LogicOp::NoOp,
LogicOp::Xor => pso::LogicOp::Xor,
LogicOp::Or => pso::LogicOp::Or,
LogicOp::Nor => pso::LogicOp::Nor,
LogicOp::Equivalent => pso::LogicOp::Equivalent,
LogicOp::Invert => pso::LogicOp::Invert,
LogicOp::OrReverse => pso::LogicOp::OrReverse,
LogicOp::CopyInverted => pso::LogicOp::CopyInverted,
LogicOp::OrInverted => pso::LogicOp::OrInverted,
LogicOp::Nand => pso::LogicOp::Nand,
LogicOp::Set => pso::LogicOp::Set,
}
}
}
#[derive(Clone, Copy, Debug)]
pub enum BlendOp {
Add {
src: BlendFactor,
dst: BlendFactor,
},
Sub {
src: BlendFactor,
dst: BlendFactor,
},
RevSub {
src: BlendFactor,
dst: BlendFactor,
},
Min,
Max,
}
impl BlendOp {
fn to_gfx_blend_op(self) -> pso::BlendOp {
match self {
BlendOp::Add { src, dst } => pso::BlendOp::Add {
src: src.to_gfx_blend_factor(),
dst: dst.to_gfx_blend_factor(),
},
BlendOp::Sub { src, dst } => pso::BlendOp::Sub {
src: src.to_gfx_blend_factor(),
dst: dst.to_gfx_blend_factor(),
},
BlendOp::RevSub { src, dst } => pso::BlendOp::RevSub {
src: src.to_gfx_blend_factor(),
dst: dst.to_gfx_blend_factor(),
},
BlendOp::Min => pso::BlendOp::Min,
BlendOp::Max => pso::BlendOp::Max,
}
}
}
#[derive(Clone, Copy, Debug)]
pub struct BlendState {
color: BlendOp,
alpha: BlendOp,
}
impl BlendState {
fn to_gfx_blend_state(self) -> pso::BlendState {
pso::BlendState {
color: self.color.to_gfx_blend_op(),
alpha: self.alpha.to_gfx_blend_op(),
}
}
}
#[derive(Clone, Debug)]
pub struct Blender {
logic_op: Option<pso::LogicOp>,
targets: Vec<pso::ColorBlendDesc>,
is_default: bool,
}
impl Blender {
pub(crate) fn into_gfx_blender(self) -> pso::BlendDesc {
pso::BlendDesc {
logic_op: self.logic_op,
targets: self.targets,
}
}
pub fn logic_op(mut self, op: LogicOp) -> Self {
self.logic_op = Some(op.to_gfx_logic_op());
self
}
fn add_blend_state(&mut self, state: BlendState, mask: pso::ColorMask) {
let state = pso::ColorBlendDesc {
mask,
blend: Some(state.to_gfx_blend_state()),
};
if self.is_default {
self.targets = vec![state];
self.is_default = false;
} else {
self.targets.push(state);
}
}
pub fn all(mut self, state: BlendState) -> Self {
self.add_blend_state(state, pso::ColorMask::ALL);
self
}
pub fn colors(mut self, state: BlendOp) -> Self {
self.add_blend_state(
BlendState {
color: state,
alpha: BlendOp::Min,
},
pso::ColorMask::COLOR,
);
self
}
pub fn alpha(mut self, state: BlendOp) -> Self {
self.add_blend_state(
BlendState {
color: BlendOp::Min,
alpha: state,
},
pso::ColorMask::ALPHA,
);
self
}
pub fn red(mut self, state: BlendOp) -> Self {
self.add_blend_state(
BlendState {
color: state,
alpha: BlendOp::Min,
},
pso::ColorMask::RED,
);
self
}
pub fn green(mut self, state: BlendOp) -> Self {
self.add_blend_state(
BlendState {
color: state,
alpha: BlendOp::Min,
},
pso::ColorMask::GREEN,
);
self
}
pub fn blue(mut self, state: BlendOp) -> Self {
self.add_blend_state(
BlendState {
color: state,
alpha: BlendOp::Min,
},
pso::ColorMask::BLUE,
);
self
}
pub fn none(mut self) -> Self {
self.targets = vec![pso::ColorBlendDesc {
mask: pso::ColorMask::NONE,
blend: None,
}];
self
}
}
impl Default for Blender {
fn default() -> Self {
let blend_state = pso::BlendState {
color: pso::BlendOp::Add {
src: pso::Factor::SrcAlpha,
dst: pso::Factor::OneMinusSrcAlpha,
},
alpha: pso::BlendOp::Max,
};
Self {
logic_op: None,
targets: vec![pso::ColorBlendDesc {
mask: pso::ColorMask::ALL,
blend: Some(blend_state),
}],
is_default: true,
}
}
}