bracket_terminal/hal/gl_common/
shader.rs

1use super::{gl_error, ShaderId};
2use crate::console::log;
3use glow::HasContext;
4use std::str;
5use ultraviolet::Vec3;
6
7#[allow(non_snake_case)]
8pub struct Shader {
9    pub ID: ShaderId,
10}
11
12/// NOTE: mixture of `shader_s.h` and `shader_m.h` (the latter just contains
13/// a few more setters for uniforms)
14impl Shader {
15    pub fn new(gl: &glow::Context, vertex_code: &str, fragment_code: &str) -> Shader {
16        // 1. compile shaders from strings
17        let shader;
18        unsafe {
19            // vertex shader
20            let vertex = gl.create_shader(glow::VERTEX_SHADER).unwrap();
21            gl.shader_source(vertex, vertex_code);
22            gl.compile_shader(vertex);
23            if !gl.get_shader_compile_status(vertex) {
24                log(&vertex_code);
25                log(&gl.get_shader_info_log(vertex));
26                panic!();
27            }
28
29            // fragment Shader
30            let fragment = gl.create_shader(glow::FRAGMENT_SHADER).unwrap();
31            gl.shader_source(fragment, fragment_code);
32            gl.compile_shader(fragment);
33            if !gl.get_shader_compile_status(fragment) {
34                log(&fragment_code);
35                log(&gl.get_shader_info_log(fragment));
36                panic!();
37            }
38
39            // shader Program
40            let id = gl.create_program().unwrap();
41            gl.attach_shader(id, vertex);
42            gl.attach_shader(id, fragment);
43            gl.link_program(id);
44            if !gl.get_program_link_status(id) {
45                log(&gl.get_program_info_log(id));
46                panic!();
47            }
48
49            // delete the shaders as they're linked into our program now and no longer necessary
50            shader = Shader { ID: id }
51        }
52
53        //log("Shaders Compiled");
54
55        shader
56    }
57
58    #[allow(non_snake_case)]
59    #[allow(clippy::missing_safety_doc)]
60    /// activate the shader
61    /// ------------------------------------------------------------------------
62    pub unsafe fn useProgram(&self, gl: &glow::Context) {
63        gl.use_program(Some(self.ID));
64        gl_error(gl);
65    }
66
67    #[allow(non_snake_case)]
68    #[allow(clippy::missing_safety_doc)]
69    /// utility uniform functions
70    /// ------------------------------------------------------------------------
71    pub unsafe fn setBool(&self, gl: &glow::Context, name: &str, value: bool) {
72        gl.uniform_1_i32(
73            gl.get_uniform_location(self.ID, name).as_ref(),
74            value as i32,
75        );
76    }
77
78    #[allow(non_snake_case)]
79    #[allow(clippy::missing_safety_doc)]
80    /// ------------------------------------------------------------------------
81    pub unsafe fn setInt(&self, gl: &glow::Context, name: &str, value: i32) {
82        gl.uniform_1_i32(gl.get_uniform_location(self.ID, name).as_ref(), value);
83    }
84
85    #[allow(non_snake_case)]
86    #[allow(clippy::missing_safety_doc)]
87    /// ------------------------------------------------------------------------
88    pub unsafe fn setFloat(&self, gl: &glow::Context, name: &str, value: f32) {
89        gl.uniform_1_f32(gl.get_uniform_location(self.ID, name).as_ref(), value);
90    }
91
92    #[allow(non_snake_case)]
93    #[allow(clippy::missing_safety_doc)]
94    /// ------------------------------------------------------------------------
95    pub unsafe fn setVector3(&self, gl: &glow::Context, name: &str, value: &Vec3) {
96        gl.uniform_3_f32(
97            gl.get_uniform_location(self.ID, name).as_ref(),
98            value.x,
99            value.y,
100            value.z,
101        );
102    }
103
104    #[allow(non_snake_case)]
105    #[allow(clippy::missing_safety_doc)]
106    /// ------------------------------------------------------------------------
107    pub unsafe fn setVec3(&self, gl: &glow::Context, name: &str, x: f32, y: f32, z: f32) {
108        gl.uniform_3_f32(gl.get_uniform_location(self.ID, name).as_ref(), x, y, z);
109    }
110
111    #[allow(non_snake_case)]
112    #[allow(clippy::missing_safety_doc)]
113    /// ------------------------------------------------------------------------
114    pub unsafe fn setVec2(&self, gl: &glow::Context, name: &str, x: f32, y: f32) {
115        gl.uniform_2_f32(gl.get_uniform_location(self.ID, name).as_ref(), x, y);
116    }
117
118    #[allow(non_snake_case)]
119    #[allow(clippy::missing_safety_doc)]
120    /// ------------------------------------------------------------------------
121    pub unsafe fn setMat4(&self, gl: &glow::Context, name: &str, mat: &[f32; 16]) {
122        gl.uniform_matrix_4_f32_slice(gl.get_uniform_location(self.ID, name).as_ref(), false, mat);
123    }
124}