[Bf-blender-cvs] [5ae58f8ab88] blender2.8: DWM: Use draw manager for sculpt PBVH drawing
Campbell Barton
noreply at git.blender.org
Thu May 11 13:29:42 CEST 2017
Commit: 5ae58f8ab889abfc8a1c8d9538ae0b4dea989408
Author: Campbell Barton
Date: Thu May 11 21:21:59 2017 +1000
Branches: blender2.8
https://developer.blender.org/rB5ae58f8ab889abfc8a1c8d9538ae0b4dea989408
DWM: Use draw manager for sculpt PBVH drawing
Add a shader-group type to draw
generated geometry by running a callback.
===================================================================
M source/blender/blenkernel/BKE_pbvh.h
M source/blender/blenkernel/intern/pbvh.c
M source/blender/draw/intern/DRW_render.h
M source/blender/draw/intern/draw_manager.c
M source/blender/draw/modes/sculpt_mode.c
M source/blender/gpu/GPU_buffers.h
M source/blender/gpu/intern/gpu_buffers.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 927303f8b3c..53180713cf9 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -30,6 +30,7 @@
#include "BLI_ghash.h"
#include "BLI_utildefines.h"
+struct Batch;
struct CCGElem;
struct CCGKey;
struct CustomData;
@@ -118,6 +119,9 @@ void BKE_pbvh_raycast_project_ray_root(
void BKE_pbvh_node_draw(PBVHNode *node, void *data);
void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3],
int (*setMaterial)(int matnr, void *attribs), bool wireframe, bool fast);
+void BKE_pbvh_draw_cb(
+ PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast,
+ void (*draw_fn)(void *user_data, struct Batch *batch), void *user_data);
/* PBVH Access */
typedef enum {
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 6bfb9d779c2..02b4479df4f 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -1845,6 +1845,67 @@ void BKE_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*fnors)[3],
pbvh_draw_BB(bvh);
}
+struct PBVHNodeDrawCallbackData {
+
+ void (*draw_fn)(void *user_data, Batch *batch);
+ void *user_data;
+ bool fast;
+};
+
+static void pbvh_node_draw_cb(PBVHNode *node, void *data_v)
+{
+ struct PBVHNodeDrawCallbackData *data = data_v;
+
+ if (!(node->flag & PBVH_FullyHidden)) {
+ Batch *triangles = GPU_draw_pbvh_buffers_get_batch(node->draw_buffers, data->fast);
+ if (triangles != NULL) {
+ data->draw_fn(data->user_data, triangles);
+ }
+ }
+}
+
+/**
+ * Version of #BKE_pbvh_draw that runs a callback.
+ */
+void BKE_pbvh_draw_cb(
+ PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast,
+ void (*draw_fn)(void *user_data, Batch *batch), void *user_data)
+{
+ struct PBVHNodeDrawCallbackData draw_data = {
+ .fast = fast,
+ .draw_fn = draw_fn,
+ .user_data = user_data,
+ };
+ PBVHNode **nodes;
+ int totnode;
+
+ for (int a = 0; a < bvh->totnode; a++)
+ pbvh_node_check_diffuse_changed(bvh, &bvh->nodes[a]);
+
+ BKE_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals | PBVH_UpdateDrawBuffers),
+ &nodes, &totnode);
+
+ pbvh_update_normals(bvh, nodes, totnode, fnors);
+ pbvh_update_draw_buffers(bvh, nodes, totnode);
+
+ if (nodes) MEM_freeN(nodes);
+
+ if (planes) {
+ BKE_pbvh_search_callback(
+ bvh, BKE_pbvh_node_planes_contain_AABB,
+ planes, pbvh_node_draw_cb, &draw_data);
+ }
+ 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_grids_update(PBVH *bvh, CCGElem **grids, void **gridfaces,
DMFlagMat *flagmats, BLI_bitmap **grid_hidden)
{
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 1cdb213d86f..bcc3277adc9 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -254,6 +254,7 @@ typedef enum {
DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass);
+DRWShadingGroup *DRW_shgroup_create_fn(struct GPUShader *shader, DRWPass *pass);
DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass);
DRWShadingGroup *DRW_shgroup_material_instance_create(struct GPUMaterial *material, DRWPass *pass, struct Batch *geom);
DRWShadingGroup *DRW_shgroup_instance_create(struct GPUShader *shader, DRWPass *pass, struct Batch *geom);
@@ -261,8 +262,15 @@ DRWShadingGroup *DRW_shgroup_point_batch_create(struct GPUShader *shader, DRWPas
DRWShadingGroup *DRW_shgroup_line_batch_create(struct GPUShader *shader, DRWPass *pass);
DRWShadingGroup *DRW_shgroup_empty_tri_batch_create(struct GPUShader *shader, DRWPass *pass, int size);
+typedef void (DRWCallGenerateFn)(
+ DRWShadingGroup *shgroup,
+ void (*draw_fn)(DRWShadingGroup *shgroup, struct Batch *geom),
+ void *user_data);
+
void DRW_shgroup_free(struct DRWShadingGroup *shgroup);
void DRW_shgroup_call_add(DRWShadingGroup *shgroup, struct Batch *geom, float (*obmat)[4]);
+void DRW_shgroup_call_generate_add(
+ DRWShadingGroup *shgroup, DRWCallGenerateFn *geometry_fn, void *user_data, float (*obmat)[4]);
void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *attr[], unsigned int attr_len);
#define DRW_shgroup_call_dynamic_add(shgroup, ...) do { \
const void *array[] = {__VA_ARGS__}; \
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index df3b4d03d8b..33456e20163 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -189,10 +189,21 @@ typedef struct DRWCall {
#ifdef USE_GPU_SELECT
int select_id;
#endif
- Batch *geometry;
float (*obmat)[4];
+ Batch *geometry;
} DRWCall;
+typedef struct DRWCallGenerate {
+ struct DRWCallGenerate *next, *prev;
+#ifdef USE_GPU_SELECT
+ int select_id;
+#endif
+ float (*obmat)[4];
+
+ DRWCallGenerateFn *geometry_fn;
+ void *user_data;
+} DRWCallGenerate;
+
typedef struct DRWCallDynamic {
struct DRWCallDynamic *next, *prev;
#ifdef USE_GPU_SELECT
@@ -222,6 +233,8 @@ struct DRWShadingGroup {
/* Used by DRWShadingGroup.type */
enum {
DRW_SHG_NORMAL,
+ /* same as 'DRW_SHG_NORMAL' but use a callback to generate geometry */
+ DRW_SHG_NORMAL_GENERATE,
DRW_SHG_POINT_BATCH,
DRW_SHG_LINE_BATCH,
DRW_SHG_TRIANGLE_BATCH,
@@ -646,6 +659,15 @@ DRWShadingGroup *DRW_shgroup_create(struct GPUShader *shader, DRWPass *pass)
return shgroup;
}
+DRWShadingGroup *DRW_shgroup_create_fn(struct GPUShader *shader, DRWPass *pass)
+{
+ DRWShadingGroup *shgroup = DRW_shgroup_create(shader, pass);
+
+ shgroup->type = DRW_SHG_NORMAL_GENERATE;
+
+ return shgroup;
+}
+
DRWShadingGroup *DRW_shgroup_material_create(struct GPUMaterial *material, DRWPass *pass)
{
double time = 0.0; /* TODO make time variable */
@@ -796,6 +818,28 @@ void DRW_shgroup_call_add(DRWShadingGroup *shgroup, Batch *geom, float (*obmat)[
BLI_addtail(&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(shgroup->type == DRW_SHG_NORMAL_GENERATE);
+
+ DRWCallGenerate *call = MEM_callocN(sizeof(DRWCallGenerate), "DRWCallGenerate");
+
+ call->obmat = obmat;
+
+ call->geometry_fn = geometry_fn;
+ call->user_data = user_data;
+
+#ifdef USE_GPU_SELECT
+ call->select_id = g_DRW_select_id;
+#endif
+
+ BLI_addtail(&shgroup->calls, call);
+}
+
void DRW_shgroup_call_dynamic_add_array(DRWShadingGroup *shgroup, const void *attr[], unsigned int attr_len)
{
DRWInterface *interface = shgroup->interface;
@@ -1348,7 +1392,7 @@ typedef struct DRWBoundTexture {
GPUTexture *tex;
} DRWBoundTexture;
-static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*obmat)[4])
+static void draw_geometry_prepare(DRWShadingGroup *shgroup, const float (*obmat)[4])
{
RegionView3D *rv3d = DST.draw_ctx.rv3d;
DRWInterface *interface = shgroup->interface;
@@ -1445,7 +1489,11 @@ static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*o
if (interface->eye != -1) {
GPU_shader_uniform_vector(shgroup->shader, interface->eye, 3, 1, (float *)eye);
}
+}
+static void draw_geometry_execute(DRWShadingGroup *shgroup, Batch *geom)
+{
+ DRWInterface *interface = shgroup->interface;
/* step 2 : bind vertex array & draw */
Batch_set_program(geom, GPU_shader_get_program(shgroup->shader), GPU_shader_get_interface(shgroup->shader));
if (interface->instance_vbo) {
@@ -1457,6 +1505,13 @@ static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*o
}
}
+static void draw_geometry(DRWShadingGroup *shgroup, Batch *geom, const float (*obmat)[4])
+{
+ draw_geometry_prepare(shgroup, obmat);
+
+ draw_geometry_execute(shgroup, geom);
+}
+
static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
{
BLI_assert(shgroup->shader);
@@ -1472,7 +1527,9 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
DST.shader = shgroup->shader;
}
- if (shgroup->type != DRW_SHG_NORMAL) {
+ const bool is_normal = ELEM(shgroup->type, DRW_SHG_NORMAL, DRW_SHG_NORMAL_GENERATE);
+
+ if (!is_normal) {
shgroup_dynamic_batch_from_calls(shgroup);
}
@@ -1547,7 +1604,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
#endif
/* Rendering Calls */
- if (shgroup->type != DRW_SHG_NORMAL) {
+ if (!is_normal) {
/* Replacing multiple calls with only one */
float obmat[4][4];
unit_m4(obmat);
@@ -1564,7 +1621,7 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
}
}
}
- else {
+ else if (shgroup->type == DRW_SHG_NORMAL) {
for (DRWCall *call = shgroup->calls.first; call; call = call->next) {
bool neg_scale = call->obmat && is_negative_m4(call->obmat);
@@ -1582,6 +1639,29 @@ static void draw_shgroup(DRWShadingGroup *shgroup, DRWState pass_state)
}
}
}
+ else if (shgroup->type == DRW_SHG_NORMAL_GENERATE) {
+ /* Same as 'DRW_SHG_NORMAL' but generate batches */
+ for (DRWCallGenerate *call = shgroup->calls.first; call; call = call->next) {
+ bool neg_scale = call->obmat && is_negative_m4(call->obmat);
+
+ /* Negative scale objects */
+ if (neg_scale) {
+ glFrontFace(GL_CW);
+ }
+
+ GPU_SELECT_LOAD_IF_PICKSEL(call);
+ draw_geometry_prepare(shgroup, call->obmat);
+ call->geometry_fn(shgroup, draw_geometry_execute, call->user_data);
+
+ /* Reset state */
+ if (neg_scale) {
+ glFrontFace(GL_CCW);
+ }
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
/* TODO: remove, (currently causes alpha issue with sculpt, need to investigate) */
DRW_state_reset();
diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c
index 114bc8c96c4..ba9219c9abb 100644
--- a/source/blender/draw/modes/sculpt_mode.c
+++ b/source/blender/draw/modes/s
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list