🚧 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)",
|
"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]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.2.1"
|
version = "2.2.1"
|
||||||
|
@ -199,6 +204,7 @@ dependencies = [
|
||||||
"gl 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"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)",
|
"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 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 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 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 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 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"
|
"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"
|
iota = "0.2.1"
|
||||||
|
|
||||||
|
maplit = "1.0.2"
|
||||||
# TODO: Drop nom depend. It's way overkill for iqm.
|
# TODO: Drop nom depend. It's way overkill for iqm.
|
||||||
nom = "5.1.0"
|
nom = "5.1.0"
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#[macro_use]
|
||||||
|
extern crate maplit;
|
||||||
|
|
||||||
use glam::{Mat4, Vec3, Vec4};
|
use glam::{Mat4, Vec3, Vec4};
|
||||||
|
|
||||||
use sdl2::event::Event;
|
use sdl2::event::Event;
|
||||||
|
@ -149,6 +152,161 @@ struct RenderableArrow {
|
||||||
inv_model_mat: Mat4,
|
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 {
|
struct GameGraphics {
|
||||||
shader_diffuse: ShaderClosure,
|
shader_diffuse: ShaderClosure,
|
||||||
shader_shadow: ShaderClosure,
|
shader_shadow: ShaderClosure,
|
||||||
|
@ -305,6 +463,83 @@ impl GameGraphics {
|
||||||
|
|
||||||
glezz::clear_color (1.0f32, 0.0f32, 1.0f32, 1.0f32);
|
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::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);
|
glezz::enable (gl::CULL_FACE);
|
||||||
|
|
||||||
let pumpkin_model_mat =
|
let pumpkin_model_mat =
|
||||||
|
@ -324,9 +559,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 the world except the ground plane
|
// Pass 0 - Draw the world except the ground plane
|
||||||
glezz::disable (gl::STENCIL_TEST);
|
passes [0].apply_slow ();
|
||||||
glezz::front_face (gl::CW);
|
|
||||||
|
|
||||||
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);
|
||||||
|
@ -385,13 +619,9 @@ 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 shadows into stencil buffer
|
// Pass 1: Draw shadows into stencil buffer
|
||||||
glezz::front_face (gl::CCW);
|
passes [1].apply_slow ();
|
||||||
glezz::enable (gl::STENCIL_TEST);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::StencilFunc (gl::ALWAYS, 1, 1);
|
|
||||||
gl::StencilOp (gl::KEEP, gl::KEEP, gl::REPLACE);
|
|
||||||
|
|
||||||
gl::ColorMask (0, 0, 0, 0);
|
gl::ColorMask (0, 0, 0, 0);
|
||||||
gl::DepthMask (0);
|
gl::DepthMask (0);
|
||||||
gl::StencilMask (1);
|
gl::StencilMask (1);
|
||||||
|
@ -421,16 +651,13 @@ impl GameGraphics {
|
||||||
let unis = shader_vars.unis;
|
let unis = shader_vars.unis;
|
||||||
let attrs = shader_vars.attrs;
|
let attrs = shader_vars.attrs;
|
||||||
|
|
||||||
// Pass 3: Draw lit ground
|
// Pass 2: Draw lit ground
|
||||||
|
passes [2].apply_slow ();
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::ColorMask (255, 255, 255, 255);
|
gl::ColorMask (255, 255, 255, 255);
|
||||||
gl::DepthMask (1);
|
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 inverse_pumpkin = pumpkin_model_mat.inverse ();
|
||||||
|
|
||||||
let object_space_light = make_object_space_vec (&inverse_pumpkin, &light);
|
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)));
|
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 4: Draw shadowed ground
|
// Pass 3: Draw shadowed ground
|
||||||
unsafe {
|
passes [3].apply_slow ();
|
||||||
gl::StencilFunc (gl::EQUAL, 0, 1);
|
|
||||||
gl::StencilOp (gl::KEEP, gl::KEEP, gl::KEEP);
|
|
||||||
}
|
|
||||||
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);
|
||||||
});
|
});
|
||||||
|
@ -574,7 +799,11 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[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