gfxmath-vec3 0.1.3

A simple 3D math library
Documentation
use super::shader::Shader;

use gfxmath_vec3::Vec3;
use std::collections::HashMap;

pub struct ShaderProgram {
    pub (crate) id: u32,
    pub (crate) uniforms: HashMap<String, i32>
}

#[allow(dead_code)]
impl ShaderProgram {
    pub fn new() -> Option<Self> {
        unsafe { 
            let id: u32 = gl::CreateProgram(); 
            if id != 0 { return Some(Self{ id, uniforms: HashMap::new() }) }
        }
        None
    }

    #[inline]
    pub fn get_id(&self) -> u32 {
        return self.id
    }

    #[inline]
    pub fn activate(&self) -> &Self {
        unsafe { gl::UseProgram(self.id); }
        return self;
    }

    #[inline]
    pub fn attach(&self, shader: &Shader) -> &Self {
        unsafe { gl::AttachShader(self.id, shader.id); }
        return self;
    }
    
    #[inline]
    pub fn detach(&self, shader: &Shader) -> &Self {
        unsafe { gl::DetachShader(self.id, shader.id); }
        return self;
    }

    #[inline]
    pub fn link(&self) -> bool {
        unsafe {
            let mut status: i32 = 0;
            gl::LinkProgram(self.id);
            gl::GetProgramiv(self.id, gl::LINK_STATUS, &mut status);
            if status == gl::TRUE.into() { return true; }
            return false;
        }
    }



    #[inline]
    pub fn add_uniform(&mut self, name: &str) {
        if let None = self.uniforms.get(name) {
            unsafe { 
                let n = std::ffi::CString::new(name).expect("malformed uniform name");
                let location = gl::GetUniformLocation(self.id, n.as_ptr());
                if location >= 0 {
                    self.uniforms.insert(String::from(name), location);
                } else {
                    println!("Failed to add uniform ({:?}) - location: {:?}", name, location)
                }
            }
        }
    }

    #[inline]
    pub fn set_uniform_1i(&self, name: &str, value: i32) {
        if let Some(e) = self.uniforms.get(name) {
            unsafe { gl::Uniform1i(*e, value) };
        }
    }

    #[inline]
    pub fn set_uniform_1f(&self, name: &str, value: f32) {
        if let Some(e) = self.uniforms.get(name) {
            unsafe { gl::Uniform1f(*e, value) };
        }
    }

    #[inline]
    pub fn set_uniform_2f(&self, name: &str, value: &(f32, f32)) {
        if let Some(e) = self.uniforms.get(name) {
            unsafe { gl::Uniform2f(*e, value.0, value.1) };
        }
    }

    #[inline]
    pub fn set_uniform_2i(&self, name: &str, value: &(i32, i32)) {
        if let Some(e) = self.uniforms.get(name) {
            unsafe { gl::Uniform2i(*e, value.0, value.1) };
        }
    }

    #[inline]
    pub fn set_uniform_3f(&self, name: &str, value: &Vec3<f32>) {
        if let Some(e) = self.uniforms.get(name) {
            unsafe { gl::Uniform3f(*e, value.x, value.y, value.z) };
        }
    }

    #[inline]
    pub fn set_uniform_4f(&self, name: &str, value: &(f32, f32, f32, f32)) {
        if let Some(e) = self.uniforms.get(name) {
            unsafe { gl::Uniform4f(*e, value.0, value.1, value.2, value.3) };
        } else {
            println!("failed to set uniform: {:?} = {:?}", name, value)
        }
    }

    #[inline]
    pub fn set_uniform_matrix_4fv(&self, name: &str, count: gl::types::GLsizei, transpose: gl::types::GLboolean, value: *const gl::types::GLfloat) {
        if let Some(e) = self.uniforms.get(name) {
            unsafe { gl::UniformMatrix4fv(*e, count, transpose, value) };
        }
    }
}

impl Drop for ShaderProgram {
    fn drop(&mut self) {
        unsafe { gl::DeleteProgram(self.id); }
    }
}