🚧 checkpoint

main
_ 2020-03-08 18:21:32 +00:00
parent 838226b2de
commit 7b140301c3
1 changed files with 91 additions and 49 deletions

View File

@ -256,10 +256,14 @@ pub struct GlState {
flags: HashMap <u32, bool>, flags: HashMap <u32, bool>,
front_face: Option <FrontFace>, front_face: Option <FrontFace>,
stencil: Option <StencilState>, stencil: Option <StencilState>,
color_mask: Option <(u8, u8, u8, u8)>,
depth_mask: Option <u8>,
stencil_mask: Option <u32>,
} }
pub struct Pass <'a> { pub struct Pass <'a> {
shader: &'a ShaderClosure, shader: Option <&'a ShaderClosure>,
// Anything that's None is "don't care" // Anything that's None is "don't care"
@ -279,30 +283,44 @@ impl Pass <'_> {
} }
} }
match state.front_face { if let Some (v) = &state.front_face {
Some (v) => glezz::front_face (v.into ()), glezz::front_face ((*v).into ());
_ => (),
} }
match &state.stencil { if let Some (v) = &state.stencil {
Some (v) => { let func = &v.func;
let func = &v.func; let op = &v.op;
let op = &v.op;
unsafe { unsafe {
gl::StencilFunc ( gl::StencilFunc (
func.func.into (), func.func.into (),
func.reference.into (), func.reference.into (),
func.mask.into () func.mask.into ()
); );
gl::StencilOp ( gl::StencilOp (
op.sfail.into (), op.sfail.into (),
op.dpfail.into (), op.dpfail.into (),
op.dppass.into () op.dppass.into ()
); );
} }
}, }
_ => (),
if let Some ((r, g, b, a)) = &state.color_mask {
unsafe {
gl::ColorMask (*r, *g, *b, *a);
}
}
if let Some (v) = &state.depth_mask {
unsafe {
gl::DepthMask (*v);
}
}
if let Some (v) = &state.stencil_mask {
unsafe {
gl::StencilMask (*v);
}
} }
} }
} }
@ -461,24 +479,41 @@ impl GameGraphics {
let light = Vec3::from ((0.25, -0.125, 1.0)).normalize (); let light = Vec3::from ((0.25, -0.125, 1.0)).normalize ();
glezz::clear_color (1.0f32, 0.0f32, 1.0f32, 1.0f32);
glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
let passes = vec! [ let passes = vec! [
// Clear everything
Pass { Pass {
shader: &self.shader_diffuse, shader: None,
required_state: GlState {
flags: hashmap! {},
front_face: None,
stencil: None,
color_mask: Some ((1, 1, 1, 1)),
depth_mask: Some (1),
stencil_mask: Some (255),
},
},
// Draw world
Pass {
shader: Some (&self.shader_diffuse),
required_state: GlState { required_state: GlState {
flags: hashmap! { flags: hashmap! {
gl::DEPTH_TEST => true,
gl::TEXTURE_2D => true,
gl::STENCIL_TEST => false, gl::STENCIL_TEST => false,
}, },
front_face: Some (FrontFace::Cw), front_face: Some (FrontFace::Cw),
stencil: None, stencil: None,
color_mask: Some ((1, 1, 1, 1)),
depth_mask: Some (1),
stencil_mask: Some (0),
}, },
}, },
// Write shadows into stencil buffer
Pass { Pass {
shader: &self.shader_shadow, shader: Some (&self.shader_shadow),
required_state: GlState { required_state: GlState {
flags: hashmap! { flags: hashmap! {
gl::DEPTH_TEST => true,
gl::STENCIL_TEST => true, gl::STENCIL_TEST => true,
}, },
front_face: Some (FrontFace::Ccw), front_face: Some (FrontFace::Ccw),
@ -494,12 +529,18 @@ impl GameGraphics {
dppass: StencilOp::Replace, dppass: StencilOp::Replace,
}, },
}), }),
color_mask: Some ((0, 0, 0, 0)),
depth_mask: Some (0),
stencil_mask: Some (255),
}, },
}, },
// Draw lit ground
Pass { Pass {
shader: &self.shader_shadow, shader: Some (&self.shader_diffuse),
required_state: GlState { required_state: GlState {
flags: hashmap! { flags: hashmap! {
gl::DEPTH_TEST => true,
gl::TEXTURE_2D => true,
gl::STENCIL_TEST => true, gl::STENCIL_TEST => true,
}, },
front_face: Some (FrontFace::Cw), front_face: Some (FrontFace::Cw),
@ -515,12 +556,18 @@ impl GameGraphics {
dppass: StencilOp::Keep, dppass: StencilOp::Keep,
}, },
}), }),
color_mask: Some ((1, 1, 1, 1)),
depth_mask: Some (1),
stencil_mask: Some (0),
}, },
}, },
// Draw unlit ground
Pass { Pass {
shader: &self.shader_shadow, shader: Some (&self.shader_diffuse),
required_state: GlState { required_state: GlState {
flags: hashmap! { flags: hashmap! {
gl::DEPTH_TEST => true,
gl::TEXTURE_2D => true,
gl::STENCIL_TEST => true, gl::STENCIL_TEST => true,
}, },
front_face: Some (FrontFace::Cw), front_face: Some (FrontFace::Cw),
@ -536,10 +583,17 @@ impl GameGraphics {
dppass: StencilOp::Keep, dppass: StencilOp::Keep,
}, },
}), }),
color_mask: Some ((1, 1, 1, 1)),
depth_mask: Some (1),
stencil_mask: Some (0),
}, },
}, },
]; ];
passes [0].apply_slow ();
glezz::clear_color (1.0f32, 0.0f32, 1.0f32, 1.0f32);
glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
glezz::enable (gl::CULL_FACE); glezz::enable (gl::CULL_FACE);
let pumpkin_model_mat = let pumpkin_model_mat =
@ -552,15 +606,12 @@ impl GameGraphics {
use uniforms::*; use uniforms::*;
glezz::enable (gl::DEPTH_TEST);
glezz::enable (gl::TEXTURE_2D);
self.shader_diffuse.with (|shader_vars| { self.shader_diffuse.with (|shader_vars| {
let unis = shader_vars.unis; let unis = shader_vars.unis;
let attrs = shader_vars.attrs; let attrs = shader_vars.attrs;
// Pass 0 - Draw the world except the ground plane // Pass 0 - Draw the world except the ground plane
passes [0].apply_slow (); passes [1].apply_slow ();
let mvp = view_mat * pumpkin_model_mat; let mvp = view_mat * pumpkin_model_mat;
glezz::uniform_matrix_4fv (unis [&MVP], &mvp); glezz::uniform_matrix_4fv (unis [&MVP], &mvp);
@ -619,13 +670,8 @@ impl GameGraphics {
let unis = shader_vars.unis; let unis = shader_vars.unis;
let attrs = shader_vars.attrs; let attrs = shader_vars.attrs;
// Pass 1: Draw shadows into stencil buffer // Draw shadows into stencil buffer
passes [1].apply_slow (); passes [2].apply_slow ();
unsafe {
gl::ColorMask (0, 0, 0, 0);
gl::DepthMask (0);
gl::StencilMask (1);
}
let view_mat = view_mat * shadow_mat; let view_mat = view_mat * shadow_mat;
@ -651,12 +697,8 @@ impl GameGraphics {
let unis = shader_vars.unis; let unis = shader_vars.unis;
let attrs = shader_vars.attrs; let attrs = shader_vars.attrs;
// Pass 2: Draw lit ground // Draw lit ground
passes [2].apply_slow (); passes [3].apply_slow ();
unsafe {
gl::ColorMask (255, 255, 255, 255);
gl::DepthMask (1);
}
let inverse_pumpkin = pumpkin_model_mat.inverse (); let inverse_pumpkin = pumpkin_model_mat.inverse ();
@ -676,8 +718,8 @@ impl GameGraphics {
glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &Vec3::from ((0.0, 0.0, 0.0))); glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &Vec3::from ((0.0, 0.0, 0.0)));
self.mesh_pitch.draw (attrs, self.grass_index); self.mesh_pitch.draw (attrs, self.grass_index);
// Pass 3: Draw shadowed ground // Draw shadowed ground
passes [3].apply_slow (); passes [4].apply_slow ();
glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light); glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light);
self.mesh_pitch.draw (attrs, self.grass_index); self.mesh_pitch.draw (attrs, self.grass_index);