use super::errors::*;
use std::path::Path;
use std::fs::File;
use std::io::prelude::*;
use raw::*;
#[derive(Debug)]
pub struct Shader {
id: ShaderId,
pub shader_type: ShaderType,
}
impl Shader {
pub fn new<T: AsRef<str>>(shader_type: ShaderType, sources: &[T]) -> Result<Shader> {
let id: ShaderId;
unsafe {
id = create_shader(shader_type);
shader_source(id, sources);
compile_shader(id);
if !get_shader_compiled(id) {
let shader_info_log =
get_shader_info_log(id).chain_err(|| "Could not retrieve shader compilation log")?;
delete_shader(id);
bail!(shader_info_log);
}
}
Ok(Shader {
id: id,
shader_type: shader_type,
})
}
pub fn from_files(shader_type: ShaderType, filepaths: &[&Path]) -> Result<Shader> {
let mut sources: Vec<String> = Vec::new();
for filepath in filepaths {
let mut file = match File::open(&filepath) {
Ok(file) => file,
Err(e) => return Err(format!("Could not open shader file : {}", e).into()),
};
let mut source = String::new();
match file.read_to_string(&mut source) {
Ok(_) => {}
Err(e) => return Err(format!("Could not read shader file! : {}", e).into()),
};
sources.push(source);
}
Shader::new(shader_type, sources.as_slice())
}
pub fn from_file(shader_type: ShaderType, filepath: &Path) -> Result<Shader> {
let mut file = match File::open(&filepath) {
Ok(file) => file,
Err(e) => return Err(format!("Could not open shader file : {}", e).into()),
};
let mut source = String::new();
match file.read_to_string(&mut source) {
Ok(_) => {}
Err(e) => return Err(format!("Could not read shader file! : {}", e).into()),
};
Shader::new(shader_type, &[source.as_str()])
}
pub fn get_id(&self) -> ShaderId {
self.id
}
}
impl Drop for Shader {
fn drop(&mut self) {
unsafe {
delete_shader(self.id);
}
}
}