diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-06-17 16:18:21 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-06-17 17:13:28 +0300 |
commit | 80fb263aa9ecca5f4483504c1c64e6c4f55ed041 (patch) | |
tree | 39652b5fc6576ad5002b5fa4ff2692ef178b7b92 /source/blender/draw/intern/draw_manager_exec.c | |
parent | 6ae2de026622e8e77d5d9682160c6347e0b65b59 (diff) |
DRW: Make stencil state clearer and distinct
Write and test states are now separate and need to be explicit.
Also add asserts when trying to write without test enabled.
Diffstat (limited to 'source/blender/draw/intern/draw_manager_exec.c')
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 107 |
1 files changed, 57 insertions, 50 deletions
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 85490e2f81d..2596570c022 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -79,6 +79,34 @@ void drw_state_set(DRWState state) } } + /* Stencil Write */ + { + DRWState test; + if (CHANGED_ANY_STORE_VAR(DRW_STATE_WRITE_STENCIL_ENABLED, test)) { + /* Stencil Write */ + if (test) { + glStencilMask(0xFF); + if (test & DRW_STATE_WRITE_STENCIL) { + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + } + else if (test & DRW_STATE_WRITE_STENCIL_SHADOW_PASS) { + glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP); + glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP); + } + else if (test & DRW_STATE_WRITE_STENCIL_SHADOW_FAIL) { + glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP); + glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP); + } + else { + BLI_assert(0); + } + } + else { + glStencilMask(0x00); + } + } + } + /* Color Write */ { int test; @@ -130,10 +158,7 @@ void drw_state_set(DRWState state) /* Depth Test */ { DRWState test; - if (CHANGED_ANY_STORE_VAR(DRW_STATE_DEPTH_LESS | DRW_STATE_DEPTH_LESS_EQUAL | - DRW_STATE_DEPTH_EQUAL | DRW_STATE_DEPTH_GREATER | - DRW_STATE_DEPTH_GREATER_EQUAL | DRW_STATE_DEPTH_ALWAYS, - test)) { + if (CHANGED_ANY_STORE_VAR(DRW_STATE_DEPTH_TEST_ENABLED, test)) { if (test) { glEnable(GL_DEPTH_TEST); @@ -165,6 +190,20 @@ void drw_state_set(DRWState state) } } + /* Stencil Test */ + { + int test; + if (CHANGED_ANY_STORE_VAR(DRW_STATE_STENCIL_TEST_ENABLED, test)) { + DST.stencil_mask = STENCIL_UNDEFINED; + if (test) { + glEnable(GL_STENCIL_TEST); + } + else { + glDisable(GL_STENCIL_TEST); + } + } + } + /* Wire Width */ { int test; @@ -264,49 +303,6 @@ void drw_state_set(DRWState state) } } - /* Stencil */ - { - DRWState test; - if (CHANGED_ANY_STORE_VAR(DRW_STATE_WRITE_STENCIL | DRW_STATE_WRITE_STENCIL_SHADOW_PASS | - DRW_STATE_WRITE_STENCIL_SHADOW_FAIL | DRW_STATE_STENCIL_EQUAL | - DRW_STATE_STENCIL_NEQUAL, - test)) { - if (test) { - glEnable(GL_STENCIL_TEST); - /* Stencil Write */ - if ((state & DRW_STATE_WRITE_STENCIL) != 0) { - glStencilMask(0xFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - } - else if ((state & DRW_STATE_WRITE_STENCIL_SHADOW_PASS) != 0) { - glStencilMask(0xFF); - glStencilOpSeparate(GL_BACK, GL_KEEP, GL_KEEP, GL_INCR_WRAP); - glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_KEEP, GL_DECR_WRAP); - } - else if ((state & DRW_STATE_WRITE_STENCIL_SHADOW_FAIL) != 0) { - glStencilMask(0xFF); - glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR_WRAP, GL_KEEP); - glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR_WRAP, GL_KEEP); - } - /* Stencil Test */ - else if ((state & (DRW_STATE_STENCIL_EQUAL | DRW_STATE_STENCIL_NEQUAL)) != 0) { - glStencilMask(0x00); /* disable write */ - DST.stencil_mask = STENCIL_UNDEFINED; - } - else { - BLI_assert(0); - } - } - else { - /* disable write & test */ - DST.stencil_mask = 0; - glStencilMask(0x00); - glStencilFunc(GL_ALWAYS, 0, 0xFF); - glDisable(GL_STENCIL_TEST); - } - } - } - /* Provoking Vertex */ { int test; @@ -331,11 +327,9 @@ static void drw_stencil_set(uint mask) { if (DST.stencil_mask != mask) { DST.stencil_mask = mask; - /* Stencil Write */ - if ((DST.state & DRW_STATE_WRITE_STENCIL) != 0) { + if ((DST.state & DRW_STATE_STENCIL_ALWAYS) != 0) { glStencilFunc(GL_ALWAYS, mask, 0xFF); } - /* Stencil Test */ else if ((DST.state & DRW_STATE_STENCIL_EQUAL) != 0) { glStencilFunc(GL_EQUAL, mask, 0xFF); } @@ -352,6 +346,18 @@ void DRW_state_reset_ex(DRWState state) drw_state_set(state); } +static void drw_state_validate(void) +{ + /* Cannot write to stencil buffer without stencil test. */ + if ((DST.state & DRW_STATE_WRITE_STENCIL_ENABLED)) { + BLI_assert(DST.state & DRW_STATE_STENCIL_TEST_ENABLED); + } + /* Cannot write to depth buffer without depth test. */ + if ((DST.state & DRW_STATE_WRITE_DEPTH)) { + BLI_assert(DST.state & DRW_STATE_DEPTH_TEST_ENABLED); + } +} + /** * Use with care, intended so selection code can override passes depth settings, * which is important for selection to work properly. @@ -980,6 +986,7 @@ static void drw_draw_pass_ex(DRWPass *pass, drw_state_set(DST.state | DRW_STATE_WRITE_DEPTH | DRW_STATE_WRITE_COLOR); drw_state_set(pass->state); + drw_state_validate(); DRW_stats_query_start(pass->name); |