diff --git a/arrow.iqm b/arrow.iqm new file mode 100644 index 0000000..c31f89f Binary files /dev/null and b/arrow.iqm differ diff --git a/pitch.iqm b/pitch.iqm new file mode 100644 index 0000000..f4165b5 Binary files /dev/null and b/pitch.iqm differ diff --git a/shaders/shadow-vert.glsl b/shaders/shadow-vert.glsl index 57ca830..1b2afc5 100644 --- a/shaders/shadow-vert.glsl +++ b/shaders/shadow-vert.glsl @@ -7,7 +7,7 @@ uniform highp mat4 uni_mvp; attribute highp vec4 attr_pos; void main (void) { - highp float depth_adjust = -1.0 / 512.0; + highp float depth_adjust = -0.0 / 512.0; gl_Position = uni_mvp * attr_pos + vec4 (0.0, 0.0, depth_adjust, 0.0); } diff --git a/sky-sphere.iqm b/sky-sphere.iqm index ad21d46..89db1b8 100644 Binary files a/sky-sphere.iqm and b/sky-sphere.iqm differ diff --git a/src/bin/pumpkin.rs b/src/bin/pumpkin.rs index 4dc8fd2..601cb22 100644 --- a/src/bin/pumpkin.rs +++ b/src/bin/pumpkin.rs @@ -13,6 +13,7 @@ use file::load_small_file; use iqm::Model; use renderable_model::RenderableModel; use shader::{ShaderProgram, ShaderObject}; +use shader_closure::*; use texture::Texture; use timestep::TimeStep; @@ -138,79 +139,6 @@ where P: AsRef ShaderProgram::new (&vert_shader, &frag_shader).unwrap () } -struct ShaderClosure { - program: ShaderProgram, - uniforms: HashMap , - attributes: renderable_model::AttrMap, -} - -struct BorrowedShaderVars <'a> { - unis: &'a HashMap , - attrs: &'a renderable_model::AttrMap, -} - -fn get_shader_attrs ( - shader: &ShaderProgram, - attr_names: &[(usize, &str)] -) --> renderable_model::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 -} - -fn get_shader_uniforms ( - shader: &ShaderProgram, - uni_names: &[(u32, &str)] -) --> HashMap -{ - 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 (&self, callback: F) - where F: Fn (BorrowedShaderVars) - { - self.program.use_program (); - - callback (BorrowedShaderVars { - unis: &self.uniforms, - attrs: &self.attributes, - }); - } -} - struct Arrow { origin: Vec3, direction: Vec3, @@ -456,6 +384,7 @@ fn main () { let unis = shader_vars.unis; let attrs = shader_vars.attrs; + // Pass 1 - Draw the world except the ground plane glezz::disable (gl::STENCIL_TEST); glezz::front_face (gl::CW); @@ -501,7 +430,6 @@ fn main () { let draw_sky = true; if draw_sky { - glezz::front_face (gl::CCW); glezz::uniform_matrix_4fv (unis [&MVP], &sky_mvp_mat); glezz::uniform_3fv (unis [&ALBEDO], &white); glezz::uniform_3fv (unis [&MIN_BRIGHT], &white); @@ -516,6 +444,8 @@ fn main () { let unis = shader_vars.unis; let attrs = shader_vars.attrs; + // Pass 2: Draw shadows into stencil buffer + glezz::front_face (gl::CCW); glezz::enable (gl::STENCIL_TEST); unsafe { gl::StencilFunc (gl::ALWAYS, 1, 1); @@ -550,6 +480,7 @@ fn main () { let unis = shader_vars.unis; let attrs = shader_vars.attrs; + // Pass 3: Draw lit ground unsafe { gl::ColorMask (255, 255, 255, 255); gl::DepthMask (1); @@ -577,6 +508,7 @@ fn main () { glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &Vec3::from ((0.0, 0.0, 0.0))); mesh_pitch.draw (attrs, grass_index); + // Pass 4: Draw shadowed ground unsafe { gl::StencilFunc (gl::EQUAL, 0, 1); gl::StencilOp (gl::KEEP, gl::KEEP, gl::KEEP); diff --git a/src/lib.rs b/src/lib.rs index 599aa0f..f9b9cdd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,5 +7,6 @@ pub mod gpu_buffers; pub mod iqm; pub mod renderable_model; pub mod shader; +pub mod shader_closure; pub mod texture; pub mod timestep; diff --git a/src/renderable_model.rs b/src/renderable_model.rs index bea63a3..316add7 100644 --- a/src/renderable_model.rs +++ b/src/renderable_model.rs @@ -1,6 +1,5 @@ use byteorder::{ByteOrder, LittleEndian}; -use std::collections::*; use std::convert::TryInto; use std::ffi::c_void; diff --git a/src/shader.rs b/src/shader.rs index a90ea2c..7ebe715 100644 --- a/src/shader.rs +++ b/src/shader.rs @@ -1,4 +1,3 @@ -use std::collections::*; use std::convert::TryInto; use std::ffi::{CStr, CString}; @@ -73,6 +72,7 @@ impl Drop for ShaderObject { } } +#[derive (PartialEq, Eq)] pub struct ShaderProgram { id: u32, } diff --git a/src/shader_closure.rs b/src/shader_closure.rs new file mode 100644 index 0000000..47c24dd --- /dev/null +++ b/src/shader_closure.rs @@ -0,0 +1,80 @@ +use std::collections::*; +use std::iter::FromIterator; + +use crate::{ + renderable_model::AttrMap, + shader::ShaderProgram, +}; + +pub struct ShaderClosure { + program: ShaderProgram, + uniforms: HashMap , + attributes: AttrMap, +} + +pub struct BorrowedShaderVars <'a> { + pub unis: &'a HashMap , + 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 +{ + 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 (&self, callback: F) + where F: Fn (BorrowedShaderVars) + { + self.program.use_program (); + + callback (BorrowedShaderVars { + unis: &self.uniforms, + attrs: &self.attributes, + }); + } +}