[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