From 10afa74e824b727c890e9934f7728390684af8e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Mon, 4 Mar 2019 01:14:51 +0100 Subject: DRW: Fix matflag not being updated after first drawcall This Fixes T61823: Flickering material problem with eevee --- source/blender/draw/intern/draw_manager_data.c | 56 +++++++++++++++----------- 1 file changed, 33 insertions(+), 23 deletions(-) (limited to 'source') diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index 91e3befa8d6..53fbb8bb9cc 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -309,13 +309,43 @@ static void drw_call_calc_orco(Object *ob, float (*r_orcofacs)[3]) } } +static void drw_call_state_update_matflag(DRWCallState *state, DRWShadingGroup *shgroup, Object *ob) +{ + uint16_t new_flags = ((state->matflag ^ shgroup->matflag) & shgroup->matflag); + + /* HACK: Here we set the matflags bit to 1 when computing the value + * so that it's not recomputed for other drawcalls. + * This is the opposite of what draw_matrices_model_prepare() does. */ + state->matflag |= shgroup->matflag; + + /* Orco factors: We compute this at creation to not have to save the *ob_data */ + if ((new_flags & DRW_CALL_ORCOTEXFAC) != 0) { + drw_call_calc_orco(ob, state->orcotexfac); + } + + if ((new_flags & DRW_CALL_OBJECTINFO) != 0) { + state->objectinfo[0] = ob ? ob->index : 0; + uint random; +#if 0 /* TODO(fclem) handle dupli objects */ + if (GMS.dob) { + random = GMS.dob->random_id; + } + else +#endif + { + random = BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0); + } + state->objectinfo[1] = random * (1.0f / (float)0xFFFFFFFF); + } +} + static DRWCallState *drw_call_state_create(DRWShadingGroup *shgroup, float (*obmat)[4], Object *ob) { DRWCallState *state = BLI_mempool_alloc(DST.vmempool->states); state->flag = 0; state->cache_id = 0; state->visibility_cb = NULL; - state->matflag = shgroup->matflag; + state->matflag = 0; /* Matrices */ if (obmat != NULL) { @@ -343,27 +373,7 @@ static DRWCallState *drw_call_state_create(DRWShadingGroup *shgroup, float (*obm state->bsphere.radius = -1.0f; } - /* Orco factors: We compute this at creation to not have to save the *ob_data */ - if ((state->matflag & DRW_CALL_ORCOTEXFAC) != 0) { - drw_call_calc_orco(ob, state->orcotexfac); - state->matflag &= ~DRW_CALL_ORCOTEXFAC; - } - - if ((state->matflag & DRW_CALL_OBJECTINFO) != 0) { - state->objectinfo[0] = ob ? ob->index : 0; - uint random; -#if 0 /* TODO(fclem) handle dupli objects */ - if (GMS.dob) { - random = GMS.dob->random_id; - } - else -#endif - { - random = BLI_hash_int_2d(BLI_hash_string(ob->id.name + 2), 0); - } - state->objectinfo[1] = random * (1.0f / (float)0xFFFFFFFF); - state->matflag &= ~DRW_CALL_OBJECTINFO; - } + drw_call_state_update_matflag(state, shgroup, ob); return state; } @@ -375,7 +385,7 @@ static DRWCallState *drw_call_state_object(DRWShadingGroup *shgroup, float (*obm } else { /* If the DRWCallState is reused, add necessary matrices. */ - DST.ob_state->matflag |= shgroup->matflag; + drw_call_state_update_matflag(DST.ob_state, shgroup, ob); } return DST.ob_state; -- cgit v1.2.3