mod3d_gl/opengl/
utils.rs

1use std;
2use std::ffi::CString;
3
4//a Functions
5//fp create_whitespace_cstring_with_len
6/// Create a CString of 'len' spaces (with null termination)
7pub fn create_whitespace_cstring_with_len(len: usize) -> CString {
8    // allocate buffer of correct size
9    let mut buffer: Vec<u8> = Vec::with_capacity(len + 1);
10    // fill it with len spaces
11    buffer.extend([b' '].iter().cycle().take(len));
12    // convert buffer to CString
13    unsafe { CString::from_vec_unchecked(buffer) }
14}
15
16//fp check_errors
17/// Check for OpenGL errors; return Ok if there are none, else all of
18/// the errors as strings in a Vec
19pub fn check_errors() -> Result<(), Vec<String>> {
20    let mut v = Vec::new();
21    loop {
22        match unsafe { gl::GetError() } {
23            gl::NO_ERROR => {
24                break;
25            }
26            gl::INVALID_ENUM => {
27                v.push("Invalid enum (Gl error)".to_string());
28            }
29            gl::INVALID_VALUE => {
30                v.push("Invalid value (Gl error)".to_string());
31            }
32            gl::INVALID_OPERATION => {
33                v.push("Invalid operation (Gl error)".to_string());
34            }
35            x => {
36                v.push(format!("GL had error {x}"));
37            }
38        }
39    }
40    if v.is_empty() {
41        Ok(())
42    } else {
43        Err(v)
44    }
45}
46
47//fp get_shaderiv
48/// Get an integer value from a particular shader
49pub fn get_shaderiv(id: gl::types::GLuint, x: gl::types::GLuint) -> gl::types::GLint {
50    unsafe {
51        let mut r = 0;
52        gl::GetShaderiv(id, x, &mut r);
53        r
54    }
55}
56
57//fp get_programiv
58/// Get an integer value from a particular program
59pub fn get_programiv(id: gl::types::GLuint, x: gl::types::GLuint) -> gl::types::GLint {
60    unsafe {
61        let mut r = 0;
62        gl::GetProgramiv(id, x, &mut r);
63        r
64    }
65}
66
67//fp get_shader_error
68/// Assummes an error exists; get its length (using 'f') and then get
69/// the error (using 'e') as a String
70pub fn get_shader_error<
71    F: FnOnce(gl::types::GLuint) -> i32,
72    E: FnOnce(gl::types::GLuint, i32, *mut gl::types::GLchar),
73>(
74    id: gl::types::GLuint,
75    f: F,
76    e: E,
77) -> String {
78    let len = f(id);
79    let error = create_whitespace_cstring_with_len(len as usize);
80    e(id, len, error.as_ptr() as *mut gl::types::GLchar);
81    format!("{}", error.to_string_lossy())
82}