🚧 Work on pass manager idea
parent
1a42b60f71
commit
838226b2de
|
@ -134,6 +134,11 @@ dependencies = [
|
|||
"cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "maplit"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.2.1"
|
||||
|
@ -199,6 +204,7 @@ dependencies = [
|
|||
"gl 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"glam 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"iota 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"nom 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"png 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -423,6 +429,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum lexical-core 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2304bccb228c4b020f3a4835d247df0a02a7c4686098d4167762cfbbe4c5cb14"
|
||||
"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
|
||||
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
|
||||
"checksum maplit 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d"
|
||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||
"checksum nodrop 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb"
|
||||
"checksum nom 5.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c433f4d505fe6ce7ff78523d2fa13a0b9f2690e181fc26168bcbe5ccc5d14e07"
|
||||
|
|
|
@ -15,6 +15,7 @@ glam = "0.8.5"
|
|||
|
||||
iota = "0.2.1"
|
||||
|
||||
maplit = "1.0.2"
|
||||
# TODO: Drop nom depend. It's way overkill for iqm.
|
||||
nom = "5.1.0"
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#[macro_use]
|
||||
extern crate maplit;
|
||||
|
||||
use glam::{Mat4, Vec3, Vec4};
|
||||
|
||||
use sdl2::event::Event;
|
||||
|
@ -149,6 +152,161 @@ struct RenderableArrow {
|
|||
inv_model_mat: Mat4,
|
||||
}
|
||||
|
||||
#[derive (Copy, Clone)]
|
||||
pub enum FrontFace {
|
||||
Cw,
|
||||
Ccw,
|
||||
}
|
||||
|
||||
impl From <FrontFace> for u32 {
|
||||
fn from (v: FrontFace) -> Self {
|
||||
use FrontFace::*;
|
||||
{
|
||||
use gl::*;
|
||||
match v {
|
||||
Cw => CW,
|
||||
Ccw => CCW,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive (Copy, Clone)]
|
||||
pub enum StencilOp {
|
||||
Keep,
|
||||
Zero,
|
||||
Replace,
|
||||
Incr,
|
||||
Decr,
|
||||
Invert,
|
||||
IncrWrap,
|
||||
DecrWrap,
|
||||
}
|
||||
|
||||
impl From <StencilOp> for u32 {
|
||||
fn from (v: StencilOp) -> Self {
|
||||
use StencilOp::*;
|
||||
{
|
||||
use gl::*;
|
||||
match v {
|
||||
Keep => KEEP,
|
||||
Zero => ZERO,
|
||||
Replace => REPLACE,
|
||||
Incr => INCR,
|
||||
Decr => DECR,
|
||||
Invert => INVERT,
|
||||
IncrWrap => INCR_WRAP,
|
||||
DecrWrap => DECR_WRAP,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive (Copy, Clone)]
|
||||
pub enum StencilFunc {
|
||||
Never,
|
||||
Always,
|
||||
Less,
|
||||
LessEqual,
|
||||
Equal,
|
||||
Greater,
|
||||
GreaterEqual,
|
||||
NotEqual,
|
||||
}
|
||||
|
||||
impl From <StencilFunc> for u32 {
|
||||
fn from (v: StencilFunc) -> Self {
|
||||
use StencilFunc::*;
|
||||
{
|
||||
use gl::*;
|
||||
match v {
|
||||
Never => NEVER,
|
||||
Always => ALWAYS,
|
||||
Less => LESS,
|
||||
LessEqual => LEQUAL,
|
||||
Equal => EQUAL,
|
||||
Greater => GREATER,
|
||||
GreaterEqual => GEQUAL,
|
||||
NotEqual => NOTEQUAL,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StencilOpState {
|
||||
sfail: StencilOp,
|
||||
dpfail: StencilOp,
|
||||
dppass: StencilOp,
|
||||
}
|
||||
|
||||
pub struct StencilFuncState {
|
||||
func: StencilFunc,
|
||||
reference: i32,
|
||||
mask: u32,
|
||||
}
|
||||
|
||||
pub struct StencilState {
|
||||
op: StencilOpState,
|
||||
func: StencilFuncState,
|
||||
}
|
||||
|
||||
// Anything that's None is "unknown"
|
||||
|
||||
pub struct GlState {
|
||||
flags: HashMap <u32, bool>,
|
||||
front_face: Option <FrontFace>,
|
||||
stencil: Option <StencilState>,
|
||||
}
|
||||
|
||||
pub struct Pass <'a> {
|
||||
shader: &'a ShaderClosure,
|
||||
|
||||
// Anything that's None is "don't care"
|
||||
|
||||
required_state: GlState,
|
||||
}
|
||||
|
||||
impl Pass <'_> {
|
||||
pub fn apply_slow (&self) {
|
||||
let state = &self.required_state;
|
||||
|
||||
for (flag, value) in state.flags.iter () {
|
||||
if *value {
|
||||
glezz::enable (*flag);
|
||||
}
|
||||
else {
|
||||
glezz::disable (*flag);
|
||||
}
|
||||
}
|
||||
|
||||
match state.front_face {
|
||||
Some (v) => glezz::front_face (v.into ()),
|
||||
_ => (),
|
||||
}
|
||||
|
||||
match &state.stencil {
|
||||
Some (v) => {
|
||||
let func = &v.func;
|
||||
let op = &v.op;
|
||||
|
||||
unsafe {
|
||||
gl::StencilFunc (
|
||||
func.func.into (),
|
||||
func.reference.into (),
|
||||
func.mask.into ()
|
||||
);
|
||||
gl::StencilOp (
|
||||
op.sfail.into (),
|
||||
op.dpfail.into (),
|
||||
op.dppass.into ()
|
||||
);
|
||||
}
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct GameGraphics {
|
||||
shader_diffuse: ShaderClosure,
|
||||
shader_shadow: ShaderClosure,
|
||||
|
@ -305,6 +463,83 @@ impl GameGraphics {
|
|||
|
||||
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! [
|
||||
Pass {
|
||||
shader: &self.shader_diffuse,
|
||||
required_state: GlState {
|
||||
flags: hashmap! {
|
||||
gl::STENCIL_TEST => false,
|
||||
},
|
||||
front_face: Some (FrontFace::Cw),
|
||||
stencil: None,
|
||||
},
|
||||
},
|
||||
Pass {
|
||||
shader: &self.shader_shadow,
|
||||
required_state: GlState {
|
||||
flags: hashmap! {
|
||||
gl::STENCIL_TEST => true,
|
||||
},
|
||||
front_face: Some (FrontFace::Ccw),
|
||||
stencil: Some (StencilState {
|
||||
func: StencilFuncState {
|
||||
func: StencilFunc::Always,
|
||||
reference: 1,
|
||||
mask: 1,
|
||||
},
|
||||
op: StencilOpState {
|
||||
sfail: StencilOp::Keep,
|
||||
dpfail: StencilOp::Keep,
|
||||
dppass: StencilOp::Replace,
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
Pass {
|
||||
shader: &self.shader_shadow,
|
||||
required_state: GlState {
|
||||
flags: hashmap! {
|
||||
gl::STENCIL_TEST => true,
|
||||
},
|
||||
front_face: Some (FrontFace::Cw),
|
||||
stencil: Some (StencilState {
|
||||
func: StencilFuncState {
|
||||
func: StencilFunc::NotEqual,
|
||||
reference: 0,
|
||||
mask: 1,
|
||||
},
|
||||
op: StencilOpState {
|
||||
sfail: StencilOp::Keep,
|
||||
dpfail: StencilOp::Keep,
|
||||
dppass: StencilOp::Keep,
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
Pass {
|
||||
shader: &self.shader_shadow,
|
||||
required_state: GlState {
|
||||
flags: hashmap! {
|
||||
gl::STENCIL_TEST => true,
|
||||
},
|
||||
front_face: Some (FrontFace::Cw),
|
||||
stencil: Some (StencilState {
|
||||
func: StencilFuncState {
|
||||
func: StencilFunc::Equal,
|
||||
reference: 0,
|
||||
mask: 1,
|
||||
},
|
||||
op: StencilOpState {
|
||||
sfail: StencilOp::Keep,
|
||||
dpfail: StencilOp::Keep,
|
||||
dppass: StencilOp::Keep,
|
||||
},
|
||||
}),
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
glezz::enable (gl::CULL_FACE);
|
||||
|
||||
let pumpkin_model_mat =
|
||||
|
@ -324,9 +559,8 @@ impl GameGraphics {
|
|||
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);
|
||||
// Pass 0 - Draw the world except the ground plane
|
||||
passes [0].apply_slow ();
|
||||
|
||||
let mvp = view_mat * pumpkin_model_mat;
|
||||
glezz::uniform_matrix_4fv (unis [&MVP], &mvp);
|
||||
|
@ -385,13 +619,9 @@ impl GameGraphics {
|
|||
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);
|
||||
// Pass 1: Draw shadows into stencil buffer
|
||||
passes [1].apply_slow ();
|
||||
unsafe {
|
||||
gl::StencilFunc (gl::ALWAYS, 1, 1);
|
||||
gl::StencilOp (gl::KEEP, gl::KEEP, gl::REPLACE);
|
||||
|
||||
gl::ColorMask (0, 0, 0, 0);
|
||||
gl::DepthMask (0);
|
||||
gl::StencilMask (1);
|
||||
|
@ -421,16 +651,13 @@ impl GameGraphics {
|
|||
let unis = shader_vars.unis;
|
||||
let attrs = shader_vars.attrs;
|
||||
|
||||
// Pass 3: Draw lit ground
|
||||
// Pass 2: Draw lit ground
|
||||
passes [2].apply_slow ();
|
||||
unsafe {
|
||||
gl::ColorMask (255, 255, 255, 255);
|
||||
gl::DepthMask (1);
|
||||
gl::StencilFunc (gl::NOTEQUAL, 0, 1);
|
||||
gl::StencilOp (gl::KEEP, gl::KEEP, gl::KEEP);
|
||||
}
|
||||
|
||||
glezz::front_face (gl::CW);
|
||||
|
||||
let inverse_pumpkin = pumpkin_model_mat.inverse ();
|
||||
|
||||
let object_space_light = make_object_space_vec (&inverse_pumpkin, &light);
|
||||
|
@ -449,11 +676,9 @@ impl GameGraphics {
|
|||
glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &Vec3::from ((0.0, 0.0, 0.0)));
|
||||
self.mesh_pitch.draw (attrs, self.grass_index);
|
||||
|
||||
// Pass 4: Draw shadowed ground
|
||||
unsafe {
|
||||
gl::StencilFunc (gl::EQUAL, 0, 1);
|
||||
gl::StencilOp (gl::KEEP, gl::KEEP, gl::KEEP);
|
||||
}
|
||||
// Pass 3: Draw shadowed ground
|
||||
passes [3].apply_slow ();
|
||||
|
||||
glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light);
|
||||
self.mesh_pitch.draw (attrs, self.grass_index);
|
||||
});
|
||||
|
@ -574,7 +799,11 @@ mod tests {
|
|||
use super::*;
|
||||
|
||||
#[test]
|
||||
pub fn iqm () {
|
||||
pub fn sizes () {
|
||||
use std::mem;
|
||||
|
||||
assert_eq! (8, mem::size_of::<Option <u32>>());
|
||||
assert_eq! (1, mem::size_of::<FrontFace>());
|
||||
assert_eq! (1, mem::size_of::<Option <FrontFace>>());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue