Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2019-05-04 02:39:35 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-05-04 15:11:04 +0300
commitb2f1a6587410d00ad3bbd22e045979f80048afe2 (patch)
tree8312daea35aed37a1cdba6d6e6e97958b7f21d47 /source/blender/draw/intern/draw_manager_data.c
parent1d8ed6dcd7cd2b3ccfaaacb59387dca481262eb6 (diff)
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
Diffstat (limited to 'source/blender/draw/intern/draw_manager_data.c')
-rw-r--r--source/blender/draw/intern/draw_manager_data.c200
1 files changed, 121 insertions, 79 deletions
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 65ef2fa66fa..c63e30e65d7 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -38,6 +38,8 @@
#include "BLI_link_utils.h"
#include "BLI_mempool.h"
+#include "GPU_buffers.h"
+
#include "intern/gpu_codegen.h"
struct GPUVertFormat *g_pos_format = NULL;
@@ -616,110 +618,150 @@ void DRW_shgroup_call_object_instances_add(DRWShadingGroup *shgroup,
BLI_LINKS_APPEND(&shgroup->calls, call);
}
-void DRW_shgroup_call_generate_add(DRWShadingGroup *shgroup,
- DRWCallGenerateFn *geometry_fn,
- void *user_data,
- float (*obmat)[4])
-{
- BLI_assert(geometry_fn != NULL);
- BLI_assert(ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_FEEDBACK_TRANSFORM));
+// #define SCULPT_DEBUG_BUFFERS
- DRWCall *call = BLI_mempool_alloc(DST.vmempool->calls);
- call->state = drw_call_state_create(shgroup, obmat, NULL);
- call->type = DRW_CALL_GENERATE;
- call->generate.geometry_fn = geometry_fn;
- call->generate.user_data = user_data;
-#ifdef USE_GPU_SELECT
- call->select_id = DST.select_id;
+typedef struct DRWSculptCallbackData {
+ Object *ob;
+ DRWShadingGroup **shading_groups;
+ Material **materials;
+ bool use_wire;
+ bool use_mats;
+ bool use_mask;
+ bool fast_mode; /* Set by draw manager. Do not init. */
+#ifdef SCULPT_DEBUG_BUFFERS
+ int node_nr;
+#endif
+} DRWSculptCallbackData;
+
+#ifdef SCULPT_DEBUG_BUFFERS
+# define SCULPT_DEBUG_COLOR(id) (sculpt_debug_colors[id % 9])
+static float sculpt_debug_colors[9][4] = {
+ {1.0f, 0.2f, 0.2f, 1.0f},
+ {0.2f, 1.0f, 0.2f, 1.0f},
+ {0.2f, 0.2f, 1.0f, 1.0f},
+ {1.0f, 1.0f, 0.2f, 1.0f},
+ {0.2f, 1.0f, 1.0f, 1.0f},
+ {1.0f, 0.2f, 1.0f, 1.0f},
+ {1.0f, 0.7f, 0.2f, 1.0f},
+ {0.2f, 1.0f, 0.7f, 1.0f},
+ {0.7f, 0.2f, 1.0f, 1.0f},
+};
#endif
- BLI_LINKS_APPEND(&shgroup->calls, call);
-}
-
-/* This function tests if the current draw engine draws the vertex colors
- * It is used when drawing sculpts
- *
- * XXX: should we use a callback to a the draw engine to retrieve this
- * setting, this makes the draw manager more clean? */
-static bool DRW_draw_vertex_color_active(const DRWContextState *draw_ctx)
-{
- View3D *v3d = draw_ctx->v3d;
- return v3d->shading.type == OB_SOLID && v3d->shading.color_type == V3D_SHADING_VERTEX_COLOR;
-}
-
-static void sculpt_draw_cb(DRWShadingGroup *shgroup,
- void (*draw_fn)(DRWShadingGroup *shgroup, GPUBatch *geom),
- void *user_data)
+static void sculpt_draw_cb(DRWSculptCallbackData *scd, GPU_PBVH_Buffers *buffers)
{
- Object *ob = user_data;
-
- /* XXX should be ensured before but sometime it's not... go figure (see T57040). */
- PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(DST.draw_ctx.depsgraph, ob);
+ GPUBatch *geom = GPU_pbvh_buffers_batch_get(buffers, scd->fast_mode, scd->use_wire);
+ Material *ma = NULL;
+ short index = 0;
- const DRWContextState *drwctx = DRW_context_state_get();
- int fast_mode = 0;
+ /* Meh... use_mask is a bit misleading here. */
+ if (scd->use_mask && !GPU_pbvh_buffers_has_mask(buffers)) {
+ return;
+ }
- if (drwctx->evil_C != NULL) {
- Paint *p = BKE_paint_get_active_from_context(drwctx->evil_C);
- if (p && (p->flags & PAINT_FAST_NAVIGATE)) {
- fast_mode = drwctx->rv3d->rflag & RV3D_NAVIGATING;
- }
+ if (scd->use_mats) {
+ index = GPU_pbvh_buffers_material_index_get(buffers);
+ ma = scd->materials[index];
}
- if (pbvh) {
- const bool show_vcol = DRW_draw_vertex_color_active(drwctx);
- BKE_pbvh_draw_cb(pbvh,
- NULL,
- NULL,
- fast_mode,
- false,
- false,
- show_vcol,
- (void (*)(void *, GPUBatch *))draw_fn,
- shgroup);
+ DRWShadingGroup *shgrp = scd->shading_groups[index];
+ if (geom != NULL && shgrp != NULL) {
+#ifdef SCULPT_DEBUG_BUFFERS
+ /* Color each buffers in different colors. Only work in solid/Xray mode. */
+ shgrp = DRW_shgroup_create_sub(shgrp);
+ DRW_shgroup_uniform_vec3(shgrp, "materialDiffuseColor", SCULPT_DEBUG_COLOR(scd->node_nr++), 1);
+#endif
+ /* DRW_shgroup_call_object_add_ex reuses matrices calculations for all the drawcalls of this
+ * object. */
+ DRW_shgroup_call_object_add_ex(shgrp, geom, scd->ob, ma, true);
}
}
-static void sculpt_draw_wires_cb(DRWShadingGroup *shgroup,
- void (*draw_fn)(DRWShadingGroup *shgroup, GPUBatch *geom),
- void *user_data)
+#ifdef SCULPT_DEBUG_BUFFERS
+static void sculpt_debug_cb(void *user_data,
+ const float bmin[3],
+ const float bmax[3],
+ PBVHNodeFlags flag)
{
- Object *ob = user_data;
+ int *node_nr = (int *)user_data;
+ BoundBox bb;
+ BKE_boundbox_init_from_minmax(&bb, bmin, bmax);
+
+# if 0 /* Nodes hierarchy. */
+ if (flag & PBVH_Leaf) {
+ DRW_debug_bbox(&bb, (float[4]){0.0f, 1.0f, 0.0f, 1.0f});
+ }
+ else {
+ DRW_debug_bbox(&bb, (float[4]){0.5f, 0.5f, 0.5f, 0.6f});
+ }
+# else /* Color coded leaf bounds. */
+ if (flag & PBVH_Leaf) {
+ DRW_debug_bbox(&bb, SCULPT_DEBUG_COLOR((*node_nr)++));
+ }
+# endif
+}
+#endif
+static void drw_sculpt_generate_calls(DRWSculptCallbackData *scd, bool use_vcol)
+{
/* XXX should be ensured before but sometime it's not... go figure (see T57040). */
- PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(DST.draw_ctx.depsgraph, ob);
+ PBVH *pbvh = BKE_sculpt_object_pbvh_ensure(DST.draw_ctx.depsgraph, scd->ob);
+ if (!pbvh) {
+ return;
+ }
- const DRWContextState *drwctx = DRW_context_state_get();
- int fast_mode = 0;
+ float(*planes)[4] = NULL; /* TODO proper culling. */
+ scd->fast_mode = false;
+ const DRWContextState *drwctx = DRW_context_state_get();
if (drwctx->evil_C != NULL) {
Paint *p = BKE_paint_get_active_from_context(drwctx->evil_C);
if (p && (p->flags & PAINT_FAST_NAVIGATE)) {
- fast_mode = drwctx->rv3d->rflag & RV3D_NAVIGATING;
+ scd->fast_mode = (drwctx->rv3d->rflag & RV3D_NAVIGATING) != 0;
}
}
- if (pbvh) {
- BKE_pbvh_draw_cb(pbvh,
- NULL,
- NULL,
- fast_mode,
- true,
- false,
- false,
- (void (*)(void *, GPUBatch *))draw_fn,
- shgroup);
- }
-}
+ BKE_pbvh_draw_cb(
+ pbvh, planes, NULL, use_vcol, (void (*)(void *, GPU_PBVH_Buffers *))sculpt_draw_cb, scd);
-void DRW_shgroup_call_sculpt_add(DRWShadingGroup *shgroup, Object *ob, float (*obmat)[4])
-{
- DRW_shgroup_call_generate_add(shgroup, sculpt_draw_cb, ob, obmat);
+#ifdef SCULPT_DEBUG_BUFFERS
+ int node_nr = 0;
+ DRW_debug_modelmat(scd->ob->obmat);
+ BKE_pbvh_draw_debug_cb(
+ pbvh,
+ (void (*)(void *d, const float min[3], const float max[3], PBVHNodeFlags f))sculpt_debug_cb,
+ &node_nr);
+#endif
}
-void DRW_shgroup_call_sculpt_wires_add(DRWShadingGroup *shgroup, Object *ob, float (*obmat)[4])
-{
- DRW_shgroup_call_generate_add(shgroup, sculpt_draw_wires_cb, ob, obmat);
+void DRW_shgroup_call_sculpt_add(
+ DRWShadingGroup *shgroup, Object *ob, bool use_wire, bool use_mask, bool use_vcol)
+{
+ DRWSculptCallbackData scd = {
+ .ob = ob,
+ .shading_groups = &shgroup,
+ .materials = NULL,
+ .use_wire = use_wire,
+ .use_mats = false,
+ .use_mask = use_mask,
+ };
+ drw_sculpt_generate_calls(&scd, use_vcol);
+}
+
+void DRW_shgroup_call_sculpt_with_materials_add(DRWShadingGroup **shgroups,
+ Material **materials,
+ Object *ob,
+ bool use_vcol)
+{
+ DRWSculptCallbackData scd = {
+ .ob = ob,
+ .shading_groups = shgroups,
+ .materials = materials,
+ .use_wire = false,
+ .use_mats = true,
+ .use_mask = false,
+ };
+ drw_sculpt_generate_calls(&scd, use_vcol);
}
void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup,