1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
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); } } }