use gl::{self, types::*};
#[cfg(not(feature="webgl"))]
use texture::{Component, Swizzles};
use state::StateRef;
#[derive(Debug)]
pub struct Sampler{
id: GLuint,
gl: StateRef,
}
impl Drop for Sampler{
fn drop(&mut self){
unsafe{
self.gl.DeleteSamplers(1, &self.id)
}
}
}
impl Sampler{
pub(crate) fn new(gl: &StateRef) -> Sampler{
let mut id = 0;
unsafe{
gl.GenSamplers(1, &mut id);
}
Sampler{id, gl: gl.clone()}
}
pub fn id(&self) -> GLuint {
self.id
}
#[cfg(not(feature="webgl"))]
pub fn set_swizzle_r(&mut self, component: Component){
unsafe{
self.set_parameteri(gl::TEXTURE_SWIZZLE_R, component.to_dst() as GLint);
}
}
#[cfg(not(feature="webgl"))]
pub fn set_swizzle_g(&mut self, component: Component){
unsafe{
self.set_parameteri(gl::TEXTURE_SWIZZLE_G, component.to_dst() as GLint);
}
}
#[cfg(not(feature="webgl"))]
pub fn set_swizzle_b(&mut self, component: Component){
unsafe{
self.set_parameteri(gl::TEXTURE_SWIZZLE_B, component.to_dst() as GLint);
}
}
#[cfg(not(feature="webgl"))]
pub fn set_swizzle_a(&mut self, component: Component){
unsafe{
self.set_parameteri(gl::TEXTURE_SWIZZLE_A, component.to_dst() as GLint);
}
}
#[cfg(not(feature="webgl"))]
pub fn set_swizzles(&mut self, swizzles: Swizzles){
self.set_swizzle_r(swizzles.r);
self.set_swizzle_g(swizzles.g);
self.set_swizzle_b(swizzles.b);
self.set_swizzle_a(swizzles.a);
}
#[cfg(not(feature="webgl"))]
pub fn set_anisotropy_level(&mut self, level: f32){
unsafe{
self.set_parameterf(gl::TEXTURE_MAX_ANISOTROPY_EXT, level);
}
}
pub fn set_base_level(&mut self, level: GLint){
unsafe{
self.set_parameteri(gl::TEXTURE_BASE_LEVEL, level);
}
}
pub fn set_max_level(&mut self, level: GLint){
unsafe{
self.set_parameteri(gl::TEXTURE_MAX_LEVEL, level);
}
}
pub fn set_min_lod(&mut self, level: GLint){
unsafe{
self.set_parameteri(gl::TEXTURE_MIN_LOD, level);
}
}
pub fn set_max_lod(&mut self, level: GLint){
unsafe{
self.set_parameteri(gl::TEXTURE_MAX_LOD, level);
}
}
pub fn set_min_mag_filters(&mut self, min: GLuint, mag: GLuint){
unsafe{
self.set_parameteri(gl::TEXTURE_MIN_FILTER, min as GLint);
self.set_parameteri(gl::TEXTURE_MAG_FILTER, mag as GLint);
}
}
pub fn set_wrap_s(&mut self, wrap: GLenum){
unsafe{
self.set_parameteri(gl::TEXTURE_WRAP_S, wrap as GLint);
}
}
pub fn set_wrap_t(&mut self, wrap: GLenum){
unsafe{
self.set_parameteri(gl::TEXTURE_WRAP_T, wrap as GLint);
}
}
pub fn set_wrap_r(&mut self, wrap: GLenum){
unsafe{
self.set_parameteri(gl::TEXTURE_WRAP_R, wrap as GLint);
}
}
pub fn set_compare_mode(&mut self, mode: GLenum){
unsafe{
self.set_parameteri(gl::TEXTURE_COMPARE_MODE, mode as GLint)
}
}
pub fn set_compare_func(&mut self, mode: GLenum){
unsafe{
self.set_parameteri(gl::TEXTURE_COMPARE_FUNC, mode as GLint)
}
}
#[cfg(not(feature="webgl"))]
pub fn set_border_color(&mut self, color: &[f32;4]){
unsafe{
self.set_parameterfv(gl::TEXTURE_BORDER_COLOR, color);
}
}
#[cfg(not(feature="webgl"))]
pub fn depth_stencil_texture_mode(&self) -> GLenum{
unsafe{
self.get_parameteri(gl::DEPTH_STENCIL_TEXTURE_MODE) as GLenum
}
}
pub fn mag_filter(&self) -> GLenum{
unsafe{
self.get_parameteri(gl::TEXTURE_MAG_FILTER) as GLenum
}
}
pub fn min_filter(&self) -> GLenum{
unsafe{
self.get_parameteri(gl::TEXTURE_MIN_FILTER) as GLenum
}
}
pub fn min_lod(&self) -> i32{
unsafe{
self.get_parameteri(gl::TEXTURE_MIN_LOD)
}
}
pub fn max_lod(&self) -> i32{
unsafe{
self.get_parameteri(gl::TEXTURE_MAX_LOD)
}
}
pub fn base_level(&self) -> i32{
unsafe{
self.get_parameteri(gl::TEXTURE_BASE_LEVEL)
}
}
pub fn max_level(&self) -> i32{
unsafe{
self.get_parameteri(gl::TEXTURE_MAX_LEVEL)
}
}
#[cfg(not(feature="webgl"))]
pub fn swizzle_r(&self) -> Component{
unsafe{
let dst = self.get_parameteri(gl::TEXTURE_SWIZZLE_R);
Component::from_dst(dst as GLenum).unwrap()
}
}
#[cfg(not(feature="webgl"))]
pub fn swizzle_g(&self) -> Component{
unsafe{
let dst = self.get_parameteri(gl::TEXTURE_SWIZZLE_G);
Component::from_dst(dst as GLenum).unwrap()
}
}
#[cfg(not(feature="webgl"))]
pub fn swizzle_b(&self) -> Component{
unsafe{
let dst = self.get_parameteri(gl::TEXTURE_SWIZZLE_B);
Component::from_dst(dst as GLenum).unwrap()
}
}
#[cfg(not(feature="webgl"))]
pub fn swizzle_a(&self) -> Component{
unsafe{
let dst = self.get_parameteri(gl::TEXTURE_SWIZZLE_A);
Component::from_dst(dst as GLenum).unwrap()
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
pub fn swizzles(&self) -> Swizzles{
let rgba = unsafe{
self.get_parameterfv(gl::TEXTURE_SWIZZLE_RGBA, 4)
};
Swizzles{
r: Component::from_dst(rgba[0] as GLenum).unwrap(),
g: Component::from_dst(rgba[1] as GLenum).unwrap(),
b: Component::from_dst(rgba[2] as GLenum).unwrap(),
a: Component::from_dst(rgba[3] as GLenum).unwrap(),
}
}
#[cfg(feature = "gles")]
pub fn swizzles(&self) -> Swizzles{
let r;
let g;
let b;
let a;
unsafe{
r = self.get_parameterf(gl::TEXTURE_SWIZZLE_R);
g = self.get_parameterf(gl::TEXTURE_SWIZZLE_G);
b = self.get_parameterf(gl::TEXTURE_SWIZZLE_B);
a = self.get_parameterf(gl::TEXTURE_SWIZZLE_A);
}
Swizzles{
r: Component::from_dst(r as GLenum).unwrap(),
g: Component::from_dst(g as GLenum).unwrap(),
b: Component::from_dst(b as GLenum).unwrap(),
a: Component::from_dst(a as GLenum).unwrap(),
}
}
pub fn wrap_s(&self) -> GLenum{
unsafe{
self.get_parameteri(gl::TEXTURE_WRAP_S) as GLenum
}
}
pub fn wrap_t(&self) -> GLenum{
unsafe{
self.get_parameteri(gl::TEXTURE_WRAP_T) as GLenum
}
}
pub fn wrap_r(&self) -> GLenum{
unsafe{
self.get_parameteri(gl::TEXTURE_WRAP_R) as GLenum
}
}
#[cfg(not(feature="webgl"))]
pub fn border_color(&self) -> [f32;4]{
unsafe{
let vector = self.get_parameterfv(gl::TEXTURE_BORDER_COLOR, 4);
let mut arr = [0f32; 4];
arr.copy_from_slice(&vector);
arr
}
}
pub fn compare_mode(&self) -> GLenum{
unsafe{
self.get_parameteri(gl::TEXTURE_COMPARE_MODE) as GLenum
}
}
pub fn compare_func(&self) -> GLenum{
unsafe{
self.get_parameteri(gl::TEXTURE_COMPARE_FUNC) as GLenum
}
}
#[cfg(not(feature="webgl"))]
pub fn image_format_compatibility_type(&self) -> GLenum{
unsafe{
self.get_parameteri(gl::IMAGE_FORMAT_COMPATIBILITY_TYPE) as GLenum
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
pub fn seamless(&self) -> bool {
unsafe{
self.get_parameteri(gl::TEXTURE_CUBE_MAP_SEAMLESS) != 0
}
}
#[cfg(all(not(feature = "gles"), not(feature="webgl")))]
pub fn set_seamless(&mut self, seamless: bool) {
unsafe{
self.set_parameteri(gl::TEXTURE_CUBE_MAP_SEAMLESS, seamless as u8 as i32)
}
}
pub unsafe fn set_parameteri(&mut self, parameter: GLenum, value: GLint) {
#[cfg(target_os="emscripten")]
{
extern "C"{
fn emscripten_glSamplerParameteri(id: GLuint, parameter: GLenum, value: GLint);
}
emscripten_glSamplerParameteri(self.id, parameter, value)
}
#[cfg(not(target_os="emscripten"))]
{
self.gl.SamplerParameteri(self.id, parameter, value)
}
}
pub unsafe fn set_parameterf(&mut self, parameter: GLenum, value: GLfloat) {
#[cfg(target_os="emscripten")]
{
extern "C"{
fn emscripten_glSamplerParameterf(id: GLuint, parameter: GLenum, value: GLfloat);
}
emscripten_glSamplerParameterf(self.id, parameter, value)
}
#[cfg(not(target_os="emscripten"))]
{
self.gl.SamplerParameterf(self.id, parameter, value)
}
}
pub unsafe fn set_parameteriv(&mut self, parameter: GLenum, value: &[GLint]) {
#[cfg(target_os="emscripten")]
{
extern "C"{
fn emscripten_glSamplerParameteriv(id: GLuint, parameter: GLenum, value: *const GLint);
}
emscripten_glSamplerParameteriv(self.id, parameter, value.as_ptr())
}
#[cfg(not(target_os="emscripten"))]
{
self.gl.SamplerParameteriv(self.id, parameter, value.as_ptr())
}
}
pub unsafe fn set_parameterfv(&mut self, parameter: GLenum, value: &[GLfloat]) {
#[cfg(target_os="emscripten")]
{
extern "C"{
fn emscripten_glSamplerParameterfv(id: GLuint, parameter: GLenum, value: *const GLfloat);
}
emscripten_glSamplerParameterfv(self.id, parameter, value.as_ptr())
}
#[cfg(not(target_os="emscripten"))]
{
self.gl.SamplerParameterfv(self.id, parameter, value.as_ptr())
}
}
pub unsafe fn get_parameteri(&self, parameter: GLenum) -> GLint {
let mut value = 0;
#[cfg(target_os="emscripten")]
{
extern "C"{
fn emscripten_glGetSamplerParameteriv(id: GLuint, parameter: GLenum, value: *const GLint);
}
emscripten_glGetSamplerParameteriv(self.id, parameter, &mut value)
}
#[cfg(not(target_os="emscripten"))]
{
self.gl.GetSamplerParameteriv(self.id, parameter, &mut value)
}
value
}
pub unsafe fn get_parameterf(&self, parameter: GLenum) -> GLfloat {
let mut value = 0.;
#[cfg(target_os="emscripten")]
{
extern "C"{
fn emscripten_glGetSamplerParameterfv(id: GLuint, parameter: GLenum, value: *const GLfloat);
}
emscripten_glGetSamplerParameterfv(self.id, parameter, &mut value)
}
#[cfg(not(target_os="emscripten"))]
{
self.gl.GetSamplerParameterfv(self.id, parameter, &mut value)
}
value
}
pub unsafe fn get_parameteriv(&self, parameter: GLenum, len: usize) -> Vec<GLint> {
let mut value = vec![0;len];
#[cfg(target_os="emscripten")]
{
extern "C"{
fn emscripten_glGetSamplerParameteriv(id: GLuint, parameter: GLenum, value: *const GLint);
}
emscripten_glGetSamplerParameteriv(self.id, parameter, value.as_mut_ptr())
}
#[cfg(not(target_os="emscripten"))]
{
self.gl.GetSamplerParameteriv(self.id, parameter, value.as_mut_ptr())
}
value
}
pub unsafe fn get_parameterfv(&self, parameter: GLenum, len: usize) -> Vec<GLfloat> {
let mut value = vec![0.;len];
#[cfg(target_os="emscripten")]
{
extern "C"{
fn emscripten_glGetSamplerParameterfv(id: GLuint, parameter: GLenum, value: *const GLfloat);
}
emscripten_glGetSamplerParameterfv(self.id, parameter, value.as_mut_ptr())
}
#[cfg(not(target_os="emscripten"))]
{
self.gl.GetSamplerParameterfv(self.id, parameter, value.as_mut_ptr())
}
value
}
}