forked from bartvdbraak/blender
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.
This commit is contained in:
parent
8fb9dfbec5
commit
2ff8f965df
@ -336,11 +336,19 @@ typedef void (DRWCallGenerateFn)(
|
||||
void (*draw_fn)(DRWShadingGroup *shgroup, struct Gwn_Batch *geom),
|
||||
void *user_data);
|
||||
|
||||
/* return final visibility */
|
||||
typedef bool (DRWCallVisibilityFn)(
|
||||
bool vis_in,
|
||||
void *user_data);
|
||||
|
||||
void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *batch);
|
||||
|
||||
void DRW_shgroup_free(struct DRWShadingGroup *shgroup);
|
||||
void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct Gwn_Batch *geom, float (*obmat)[4]);
|
||||
void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, struct Gwn_Batch *geom, struct Object *ob);
|
||||
void DRW_shgroup_call_object_add_with_callback(
|
||||
DRWShadingGroup *shgroup, struct Gwn_Batch *geom, struct Object *ob,
|
||||
DRWCallVisibilityFn *callback, void *user_data);
|
||||
/* Used for drawing a batch with instancing without instance attribs. */
|
||||
void DRW_shgroup_call_instances_add(
|
||||
DRWShadingGroup *shgroup, struct Gwn_Batch *geom, float (*obmat)[4], unsigned int *count);
|
||||
|
@ -102,6 +102,9 @@ enum {
|
||||
};
|
||||
|
||||
typedef struct DRWCallState {
|
||||
DRWCallVisibilityFn *visibility_cb;
|
||||
void *user_data;
|
||||
|
||||
unsigned char flag;
|
||||
unsigned char cache_id; /* Compared with DST.state_cache_id to see if matrices are still valid. */
|
||||
uint16_t matflag; /* Which matrices to compute. */
|
||||
|
@ -274,6 +274,7 @@ static DRWCallState *drw_call_state_create(DRWShadingGroup *shgroup, float (*obm
|
||||
DRWCallState *state = BLI_mempool_alloc(DST.vmempool->states);
|
||||
state->flag = 0;
|
||||
state->cache_id = 0;
|
||||
state->visibility_cb = NULL;
|
||||
state->matflag = shgroup->matflag;
|
||||
|
||||
/* Matrices */
|
||||
@ -357,6 +358,26 @@ void DRW_shgroup_call_object_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, Obje
|
||||
BLI_LINKS_APPEND(&shgroup->calls, call);
|
||||
}
|
||||
|
||||
void DRW_shgroup_call_object_add_with_callback(
|
||||
DRWShadingGroup *shgroup, Gwn_Batch *geom, Object *ob,
|
||||
DRWCallVisibilityFn *callback, void *user_data)
|
||||
{
|
||||
BLI_assert(geom != NULL);
|
||||
BLI_assert(shgroup->type == DRW_SHG_NORMAL);
|
||||
|
||||
DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
|
||||
call->state = drw_call_state_object(shgroup, ob->obmat, ob);
|
||||
call->state->visibility_cb = callback;
|
||||
call->state->user_data = user_data;
|
||||
call->type = DRW_CALL_SINGLE;
|
||||
call->single.geometry = geom;
|
||||
#ifdef USE_GPU_SELECT
|
||||
call->select_id = DST.select_id;
|
||||
#endif
|
||||
|
||||
BLI_LINKS_APPEND(&shgroup->calls, call);
|
||||
}
|
||||
|
||||
void DRW_shgroup_call_instances_add(DRWShadingGroup *shgroup, Gwn_Batch *geom, float (*obmat)[4], unsigned int *count)
|
||||
{
|
||||
BLI_assert(geom != NULL);
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user