DRW: Fix matflag not being updated after first drawcall

This Fixes T61823: Flickering material problem with eevee
This commit is contained in:
Clément Foucault 2019-03-04 01:14:51 +01:00
parent c7cf8282a6
commit 10afa74e82
Notes: blender-bot 2023-02-14 06:00:50 +01:00
Referenced by issue #61823, Flickering material problem with eevee
1 changed files with 33 additions and 23 deletions

View File

@ -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;