81 lines
1.5 KiB
Rust
81 lines
1.5 KiB
Rust
use std::collections::*;
|
|
use std::iter::FromIterator;
|
|
|
|
use crate::{
|
|
renderable_model::AttrMap,
|
|
shader::ShaderProgram,
|
|
};
|
|
|
|
pub struct ShaderClosure {
|
|
program: ShaderProgram,
|
|
uniforms: HashMap <u32, i32>,
|
|
attributes: AttrMap,
|
|
}
|
|
|
|
pub struct BorrowedShaderVars <'a> {
|
|
pub unis: &'a HashMap <u32, i32>,
|
|
pub attrs: &'a AttrMap,
|
|
}
|
|
|
|
pub fn get_shader_attrs (
|
|
shader: &ShaderProgram,
|
|
attr_names: &[(usize, &str)]
|
|
)
|
|
-> AttrMap
|
|
{
|
|
let mut v = vec! [None; attr_names.iter ().map (|(i, _)| i).max ().unwrap () + 1];
|
|
|
|
let attrs = shader.get_attribute_locations (attr_names.iter ().map (|(_, v)| v).copied ());
|
|
|
|
for ((i, _), loc) in attr_names.iter ().zip (attrs.into_iter ()) {
|
|
v [*i] = loc;
|
|
}
|
|
|
|
v
|
|
}
|
|
|
|
pub fn get_shader_uniforms (
|
|
shader: &ShaderProgram,
|
|
uni_names: &[(u32, &str)]
|
|
)
|
|
-> HashMap <u32, i32>
|
|
{
|
|
let unis = shader.get_uniform_locations (uni_names.iter ().map (|(_, v)| v).copied ());
|
|
|
|
let pairs =
|
|
uni_names.iter ().map (|(i, _)| i).copied ()
|
|
.zip (unis.into_iter ())
|
|
.filter (|(_, v)| *v >= 0)
|
|
;
|
|
|
|
HashMap::from_iter (pairs)
|
|
}
|
|
|
|
impl ShaderClosure {
|
|
pub fn new (
|
|
program: ShaderProgram,
|
|
uniform_names: &[(u32, &str)],
|
|
attr_names: &[(usize, &str)]
|
|
) -> Self
|
|
{
|
|
let uniforms = get_shader_uniforms (&program, uniform_names);
|
|
let attributes = get_shader_attrs (&program, attr_names);
|
|
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,
|
|
});
|
|
}
|
|
}
|