diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-04-24 13:29:15 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-04-24 13:48:43 +0300 |
commit | 2ff8f965dfa5f680f613fc33425281e398893f49 (patch) | |
tree | 886990052152c485052d10cffb758267c2d01f17 /source/blender/draw/intern/draw_manager_exec.c | |
parent | 8fb9dfbec5fa5b6ed1f94494b6972988605e5c14 (diff) |
DRW: Add visibility callback function.
This add a callback function that runs after frustum culling test.
This callback returns the final visibility for this object.
Be aware that it's called for EVERY drawcalls that use this callback even
if their visibility has been cached.
Diffstat (limited to 'source/blender/draw/intern/draw_manager_exec.c')
-rw-r--r-- | source/blender/draw/intern/draw_manager_exec.c | 30 |
1 files changed, 22 insertions, 8 deletions
diff --git a/source/blender/draw/intern/draw_manager_exec.c b/source/blender/draw/intern/draw_manager_exec.c index 159a19a94c2..9aa5efc837d 100644 --- a/source/blender/draw/intern/draw_manager_exec.c +++ b/source/blender/draw/intern/draw_manager_exec.c @@ -644,22 +644,35 @@ bool DRW_culling_box_test(BoundBox *bbox) /** \name Draw (DRW_draw) * \{ */ +static void draw_visibility_eval(DRWCallState *st) +{ + bool culled = st->flag & DRW_CALL_CULLED; + + if (st->cache_id != DST.state_cache_id) { + /* Update culling result for this view. */ + culled = !DRW_culling_sphere_test(&st->bsphere); + } + + if (st->visibility_cb) { + culled = !st->visibility_cb(!culled, st->user_data); + } + + SET_FLAG_FROM_TEST(st->flag, culled, DRW_CALL_CULLED); +} + static void draw_matrices_model_prepare(DRWCallState *st) { if (st->cache_id == DST.state_cache_id) { - return; /* Values are already updated for this view. */ + /* Values are already updated for this view. */ + return; } else { st->cache_id = DST.state_cache_id; } - if (DRW_culling_sphere_test(&st->bsphere)) { - st->flag &= ~DRW_CALL_CULLED; - } - else { - st->flag |= DRW_CALL_CULLED; - return; /* No need to go further the call will not be used. */ - } + /* No need to go further the call will not be used. */ + if (st->flag & DRW_CALL_CULLED) + return; /* Order matters */ if (st->matflag & (DRW_CALL_MODELVIEW | DRW_CALL_MODELVIEWINVERSE | @@ -1014,6 +1027,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state) for (DRWCall *call = shgroup->calls.first; call; call = call->next) { /* OPTI/IDEA(clem): Do this preparation in another thread. */ + draw_visibility_eval(call->state); draw_matrices_model_prepare(call->state); if ((call->state->flag & DRW_CALL_CULLED) != 0) |