♻️ Make it harder to access the wrong shader vars by accident

main
_ 2020-03-08 02:53:02 +00:00
parent b8e0429095
commit 61988a61ce
2 changed files with 77 additions and 25 deletions

View File

@ -1,5 +1,4 @@
use glam::{Mat4, Vec3, Vec4}; use glam::{Mat4, Vec3, Vec4};
use rand::Rng;
use sdl2::event::Event; use sdl2::event::Event;
use sdl2::keyboard::{Keycode, Scancode}; use sdl2::keyboard::{Keycode, Scancode};
@ -129,6 +128,43 @@ where P: AsRef <std::path::Path>
RenderableModel::from_iqm (&model) RenderableModel::from_iqm (&model)
} }
struct ShaderClosure {
program: ShaderProgram,
uniforms: HashMap <u32, i32>,
attributes: HashMap <String, Option <u32>>,
}
struct BorrowedShaderVars <'a> {
unis: &'a HashMap <u32, i32>,
attrs: &'a HashMap <String, Option <u32>>,
}
impl ShaderClosure {
pub fn new (
program: ShaderProgram,
uniforms: HashMap <u32, i32>,
attributes: HashMap <String, Option <u32>>
) -> Self
{
Self {
program,
uniforms,
attributes,
}
}
pub fn with <F> (&self, callback: F)
where F: Fn (BorrowedShaderVars)
{
self.program.use_program ();
callback (BorrowedShaderVars {
unis: &self.uniforms,
attrs: &self.attributes,
});
}
}
fn main () { fn main () {
let sdl_context = sdl2::init ().unwrap (); let sdl_context = sdl2::init ().unwrap ();
let video_subsystem = sdl_context.video ().unwrap (); let video_subsystem = sdl_context.video ().unwrap ();
@ -171,6 +207,18 @@ fn main () {
ShaderProgram::new (&vert_shader, &frag_shader).unwrap () ShaderProgram::new (&vert_shader, &frag_shader).unwrap ()
}; };
let attrs = shader_program.get_attribute_locations (vec! [
"pos",
"uv",
"normal",
].into_iter ());
let shadow_attrs = shadow_shader.get_attribute_locations (vec! [
"pos",
"uv",
"normal",
].into_iter ());
let uni_lookup: HashMap <_, &str> = HashMap::from_iter ({ let uni_lookup: HashMap <_, &str> = HashMap::from_iter ({
use uniforms::*; use uniforms::*;
vec! [ vec! [
@ -204,17 +252,12 @@ fn main () {
unis unis
}; };
let attrs = shader_program.get_attribute_locations (vec! [ glezz::enable_vertex_attrib_array (attrs ["pos"]);
"pos", glezz::enable_vertex_attrib_array (attrs ["uv"]);
"uv", glezz::enable_vertex_attrib_array (attrs ["normal"]);
"normal",
].into_iter ());
let shadow_attrs = shadow_shader.get_attribute_locations (vec! [ let shader_diffuse = ShaderClosure::new (shader_program, unis, attrs);
"pos", let shader_shadow = ShaderClosure::new (shadow_shader, shadow_unis, shadow_attrs);
"uv",
"normal",
].into_iter ());
let texture = Texture::from_file ("sky.png"); let texture = Texture::from_file ("sky.png");
texture.bind (); texture.bind ();
@ -275,10 +318,6 @@ fn main () {
(colors, grass_index.unwrap ()) (colors, grass_index.unwrap ())
}; };
glezz::enable_vertex_attrib_array (attrs ["pos"]);
glezz::enable_vertex_attrib_array (attrs ["uv"]);
glezz::enable_vertex_attrib_array (attrs ["normal"]);
glezz::enable (gl::DEPTH_TEST); glezz::enable (gl::DEPTH_TEST);
glezz::enable (gl::TEXTURE_2D); glezz::enable (gl::TEXTURE_2D);
@ -343,10 +382,12 @@ fn main () {
let world_model_mat = Mat4::identity (); let world_model_mat = Mat4::identity ();
{
use uniforms::*; use uniforms::*;
shader_program.use_program (); shader_diffuse.with (|shader_vars| {
let unis = shader_vars.unis;
let attrs = shader_vars.attrs;
glezz::disable (gl::STENCIL_TEST); glezz::disable (gl::STENCIL_TEST);
glezz::front_face (gl::CW); glezz::front_face (gl::CW);
@ -398,25 +439,34 @@ fn main () {
gl::DepthMask (0); gl::DepthMask (0);
gl::StencilMask (1); gl::StencilMask (1);
} }
shadow_shader.use_program (); });
shader_shadow.with (|shader_vars| {
let unis = shader_vars.unis;
let attrs = shader_vars.attrs;
let view_mat = view_mat * shadow_mat; let view_mat = view_mat * shadow_mat;
let mvp = view_mat * pumpkin_model_mat; let mvp = view_mat * pumpkin_model_mat;
glezz::uniform_matrix_4fv (shadow_unis [&MVP], &mvp); glezz::uniform_matrix_4fv (unis [&MVP], &mvp);
mesh_pumpkin.draw_all (&shadow_attrs, |_| true); mesh_pumpkin.draw_all (&attrs, |_| true);
let mvp = view_mat * world_model_mat; let mvp = view_mat * world_model_mat;
glezz::uniform_matrix_4fv (shadow_unis [&MVP], &mvp); glezz::uniform_matrix_4fv (unis [&MVP], &mvp);
mesh_pitch.draw_all (&shadow_attrs, |i| i != grass_index); mesh_pitch.draw_all (&attrs, |i| i != grass_index);
unsafe { unsafe {
gl::ColorMask (255, 255, 255, 255); gl::ColorMask (255, 255, 255, 255);
gl::DepthMask (1); gl::DepthMask (1);
} }
shader_program.use_program (); });
shader_diffuse.with (|shader_vars| {
let unis = shader_vars.unis;
let attrs = shader_vars.attrs;
glezz::front_face (gl::CW); glezz::front_face (gl::CW);
let inverse_pumpkin = pumpkin_model_mat.inverse (); let inverse_pumpkin = pumpkin_model_mat.inverse ();
@ -447,7 +497,7 @@ fn main () {
} }
glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light); glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light);
mesh_pitch.draw (&attrs, grass_index); mesh_pitch.draw (&attrs, grass_index);
} });
window.gl_swap_window (); window.gl_swap_window ();

View File

@ -119,6 +119,8 @@ impl ShaderProgram {
} }
} }
// 'use' is a keyword
pub fn use_program (&self) { pub fn use_program (&self) {
unsafe { unsafe {
gl::UseProgram (self.id); gl::UseProgram (self.id);