Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2019-06-17 16:18:21 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-06-17 17:13:28 +0300
commit80fb263aa9ecca5f4483504c1c64e6c4f55ed041 (patch)
tree39652b5fc6576ad5002b5fa4ff2692ef178b7b92 /source/blender/draw/intern/draw_manager_exec.c
parent6ae2de026622e8e77d5d9682160c6347e0b65b59 (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.c107
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);