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
pub mod program;
pub mod object;
pub mod data;
pub mod shader;
pub mod instanced;
use gl::types::*;
use std::ffi::CString;
use std::ptr;
// Shader holds the id to the location on the graphics card
// that is generated by opengl
pub struct Shader {
pub id: GLuint,
}
impl Shader {
// create a new shader from source code with
// either the type gl::VERTEX_SHADER or gl::FRAGMENT_SHADER
pub fn new(source_code: &str, shader_type: GLenum) -> Result<Self, String> {
unsafe {
let shader = Self {
id: gl::CreateShader(shader_type),
};
match CString::new(source_code) {
Ok(source_code) => {
// compile the shader
gl::ShaderSource(shader.id, 1, &source_code.as_ptr(), ptr::null());
gl::CompileShader(shader.id);
// check error status
let mut success: GLint = 0;
gl::GetShaderiv(shader.id, gl::COMPILE_STATUS, &mut success);
if success != 1 {
// get opengl compiler message
// and throw error
let mut error_log_size: GLint = 0;
gl::GetShaderiv(shader.id, gl::INFO_LOG_LENGTH, &mut error_log_size);
let mut error_log: Vec<u8> = Vec::with_capacity(error_log_size as usize);
gl::GetShaderInfoLog(
shader.id,
error_log_size,
&mut error_log_size,
error_log.as_mut_ptr() as *mut _,
);
error_log.set_len(error_log_size as usize);
let log = String::from_utf8(error_log).unwrap();
return Err(log);
}
},
_ => return Err("Could not create a CString.".to_string())
}
Ok(shader)
}
}
}
// delete the shader on the graphics card
// when the shader struct gets dropped
impl Drop for Shader {
fn drop(&mut self) {
unsafe {
gl::DeleteShader(self.id);
}
}
}