fere/graphics/glmanager/
compile.rs

1use gl::types::*;
2use std::{ffi::CString, ptr, str};
3
4pub fn compile_shader(path: &str, src: &str, ty: GLenum) -> GLuint {
5    let shader;
6    unsafe {
7        shader = gl::CreateShader(ty);
8        // Attempt to compile the shader
9        let c_str = CString::new(src.as_bytes()).unwrap();
10        gl::ShaderSource(shader, 1, &c_str.as_ptr(), ptr::null());
11        gl::CompileShader(shader);
12
13        // Get the compile status
14        let mut status = gl::FALSE as GLint;
15        gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);
16
17        // Fail on error
18        if status != (gl::TRUE as GLint) {
19            println!("While compiling {}", path);
20            let mut len = 0;
21            gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
22            let mut buf = Vec::with_capacity(len as usize);
23            buf.set_len((len as usize) - 1); // subtract 1 to skip the trailing null character
24            gl::GetShaderInfoLog(
25                shader,
26                len,
27                ptr::null_mut(),
28                buf.as_mut_ptr() as *mut GLchar,
29            );
30            panic!(
31                "{}",
32                str::from_utf8(&buf).expect("ShaderInfoLog not valid utf8")
33            );
34        }
35    }
36    shader
37}
38
39pub fn link_program(vs: GLuint, fs: GLuint) -> GLuint {
40    unsafe {
41        let program = gl::CreateProgram();
42        gl::AttachShader(program, vs);
43        gl::AttachShader(program, fs);
44
45        let loc_pos = 0;
46        let loc_normal = 1;
47        let loc_tex = 2;
48        let loc_fnormal = 3;
49
50        let c_str = CString::new("io_pos".as_bytes()).unwrap();
51        gl::BindAttribLocation(program, loc_pos, c_str.as_ptr());
52        let c_str = CString::new("io_normal".as_bytes()).unwrap();
53        gl::BindAttribLocation(program, loc_normal, c_str.as_ptr());
54        let c_str = CString::new("io_tex".as_bytes()).unwrap();
55        gl::BindAttribLocation(program, loc_tex, c_str.as_ptr());
56        let c_str = CString::new("io_fnormal".as_bytes()).unwrap();
57        gl::BindAttribLocation(program, loc_fnormal, c_str.as_ptr());
58
59        gl::LinkProgram(program);
60        // Get the link status
61        let mut status = gl::FALSE as GLint;
62        gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);
63
64        // Fail on error
65        if status != (gl::TRUE as GLint) {
66            let mut len: GLint = 0;
67            gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
68            let mut buf = Vec::with_capacity(len as usize);
69            buf.set_len((len as usize) - 1); // subtract 1 to skip the trailing null character
70            gl::GetProgramInfoLog(
71                program,
72                len,
73                ptr::null_mut(),
74                buf.as_mut_ptr() as *mut GLchar,
75            );
76            panic!(
77                "{}",
78                str::from_utf8(&buf).expect("ProgramInfoLog is not valid utf-8")
79            );
80        }
81
82        let mut count = 0;
83        gl::GetProgramiv(program, gl::ACTIVE_UNIFORMS, &mut count);
84
85        /*
86        print list of uniforms
87        for i in 0..count
88        {
89            let mut size = 0 as i32;
90            let mut t = 0 as u32;
91            let mut name = [0; 64];
92            let mut length = 0;
93            gl::GetActiveUniform(program, i as u32, 64, &mut length, &mut size, &mut t, name.as_mut_ptr());
94            let name: Vec<u8> = name.iter().map(|&x| x as u8).collect();
95            let name = std::str::from_utf8(&name).unwrap();
96            println!("{} {}", i, name);
97            //printf("Uniform #%d Type: %u Name: %s\n", i, type, name);
98        }
99        */
100
101        program
102    }
103}