[Bf-blender-cvs] [2ff8f965dfa] blender2.8: DRW: Add visibility callback function.

Clément Foucault noreply at git.blender.org
Tue Apr 24 12:48:52 CEST 2018


Commit: 2ff8f965dfa5f680f613fc33425281e398893f49
Author: Clément Foucault
Date:   Tue Apr 24 12:29:15 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB2ff8f965dfa5f680f613fc33425281e398893f49

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.

===================================================================

M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager.h
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/draw/intern/draw_manager_exec.c

===================================================================

diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 17537e295a6..5357da466ac 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -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);
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index fd75405f346..60ee003f25c 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -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. */
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 31f6108f7e0..b11455ead49 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -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);
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)



More information about the Bf-blender-cvs mailing list