[Bf-blender-cvs] [b2f1a658741] master: Sculpt: Refactor draw manager sculpt drawing mechanism

Clément Foucault noreply at git.blender.org
Sat May 4 14:11:37 CEST 2019


Commit: b2f1a6587410d00ad3bbd22e045979f80048afe2
Author: Clément Foucault
Date:   Sat May 4 01:39:35 2019 +0200
Branches: master
https://developer.blender.org/rBb2f1a6587410d00ad3bbd22e045979f80048afe2

Sculpt: Refactor draw manager sculpt drawing mechanism

Workbench/Eevee now displays multiple multi-materials correctly.

Iterate over pbvh nodes when doing object iteration. This makes the
rendering process more streamlined and allow for using different materials.

This change will make possible to:
- Add culling pass of each pbvh leaf node. (speedup if zoomed on a small
area)
- Reduce number of lead node iteration.
- Reduce code complexity

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

M	source/blender/blenkernel/BKE_pbvh.h
M	source/blender/blenkernel/intern/pbvh.c
M	source/blender/draw/engines/eevee/eevee_materials.c
M	source/blender/draw/engines/workbench/workbench_deferred.c
M	source/blender/draw/engines/workbench/workbench_forward.c
M	source/blender/draw/intern/DRW_render.h
M	source/blender/draw/intern/draw_manager_data.c
M	source/blender/draw/modes/overlay_mode.c
M	source/blender/draw/modes/sculpt_mode.c

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

diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index f59288f54bd..9b15462de6b 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -40,6 +40,7 @@ struct MPoly;
 struct MVert;
 struct PBVH;
 struct PBVHNode;
+struct GPU_PBVH_Buffers;
 
 typedef struct PBVH PBVH;
 typedef struct PBVHNode PBVHNode;
@@ -48,6 +49,21 @@ typedef struct {
   float (*co)[3];
 } PBVHProxyNode;
 
+typedef enum {
+  PBVH_Leaf = 1,
+
+  PBVH_UpdateNormals = 2,
+  PBVH_UpdateBB = 4,
+  PBVH_UpdateOriginalBB = 8,
+  PBVH_UpdateDrawBuffers = 16,
+  PBVH_UpdateRedraw = 32,
+
+  PBVH_RebuildDrawBuffers = 64,
+  PBVH_FullyHidden = 128,
+
+  PBVH_UpdateTopology = 256,
+} PBVHNodeFlags;
+
 /* Callbacks */
 
 /* returns 1 if the search should continue from this node, 0 otherwise */
@@ -151,13 +167,15 @@ bool BKE_pbvh_node_find_nearest_to_ray(PBVH *bvh,
 void BKE_pbvh_draw_cb(PBVH *bvh,
                       float (*planes)[4],
                       float (*fnors)[3],
-                      bool fast,
-                      bool wires,
-                      bool only_mask,
                       bool show_vcol,
-                      void (*draw_fn)(void *user_data, struct GPUBatch *batch),
+                      void (*draw_fn)(void *user_data, struct GPU_PBVH_Buffers *buffers),
                       void *user_data);
 
+void BKE_pbvh_draw_debug_cb(
+    PBVH *bvh,
+    void (*draw_fn)(void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag),
+    void *user_data);
+
 /* PBVH Access */
 typedef enum {
   PBVH_FACES,
@@ -202,21 +220,6 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *bvh,
 
 /* Node Access */
 
-typedef enum {
-  PBVH_Leaf = 1,
-
-  PBVH_UpdateNormals = 2,
-  PBVH_UpdateBB = 4,
-  PBVH_UpdateOriginalBB = 8,
-  PBVH_UpdateDrawBuffers = 16,
-  PBVH_UpdateRedraw = 32,
-
-  PBVH_RebuildDrawBuffers = 64,
-  PBVH_FullyHidden = 128,
-
-  PBVH_UpdateTopology = 256,
-} PBVHNodeFlags;
-
 void BKE_pbvh_node_mark_update(PBVHNode *node);
 void BKE_pbvh_node_mark_rebuild_draw(PBVHNode *node);
 void BKE_pbvh_node_mark_redraw(PBVHNode *node);
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index cb4ac0ea01b..f1d5347c48b 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -2202,26 +2202,17 @@ bool BKE_pbvh_node_planes_exclude_AABB(PBVHNode *node, void *data)
   return test_planes_aabb(bb_min, bb_max, data) != ISECT_INSIDE;
 }
 
-struct PBVHNodeDrawCallbackData {
-  void (*draw_fn)(void *user_data, GPUBatch *batch);
+typedef struct PBVHNodeDrawCallbackData {
+  void (*draw_fn)(void *user_data, GPU_PBVH_Buffers *buffers);
   void *user_data;
-  bool fast;
-  bool only_mask; /* Only draw nodes that have mask data. */
-  bool wires;
-};
+} PBVHNodeDrawCallbackData;
 
 static void pbvh_node_draw_cb(PBVHNode *node, void *data_v)
 {
-  struct PBVHNodeDrawCallbackData *data = data_v;
+  PBVHNodeDrawCallbackData *data = data_v;
 
   if (!(node->flag & PBVH_FullyHidden)) {
-    GPUBatch *batch = GPU_pbvh_buffers_batch_get(node->draw_buffers, data->fast, data->wires);
-    bool show_mask = GPU_pbvh_buffers_has_mask(node->draw_buffers);
-    if (!data->only_mask || show_mask) {
-      if (batch != NULL) {
-        data->draw_fn(data->user_data, batch);
-      }
-    }
+    data->draw_fn(data->user_data, node->draw_buffers);
   }
 }
 
@@ -2231,20 +2222,10 @@ static void pbvh_node_draw_cb(PBVHNode *node, void *data_v)
 void BKE_pbvh_draw_cb(PBVH *bvh,
                       float (*planes)[4],
                       float (*fnors)[3],
-                      bool fast,
-                      bool wires,
-                      bool only_mask,
                       bool show_vcol,
-                      void (*draw_fn)(void *user_data, GPUBatch *batch),
+                      void (*draw_fn)(void *user_data, GPU_PBVH_Buffers *buffers),
                       void *user_data)
 {
-  struct PBVHNodeDrawCallbackData draw_data = {
-      .only_mask = only_mask,
-      .fast = fast,
-      .wires = wires,
-      .draw_fn = draw_fn,
-      .user_data = user_data,
-  };
   PBVHNode **nodes;
   int totnode;
 
@@ -2261,6 +2242,11 @@ void BKE_pbvh_draw_cb(PBVH *bvh,
     MEM_freeN(nodes);
   }
 
+  PBVHNodeDrawCallbackData draw_data = {
+      .draw_fn = draw_fn,
+      .user_data = user_data,
+  };
+
   if (planes) {
     BKE_pbvh_search_callback(
         bvh, BKE_pbvh_node_planes_contain_AABB, planes, pbvh_node_draw_cb, &draw_data);
@@ -2268,10 +2254,18 @@ void BKE_pbvh_draw_cb(PBVH *bvh,
   else {
     BKE_pbvh_search_callback(bvh, NULL, NULL, pbvh_node_draw_cb, &draw_data);
   }
-#if 0
-  if (G.debug_value == 14)
-    pbvh_draw_BB(bvh);
-#endif
+}
+
+void BKE_pbvh_draw_debug_cb(
+    PBVH *bvh,
+    void (*draw_fn)(void *user_data, const float bmin[3], const float bmax[3], PBVHNodeFlags flag),
+    void *user_data)
+{
+  for (int a = 0; a < bvh->totnode; a++) {
+    PBVHNode *node = &bvh->nodes[a];
+
+    draw_fn(user_data, node->vb.bmin, node->vb.bmax, node->flag);
+  }
 }
 
 void BKE_pbvh_grids_update(
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index c6a523e4822..8ee5b51d825 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -1190,17 +1190,12 @@ void EEVEE_materials_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata)
 
 #define ADD_SHGROUP_CALL(shgrp, ob, ma, geom, oedata) \
   do { \
-    if (is_sculpt_mode_draw) { \
-      DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat); \
+    if (oedata) { \
+      DRW_shgroup_call_object_add_with_callback( \
+          shgrp, geom, ob, ma, EEVEE_lightprobes_obj_visibility_cb, oedata); \
     } \
     else { \
-      if (oedata) { \
-        DRW_shgroup_call_object_add_with_callback( \
-            shgrp, geom, ob, ma, EEVEE_lightprobes_obj_visibility_cb, oedata); \
-      } \
-      else { \
-        DRW_shgroup_call_object_add_ex(shgrp, geom, ob, ma, false); \
-      } \
+      DRW_shgroup_call_object_add_ex(shgrp, geom, ob, ma, false); \
     } \
   } while (0)
 
@@ -1604,6 +1599,16 @@ static void material_transparent(Material *ma,
   }
 }
 
+/* Return correct material or &defmaterial if slot is empty. */
+BLI_INLINE Material *eevee_object_material_get(Object *ob, int slot)
+{
+  Material *ma = give_current_material(ob, slot + 1);
+  if (ma == NULL) {
+    ma = &defmaterial;
+  }
+  return ma;
+}
+
 void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
                                     EEVEE_ViewLayerData *sldata,
                                     Object *ob,
@@ -1617,15 +1622,14 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
 
   const bool do_cull = (draw_ctx->v3d &&
                         (draw_ctx->v3d->shading.flag & V3D_SHADING_BACKFACE_CULLING));
-  const bool is_sculpt_mode = DRW_object_use_pbvh_drawing(ob);
+  bool is_sculpt_mode = DRW_object_use_pbvh_drawing(ob);
   /* For now just force fully shaded with eevee when supported. */
-  const bool is_sculpt_mode_draw = ob->sculpt && ob->sculpt->pbvh &&
-                                   BKE_pbvh_type(ob->sculpt->pbvh) != PBVH_FACES;
-  const bool is_default_mode_shader = is_sculpt_mode;
+  is_sculpt_mode = is_sculpt_mode &&
+                   !(ob->sculpt->pbvh && BKE_pbvh_type(ob->sculpt->pbvh) == PBVH_FACES);
 
   /* First get materials for this mesh. */
   if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL)) {
-    const int materials_len = MAX2(1, (is_sculpt_mode_draw ? 1 : ob->totcol));
+    const int materials_len = MAX2(1, ob->totcol);
 
     struct DRWShadingGroup **shgrp_array = BLI_array_alloca(shgrp_array, materials_len);
     struct DRWShadingGroup **shgrp_depth_array = BLI_array_alloca(shgrp_depth_array,
@@ -1635,40 +1639,22 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
 
     struct GPUMaterial **gpumat_array = BLI_array_alloca(gpumat_array, materials_len);
     struct GPUMaterial **gpumat_depth_array = BLI_array_alloca(gpumat_array, materials_len);
+    struct Material **ma_array = BLI_array_alloca(ma_array, materials_len);
 
     bool use_flat_nor = false;
-
-    if (is_default_mode_shader) {
-      if (is_sculpt_mode_draw) {
-        use_flat_nor = DRW_object_is_flat_normal(ob);
-      }
-    }
-
     for (int i = 0; i < materials_len; ++i) {
-      Material *ma;
-
-      if (is_sculpt_mode_draw) {
-        ma = NULL;
-      }
-      else {
-        ma = give_current_material(ob, i + 1);
-      }
-
+      ma_array[i] = eevee_object_material_get(ob, i);
       gpumat_array[i] = NULL;
       gpumat_depth_array[i] = NULL;
       shgrp_array[i] = NULL;
       shgrp_depth_array[i] = NULL;
       shgrp_depth_clip_array[i] = NULL;
 
-      if (ma == NULL) {
-        ma = &defmaterial;
-      }
-
-      switch (ma->blend_method) {
+      switch (ma_array[i]->blend_method) {
         case MA_BM_SOLID:
         case MA_BM_CLIP:
         case MA_BM_HASHED:
-          material_opaque(ma,
+          material_opaque(ma_array[i],
                           material_hash,
                           sldata,
                           vedata,
@@ -1683,7 +1669,7 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
         case MA_BM_ADD:
         case MA_BM_MULTIPLY:
         case MA_BM_BLEND:
-          material_transparent(ma,
+          material_transparent(ma_array[i],
                                sldata,
                                vedata,
                                do_cull,
@@ -1725,17 +1711,18 @@ void EEVEE_materials_cache_populate(EEVEE_Data *vedata,
                                                          &auto_layer_count);
       }
 
-      if (is_sculpt_mode_draw || mat_geom) {
+      if (is_sculpt_mode) {
+        /* TODO(fclem): Support Vcol. */
+        DRW_shgroup_call_sculpt_with_materials_add(shgrp_array, ma_array, ob, false);
+        DRW_shgroup_call_sculpt_with_materials_add(shgrp_depth_array, ma_array, ob, false);
+        DRW_shgroup_call_sculpt_with_materials_add(shgrp_depth_clip_array, ma_array, ob, false);
+        /* TODO(fclem): Support shadows in sculpt 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list