use super::*;
use std::mem::transmute;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum EnableOption {
Blend,
ColorLogicOperation,
CullFace,
DepthClamp,
DepthTest,
Dither,
FramebufferSRGB,
LineSmooth,
Multisample,
SampleShading,
SampleMask,
ScissorTest,
StencilTest,
TextureCubeMapSeamless,
ProgramPointSize,
}
impl From<EnableOption> for u32 {
fn from(option: EnableOption) -> Self {
match option {
EnableOption::Blend => gl::BLEND,
EnableOption::ColorLogicOperation => gl::COLOR_LOGIC_OP,
EnableOption::CullFace => gl::CULL_FACE,
EnableOption::DepthClamp => gl::DEPTH_CLAMP,
EnableOption::DepthTest => gl::DEPTH_TEST,
EnableOption::Dither => gl::DITHER,
EnableOption::FramebufferSRGB => gl::FRAMEBUFFER_SRGB,
EnableOption::LineSmooth => gl::LINE_SMOOTH,
EnableOption::Multisample => gl::MULTISAMPLE,
EnableOption::SampleShading => gl::SAMPLE_SHADING,
EnableOption::SampleMask => gl::SAMPLE_MASK,
EnableOption::ScissorTest => gl::SCISSOR_TEST,
EnableOption::StencilTest => gl::STENCIL_TEST,
EnableOption::TextureCubeMapSeamless => gl::TEXTURE_CUBE_MAP_SEAMLESS,
EnableOption::ProgramPointSize => gl::PROGRAM_POINT_SIZE,
}
}
}
impl From<EnableOption> for usize {
fn from(option: EnableOption) -> Self {
match option {
EnableOption::Blend => 0,
EnableOption::ColorLogicOperation => 1,
EnableOption::CullFace => 2,
EnableOption::DepthClamp => 3,
EnableOption::DepthTest => 4,
EnableOption::Dither => 5,
EnableOption::FramebufferSRGB => 6,
EnableOption::LineSmooth => 7,
EnableOption::Multisample => 8,
EnableOption::SampleShading => 9,
EnableOption::SampleMask => 10,
EnableOption::ScissorTest => 11,
EnableOption::StencilTest => 12,
EnableOption::TextureCubeMapSeamless => 13,
EnableOption::ProgramPointSize => 14,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum StencilTest {
AlwaysPass,
AlwaysFail,
Less {
reference: i32,
mask: u32,
},
LessOrEqual {
reference: i32,
mask: u32,
},
Greater {
reference: i32,
mask: u32,
},
GreaterOrEqual {
reference: i32,
mask: u32,
},
Equal {
reference: i32,
mask: u32,
},
NotEqual {
reference: i32,
mask: u32,
},
}
impl StencilTest {
pub fn reference(&self) -> i32 {
match *self {
StencilTest::AlwaysPass | StencilTest::AlwaysFail => 0,
StencilTest::Less { reference, mask: _ } => reference,
StencilTest::LessOrEqual { reference, mask: _ } => reference,
StencilTest::Greater { reference, mask: _ } => reference,
StencilTest::GreaterOrEqual { reference, mask: _ } => reference,
StencilTest::Equal { reference, mask: _ } => reference,
StencilTest::NotEqual { reference, mask: _ } => reference,
}
}
pub fn mask(&self) -> u32 {
match *self {
StencilTest::AlwaysPass | StencilTest::AlwaysFail => 0,
StencilTest::Less { reference: _, mask } => mask,
StencilTest::LessOrEqual { reference: _, mask } => mask,
StencilTest::Greater { reference: _, mask } => mask,
StencilTest::GreaterOrEqual { reference: _, mask } => mask,
StencilTest::Equal { reference: _, mask } => mask,
StencilTest::NotEqual { reference: _, mask } => mask,
}
}
}
impl Default for StencilTest {
fn default() -> StencilTest {
StencilTest::AlwaysPass
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DepthTest {
Ignore,
Overwrite,
Less,
Equal,
LessOrEqual,
Greater,
NotEqual,
GreaterOrEqual,
}
impl From<DepthTest> for gl::types::GLenum {
fn from(depth_test: DepthTest) -> Self {
match depth_test {
DepthTest::Ignore => gl::NEVER,
DepthTest::Overwrite => gl::ALWAYS,
DepthTest::Less => gl::LESS,
DepthTest::LessOrEqual => gl::LEQUAL,
DepthTest::Greater => gl::GREATER,
DepthTest::GreaterOrEqual => gl::GEQUAL,
DepthTest::Equal => gl::EQUAL,
DepthTest::NotEqual => gl::NOTEQUAL,
}
}
}
impl Default for DepthTest {
fn default() -> DepthTest {
DepthTest::Less
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum DepthMask {
Enabled,
Disabled,
}
impl From<DepthMask> for bool {
fn from(mask: DepthMask) -> Self {
match mask {
DepthMask::Enabled => true,
DepthMask::Disabled => false,
}
}
}
impl From<DepthMask> for u8 {
fn from(mask: DepthMask) -> Self {
match mask {
DepthMask::Enabled => 1,
DepthMask::Disabled => 0,
}
}
}
impl Default for DepthMask {
fn default() -> DepthMask {
DepthMask::Enabled
}
}
#[derive(Clone, Copy, Debug)]
pub struct DepthRange {
pub near: f64,
pub far: f64,
}
impl PartialEq for DepthRange {
fn eq(&self, other: &DepthRange) -> bool {
unsafe {
transmute::<f64, u64>(self.near) == transmute::<f64, u64>(other.near)
&& transmute::<f64, u64>(self.far) == transmute::<f64, u64>(other.far)
}
}
}
impl Eq for DepthRange {}
impl Default for DepthRange {
fn default() -> DepthRange {
DepthRange {
near: 0.0,
far: 1.0,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum LogicOperation {
NoOperation,
Clear,
Set,
CopyIncoming,
CopyIncomingInverted,
Invert,
And,
NotAnd,
Or,
Nor,
Xor,
Equivalent,
AndReverse,
AndInverted,
OrReverse,
OrInverted,
}
impl From<LogicOperation> for gl::types::GLenum {
fn from(logic_operation: LogicOperation) -> Self {
match logic_operation {
LogicOperation::NoOperation => gl::NOOP,
LogicOperation::Clear => gl::CLEAR,
LogicOperation::Set => gl::SET,
LogicOperation::CopyIncoming => gl::COPY,
LogicOperation::CopyIncomingInverted => gl::COPY_INVERTED,
LogicOperation::Invert => gl::INVERT,
LogicOperation::And => gl::AND,
LogicOperation::NotAnd => gl::NAND,
LogicOperation::Or => gl::OR,
LogicOperation::Nor => gl::NOR,
LogicOperation::Xor => gl::XOR,
LogicOperation::Equivalent => gl::EQUIV,
LogicOperation::AndReverse => gl::AND_REVERSE,
LogicOperation::AndInverted => gl::AND_INVERTED,
LogicOperation::OrReverse => gl::OR_REVERSE,
LogicOperation::OrInverted => gl::OR_INVERTED,
}
}
}
impl Default for LogicOperation {
fn default() -> LogicOperation {
LogicOperation::NoOperation
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BlendingEquation {
Min,
Max,
Addition,
Subtraction,
ReverseSubtraction,
}
impl From<BlendingEquation> for gl::types::GLenum {
fn from(function: BlendingEquation) -> Self {
match function {
BlendingEquation::Min => gl::MIN,
BlendingEquation::Max => gl::MAX,
BlendingEquation::Addition => gl::FUNC_ADD,
BlendingEquation::Subtraction => gl::FUNC_SUBTRACT,
BlendingEquation::ReverseSubtraction => gl::FUNC_REVERSE_SUBTRACT,
}
}
}
impl Default for BlendingEquation {
fn default() -> BlendingEquation {
BlendingEquation::Addition
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum LinearBlendingFactor {
Zero,
One,
SourceColor,
OneMinusSourceColor,
DestinationColor,
OneMinusDestinationColor,
SourceAlpha,
SourceAlphaSaturate,
OneMinusSourceAlpha,
DestinationAlpha,
OneMinusDestinationAlpha,
ConstantColor,
OneMinusConstantColor,
ConstantAlpha,
OneMinusConstantAlpha,
}
impl From<LinearBlendingFactor> for gl::types::GLenum {
fn from(factor: LinearBlendingFactor) -> Self {
match factor {
LinearBlendingFactor::Zero => gl::ZERO,
LinearBlendingFactor::One => gl::ONE,
LinearBlendingFactor::SourceColor => gl::SRC_COLOR,
LinearBlendingFactor::OneMinusSourceColor => gl::ONE_MINUS_SRC_COLOR,
LinearBlendingFactor::DestinationColor => gl::DST_COLOR,
LinearBlendingFactor::OneMinusDestinationColor => gl::ONE_MINUS_DST_COLOR,
LinearBlendingFactor::SourceAlpha => gl::SRC_ALPHA,
LinearBlendingFactor::OneMinusSourceAlpha => gl::ONE_MINUS_SRC_ALPHA,
LinearBlendingFactor::DestinationAlpha => gl::DST_ALPHA,
LinearBlendingFactor::OneMinusDestinationAlpha => gl::ONE_MINUS_DST_ALPHA,
LinearBlendingFactor::SourceAlphaSaturate => gl::SRC_ALPHA_SATURATE,
LinearBlendingFactor::ConstantColor => gl::CONSTANT_COLOR,
LinearBlendingFactor::OneMinusConstantColor => gl::ONE_MINUS_CONSTANT_COLOR,
LinearBlendingFactor::ConstantAlpha => gl::CONSTANT_ALPHA,
LinearBlendingFactor::OneMinusConstantAlpha => gl::ONE_MINUS_CONSTANT_ALPHA,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum FaceOrientation {
Clockwise,
CounterClockwise,
}
impl From<FaceOrientation> for gl::types::GLenum {
fn from(orientation: FaceOrientation) -> Self {
match orientation {
FaceOrientation::Clockwise => gl::CW,
FaceOrientation::CounterClockwise => gl::CCW,
}
}
}
impl Default for FaceOrientation {
fn default() -> FaceOrientation {
FaceOrientation::CounterClockwise
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct Viewport {
pub x: usize,
pub y: usize,
pub width: usize,
pub height: usize,
}
impl Default for Viewport {
fn default() -> Viewport {
Viewport {
x: 0,
y: 0,
width: 0,
height: 0,
}
}
}
#[derive(Debug, Copy, Clone)]
pub struct ClearColor {
pub r: f32,
pub g: f32,
pub b: f32,
pub a: f32,
}
impl PartialEq for ClearColor {
fn eq(&self, other: &ClearColor) -> bool {
unsafe {
transmute::<f32, u32>(self.r) == transmute::<f32, u32>(other.r)
&& transmute::<f32, u32>(self.g) == transmute::<f32, u32>(other.g)
&& transmute::<f32, u32>(self.b) == transmute::<f32, u32>(other.b)
&& transmute::<f32, u32>(self.a) == transmute::<f32, u32>(other.a)
}
}
}
impl Eq for ClearColor {}
impl Default for ClearColor {
fn default() -> ClearColor {
ClearColor {
r: 0.0,
g: 0.0,
b: 0.0,
a: 1.0,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ClipControlOrigin {
LowerLeft,
UpperLeft,
}
impl Default for ClipControlOrigin {
fn default() -> ClipControlOrigin {
ClipControlOrigin::LowerLeft
}
}
impl From<ClipControlOrigin> for gl::types::GLenum {
fn from(origin: ClipControlOrigin) -> Self {
match origin {
ClipControlOrigin::LowerLeft => gl::LOWER_LEFT,
ClipControlOrigin::UpperLeft => gl::UPPER_LEFT,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ClipControlDepth {
NegativeOneToOne,
ZeroToOne,
}
impl Default for ClipControlDepth {
fn default() -> ClipControlDepth {
ClipControlDepth::NegativeOneToOne
}
}
impl From<ClipControlDepth> for gl::types::GLenum {
fn from(depth: ClipControlDepth) -> Self {
match depth {
ClipControlDepth::NegativeOneToOne => gl::NEGATIVE_ONE_TO_ONE,
ClipControlDepth::ZeroToOne => gl::ZERO_TO_ONE,
}
}
}
pub fn enable(option: EnableOption) {
unsafe {
gl::Enable(option.into());
}
}
pub fn disable(option: EnableOption) {
unsafe {
gl::Disable(option.into());
}
}
pub fn viewport(viewport: Viewport) {
unsafe {
gl::Viewport(
viewport.x as i32,
viewport.y as i32,
viewport.width as i32,
viewport.height as i32,
);
}
}
pub fn stencil_func_separate(face: Face, test: StencilTest) {
unsafe {
match test {
StencilTest::AlwaysPass => gl::StencilFuncSeparate(face.into(), gl::ALWAYS, 0, u32::max_value()),
StencilTest::AlwaysFail => gl::StencilFuncSeparate(face.into(), gl::NEVER, 0, u32::max_value()),
StencilTest::Less { reference, mask } => gl::StencilFuncSeparate(face.into(), gl::LESS, reference, mask),
StencilTest::LessOrEqual { reference, mask } => {
gl::StencilFuncSeparate(face.into(), gl::LEQUAL, reference, mask)
}
StencilTest::Greater { reference, mask } => {
gl::StencilFuncSeparate(face.into(), gl::GREATER, reference, mask)
}
StencilTest::GreaterOrEqual { reference, mask } => {
gl::StencilFuncSeparate(face.into(), gl::GEQUAL, reference, mask)
}
StencilTest::Equal { reference, mask } => gl::StencilFuncSeparate(face.into(), gl::EQUAL, reference, mask),
StencilTest::NotEqual { reference, mask } => {
gl::StencilFuncSeparate(face.into(), gl::NOTEQUAL, reference, mask)
}
}
}
}
pub fn depth_function(test: DepthTest) {
unsafe {
gl::DepthFunc(test.into());
}
}
pub fn depth_mask(depth_mask: DepthMask) {
unsafe {
gl::DepthMask(depth_mask.into());
}
}
pub fn depth_range(depth_range: DepthRange) {
unsafe {
gl::DepthRange(depth_range.near, depth_range.far);
}
}
pub fn logic_op(logic_operation: LogicOperation) {
unsafe {
gl::LogicOp(logic_operation.into());
}
}
pub fn scissor(x: u32, y: u32, width: usize, height: usize) {
unsafe {
gl::Scissor(x as i32, y as i32, width as i32, height as i32);
}
}
pub fn blend_color(red: f32, green: f32, blue: f32, alpha: f32) {
unsafe {
gl::BlendColor(red, green, blue, alpha);
}
}
pub fn blend_equation_separate(rgb: BlendingEquation, alpha: BlendingEquation) {
unsafe {
gl::BlendEquationSeparate(rgb.into(), alpha.into());
}
}
pub fn blend_func_separate(
source_rgb: LinearBlendingFactor,
destination_rgb: LinearBlendingFactor,
source_alpha: LinearBlendingFactor,
destination_alpha: LinearBlendingFactor,
) {
unsafe {
gl::BlendFuncSeparate(
source_rgb.into(),
destination_rgb.into(),
source_alpha.into(),
destination_alpha.into(),
);
}
}
pub fn front_face(orientation: FaceOrientation) {
unsafe {
gl::FrontFace(orientation.into());
}
}
pub fn cull_face(face: Face) {
unsafe {
gl::CullFace(face.into());
}
}
pub fn clear_color(color: ClearColor) {
unsafe {
gl::ClearColor(color.r, color.g, color.b, color.a);
}
}
pub fn clear_depth(depth: f64) {
unsafe {
gl::ClearDepth(depth);
}
}
pub fn color_mask(red: bool, green: bool, blue: bool, alpha: bool) {
unsafe {
gl::ColorMask(red as u8, green as u8, blue as u8, alpha as u8);
}
}
pub fn clip_control(origin: ClipControlOrigin, depth: ClipControlDepth) {
unsafe {
gl::ClipControl(origin.into(), depth.into());
}
}