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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
use super::*; use super::errors::*; use std::ptr; use std::ffi::CString; use std::mem::uninitialized; #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct ShaderId(u32); impl From<ShaderId> for u32 { fn from(shader_id: ShaderId) -> Self { shader_id.0 } } #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum ShaderParameter { ShaderType, DeleteStatus, CompileStatus, InfoLogLength, ShaderSourceLength, } impl From<ShaderParameter> for u32 { fn from(shader_parameter: ShaderParameter) -> Self { use self::ShaderParameter::*; match shader_parameter { ShaderType => gl::SHADER_TYPE, DeleteStatus => gl::DELETE_STATUS, CompileStatus => gl::COMPILE_STATUS, InfoLogLength => gl::INFO_LOG_LENGTH, ShaderSourceLength => gl::SHADER_SOURCE_LENGTH, } } } #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub enum ShaderType { Vertex, Fragment, Geometry, TessellationEvaluation, TessellationControl, Compute, } impl From<ShaderType> for u32 { fn from(shader_type: ShaderType) -> Self { match shader_type { ShaderType::Vertex => gl::VERTEX_SHADER, ShaderType::Fragment => gl::FRAGMENT_SHADER, ShaderType::Geometry => gl::GEOMETRY_SHADER, ShaderType::TessellationEvaluation => gl::TESS_EVALUATION_SHADER, ShaderType::TessellationControl => gl::TESS_CONTROL_SHADER, ShaderType::Compute => gl::COMPUTE_SHADER, } } } pub unsafe fn create_shader(shader_type: ShaderType) -> ShaderId { ShaderId(gl::CreateShader(shader_type.into())) } pub unsafe fn shader_source(id: ShaderId, sources: &[&str]) { let source = sources.join(""); let source_cstr = CString::new(source.as_bytes()).unwrap(); gl::ShaderSource(id.into(), 1, [source_cstr.as_ptr()].as_ptr(), ptr::null()); } pub unsafe fn compile_shader(id: ShaderId) { gl::CompileShader(id.into()); } pub unsafe fn get_shader(id: ShaderId, parameter: ShaderParameter) -> i32 { let mut value: gl::types::GLint = uninitialized(); gl::GetShaderiv(id.into(), parameter.into(), &mut value); value } pub unsafe fn get_shader_info_log(id: ShaderId) -> Result<String> { let mut error_log_size: gl::types::GLint = get_shader(id.into(), ShaderParameter::InfoLogLength); let mut error_log: Vec<u8> = Vec::with_capacity(error_log_size as usize); gl::GetShaderInfoLog( id.into(), error_log_size, &mut error_log_size, error_log.as_mut_ptr() as *mut gl::types::GLchar, ); error_log.set_len(error_log_size as usize); let string = match String::from_utf8(error_log) { Ok(s) => s, Err(_) => bail!("Could not convert log"), }; Ok(string) } pub unsafe fn delete_shader(id: ShaderId) { gl::DeleteShader(id.into()) }