use std::mem;
use gl;
use gl::types::*;
use super::{Blending, CullFace, Depth, DrawMode, Error, IndexKind};
#[inline]
pub fn gl_set_defaults() {
unsafe {
gl::FrontFace(gl::CCW);
if gl::PixelStorei::is_loaded() {
gl::PixelStorei(gl::UNPACK_ALIGNMENT, 1);
}
}
gl_set_viewport(0, 0, 1, 1);
gl_set_clear_depth(1.0);
gl_set_clear_stencil(0);
gl_set_depth_write(true);
gl_set_depth_range(0.0, 1.0);
gl_set_line_width(1.0);
gl_set_blending(Blending::Default);
gl_set_cull_face(CullFace::Back);
gl_set_depth_func(Depth::LessThanOrEqual);
gl_set_clear_color(&[0.0, 0.0, 0.0, 1.0]);
gl_clear(true, true, true);
}
#[inline(always)]
pub fn gl_get_error() -> Error {
unsafe { gl::GetError().into() }
}
#[inline(always)]
pub fn gl_set_viewport(x: usize, y: usize, width: usize, height: usize) {
unsafe {
gl::Viewport(x as GLint, y as GLint, width as GLsizei, height as GLsizei);
}
}
#[inline(always)]
pub fn gl_set_clear_depth(clear_depth: f64) {
unsafe {
if gl::ClearDepthf::is_loaded() {
gl::ClearDepthf(clear_depth as f32);
} else if gl::ClearDepth::is_loaded() {
gl::ClearDepth(clear_depth);
}
}
}
#[inline(always)]
pub fn gl_set_clear_stencil(clear_stencil: isize) {
unsafe {
gl::ClearStencil(clear_stencil as GLint);
}
}
#[inline(always)]
pub fn gl_set_depth_write(depth_write: bool) {
unsafe {
gl::DepthMask(if depth_write { gl::TRUE } else { gl::FALSE });
}
}
#[inline(always)]
pub fn gl_set_depth_range(near: f64, far: f64) {
unsafe {
if gl::DepthRangef::is_loaded() {
gl::DepthRangef(near as f32, far as f32);
} else if gl::DepthRange::is_loaded() {
gl::DepthRange(near, far);
}
}
}
#[inline(always)]
pub fn gl_set_line_width(line_width: f32) {
unsafe {
gl::LineWidth(line_width as GLfloat);
}
}
#[inline]
pub fn gl_set_blending(blending: Blending) {
match &blending {
&Blending::Additive => unsafe {
gl::Enable(gl::BLEND);
gl::BlendEquation(gl::FUNC_ADD);
gl::BlendFunc(gl::SRC_ALPHA, gl::ONE);
},
&Blending::Subtractive => unsafe {
gl::Enable(gl::BLEND);
gl::BlendEquation(gl::FUNC_ADD);
gl::BlendFunc(gl::ZERO, gl::ONE_MINUS_SRC_COLOR);
},
&Blending::Multiply => unsafe {
gl::Enable(gl::BLEND);
gl::BlendEquation(gl::FUNC_ADD);
gl::BlendFunc(gl::ZERO, gl::SRC_COLOR);
},
&Blending::Default => unsafe {
gl::Enable(gl::BLEND);
gl::BlendEquationSeparate(gl::FUNC_ADD, gl::FUNC_ADD);
gl::BlendFuncSeparate(
gl::SRC_ALPHA,
gl::ONE_MINUS_SRC_ALPHA,
gl::ONE,
gl::ONE_MINUS_SRC_ALPHA,
);
},
&Blending::None => unsafe {
gl::Disable(gl::BLEND);
},
}
}
#[inline]
pub fn gl_set_cull_face(cull_face: CullFace) {
match &cull_face {
&CullFace::Back => unsafe {
gl::Enable(gl::CULL_FACE);
gl::CullFace(gl::BACK);
},
&CullFace::Front => unsafe {
gl::Enable(gl::CULL_FACE);
gl::CullFace(gl::FRONT);
},
&CullFace::FrontAndBack => unsafe {
gl::Enable(gl::CULL_FACE);
gl::CullFace(gl::FRONT_AND_BACK);
},
&CullFace::None => unsafe {
gl::Disable(gl::CULL_FACE);
},
}
}
#[inline]
pub fn gl_set_depth_func(depth_func: Depth) {
match &depth_func {
&Depth::Never => unsafe {
gl::Enable(gl::DEPTH_TEST);
gl::DepthFunc(gl::NEVER);
},
&Depth::LessThan => unsafe {
gl::Enable(gl::DEPTH_TEST);
gl::DepthFunc(gl::LESS);
},
&Depth::Equal => unsafe {
gl::Enable(gl::DEPTH_TEST);
gl::DepthFunc(gl::EQUAL);
},
&Depth::LessThanOrEqual => unsafe {
gl::Enable(gl::DEPTH_TEST);
gl::DepthFunc(gl::LEQUAL);
},
&Depth::GreaterThan => unsafe {
gl::Enable(gl::DEPTH_TEST);
gl::DepthFunc(gl::GREATER);
},
&Depth::NotEqual => unsafe {
gl::Enable(gl::DEPTH_TEST);
gl::DepthFunc(gl::NOTEQUAL);
},
&Depth::GreaterThanOrEqual => unsafe {
gl::Enable(gl::DEPTH_TEST);
gl::DepthFunc(gl::GEQUAL);
},
&Depth::Always => unsafe {
gl::Enable(gl::DEPTH_TEST);
gl::DepthFunc(gl::ALWAYS);
},
&Depth::None => unsafe {
gl::Disable(gl::DEPTH_TEST);
},
}
}
#[inline(always)]
pub fn gl_set_clear_color(color: &[f32; 4]) {
unsafe {
gl::ClearColor(color[0], color[1], color[2], color[3]);
}
}
#[inline]
pub fn gl_clear(color: bool, depth: bool, stencil: bool) {
let mut bits: GLbitfield = 0;
if color {
bits = bits | gl::COLOR_BUFFER_BIT;
}
if depth {
bits = bits | gl::DEPTH_BUFFER_BIT;
}
if stencil {
bits = bits | gl::STENCIL_BUFFER_BIT;
}
gl_clear_bits(bits);
}
#[inline(always)]
pub fn gl_clear_bits(bits: GLbitfield) {
unsafe {
gl::Clear(bits);
}
}
#[inline]
pub fn gl_draw_arrays(mode: DrawMode, first: usize, count: usize) {
unsafe {
gl::DrawArrays(mode.into(), first as GLint, count as GLsizei);
}
}
#[inline]
pub fn gl_draw_elements(mode: DrawMode, count: usize, kind: IndexKind, offset: GLint) {
unsafe {
gl::DrawElements(
mode.into(),
count as GLint,
kind.into(),
mem::transmute(offset as usize),
);
}
}