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:
-rw-r--r--source/blender/blenkernel/BKE_pbvh.h2
-rw-r--r--source/blender/blenkernel/intern/pbvh.c10
-rw-r--r--source/blender/draw/intern/DRW_render.h1
-rw-r--r--source/blender/draw/intern/draw_manager_data.c34
-rw-r--r--source/blender/draw/modes/overlay_mode.c12
-rw-r--r--source/blender/draw/modes/sculpt_mode.c2
-rw-r--r--source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl2
-rw-r--r--source/blender/gpu/GPU_buffers.h2
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c249
9 files changed, 229 insertions, 85 deletions
diff --git a/source/blender/blenkernel/BKE_pbvh.h b/source/blender/blenkernel/BKE_pbvh.h
index 8127d682133..87d1a6c6915 100644
--- a/source/blender/blenkernel/BKE_pbvh.h
+++ b/source/blender/blenkernel/BKE_pbvh.h
@@ -125,7 +125,7 @@ bool BKE_pbvh_node_find_nearest_to_ray(
/* Drawing */
void BKE_pbvh_draw_cb(
- PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast, bool only_mask,
+ PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast, bool wires, bool only_mask,
void (*draw_fn)(void *user_data, struct GPUBatch *batch), void *user_data);
/* PBVH Access */
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 45a0872bdc5..69617a354a9 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -2049,6 +2049,7 @@ struct PBVHNodeDrawCallbackData {
void *user_data;
bool fast;
bool only_mask; /* Only draw nodes that have mask data. */
+ bool wires;
};
static void pbvh_node_draw_cb(PBVHNode *node, void *data_v)
@@ -2056,11 +2057,11 @@ static void pbvh_node_draw_cb(PBVHNode *node, void *data_v)
struct PBVHNodeDrawCallbackData *data = data_v;
if (!(node->flag & PBVH_FullyHidden)) {
- GPUBatch *triangles = GPU_pbvh_buffers_batch_get(node->draw_buffers, data->fast);
+ 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 (triangles != NULL) {
- data->draw_fn(data->user_data, triangles);
+ if (batch != NULL) {
+ data->draw_fn(data->user_data, batch);
}
}
}
@@ -2070,12 +2071,13 @@ static void pbvh_node_draw_cb(PBVHNode *node, void *data_v)
* Version of #BKE_pbvh_draw that runs a callback.
*/
void BKE_pbvh_draw_cb(
- PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast, bool only_mask,
+ PBVH *bvh, float (*planes)[4], float (*fnors)[3], bool fast, bool wires, bool only_mask,
void (*draw_fn)(void *user_data, GPUBatch *batch), void *user_data)
{
struct PBVHNodeDrawCallbackData draw_data = {
.only_mask = only_mask,
.fast = fast,
+ .wires = wires,
.draw_fn = draw_fn,
.user_data = user_data,
};
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 8f78953cb52..259605b4707 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -378,6 +378,7 @@ void DRW_shgroup_call_instances_add(
void DRW_shgroup_call_object_instances_add(
DRWShadingGroup *shgroup, struct GPUBatch *geom, struct Object *ob, uint *count);
void DRW_shgroup_call_sculpt_add(DRWShadingGroup *shgroup, struct Object *ob, float (*obmat)[4]);
+void DRW_shgroup_call_sculpt_wires_add(DRWShadingGroup *shgroup, struct Object *ob, 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[], uint attr_len);
diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c
index 73825c700d5..54456d43ef7 100644
--- a/source/blender/draw/intern/draw_manager_data.c
+++ b/source/blender/draw/intern/draw_manager_data.c
@@ -581,7 +581,34 @@ static void sculpt_draw_cb(
if (pbvh) {
BKE_pbvh_draw_cb(
- pbvh, NULL, NULL, fast_mode, false,
+ pbvh, NULL, NULL, fast_mode, false, false,
+ (void (*)(void *, GPUBatch *))draw_fn, shgroup);
+ }
+}
+
+static void sculpt_draw_wires_cb(
+ DRWShadingGroup *shgroup,
+ void (*draw_fn)(DRWShadingGroup *shgroup, GPUBatch *geom),
+ void *user_data)
+{
+ 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);
+
+ const DRWContextState *drwctx = DRW_context_state_get();
+ int fast_mode = 0;
+
+ 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 (pbvh) {
+ BKE_pbvh_draw_cb(
+ pbvh, NULL, NULL, fast_mode, true, false,
(void (*)(void *, GPUBatch *))draw_fn, shgroup);
}
}
@@ -591,6 +618,11 @@ void DRW_shgroup_call_sculpt_add(DRWShadingGroup *shgroup, Object *ob, float (*o
DRW_shgroup_call_generate_add(shgroup, sculpt_draw_cb, ob, obmat);
}
+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_dynamic_add_array(DRWShadingGroup *shgroup, const void *attr[], uint attr_len)
{
#ifdef USE_GPU_SELECT
diff --git a/source/blender/draw/modes/overlay_mode.c b/source/blender/draw/modes/overlay_mode.c
index ea502e176f1..9929e4ca6e4 100644
--- a/source/blender/draw/modes/overlay_mode.c
+++ b/source/blender/draw/modes/overlay_mode.c
@@ -319,11 +319,11 @@ static void overlay_cache_populate(void *vedata, Object *ob)
if (geom || is_sculpt_mode) {
shgrp = DRW_shgroup_create_sub(pd->face_wires_shgrp);
- static float all_wires_param = 10.0f;
- DRW_shgroup_uniform_float(
- shgrp, "wireStepParam",
- (all_wires || is_sculpt_mode) ? &all_wires_param : &pd->wire_step_param,
- 1);
+ float wire_step_param = 10.0f;
+ if (!is_sculpt_mode) {
+ wire_step_param = (all_wires) ? 1.0f : pd->wire_step_param;
+ }
+ DRW_shgroup_uniform_float_copy(shgrp, "wireStepParam", wire_step_param);
if (!(DRW_state_is_select() || DRW_state_is_depth())) {
DRW_shgroup_stencil_mask(shgrp, stencil_mask);
@@ -332,7 +332,7 @@ static void overlay_cache_populate(void *vedata, Object *ob)
}
if (is_sculpt_mode) {
- DRW_shgroup_call_sculpt_add(shgrp, ob, ob->obmat);
+ DRW_shgroup_call_sculpt_wires_add(shgrp, ob, ob->obmat);
}
else {
DRW_shgroup_call_add(shgrp, geom, ob->obmat);
diff --git a/source/blender/draw/modes/sculpt_mode.c b/source/blender/draw/modes/sculpt_mode.c
index 76312942613..546270f8a18 100644
--- a/source/blender/draw/modes/sculpt_mode.c
+++ b/source/blender/draw/modes/sculpt_mode.c
@@ -177,7 +177,7 @@ static void sculpt_draw_mask_cb(
if (pbvh) {
BKE_pbvh_draw_cb(
- pbvh, NULL, NULL, false, true,
+ pbvh, NULL, NULL, false, false, true,
(void (*)(void *, struct GPUBatch *))draw_fn, shgroup);
}
}
diff --git a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
index 2a328a71366..8cb4db23b7e 100644
--- a/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
+++ b/source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl
@@ -10,7 +10,7 @@ uniform float ofs;
#ifndef USE_SCULPT
float get_edge_sharpness(float wd)
{
- return (wd == 1.0) ? 1.0 : ((wd == 0.0) ? -1.0 : (wd + wireStepParam));
+ return ((wd == 1.0) ? 1.0 : ((wd == 0.0) ? -1.5 : wd)) + wireStepParam;
}
#else
float get_edge_sharpness(float wd) { return 1.0; }
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index 6e3b8f20b5c..dc634b91284 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -80,7 +80,7 @@ void GPU_pbvh_grid_buffers_update(
const int update_flags);
/* draw */
-struct GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast);
+struct GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool wires);
bool GPU_pbvh_buffers_has_mask(GPU_PBVH_Buffers *buffers);
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 9004ad5f4c9..71c55da690a 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -54,8 +54,11 @@
struct GPU_PBVH_Buffers {
GPUIndexBuf *index_buf, *index_buf_fast;
+ GPUIndexBuf *index_lines_buf, *index_lines_buf_fast;
GPUVertBuf *vert_buf;
+ GPUBatch *lines;
+ GPUBatch *lines_fast;
GPUBatch *triangles;
GPUBatch *triangles_fast;
@@ -75,8 +78,6 @@ struct GPU_PBVH_Buffers {
BLI_bitmap * const *grid_hidden;
const int *grid_indices;
int totgrid;
- bool has_hidden;
- bool is_index_buf_global; /* Means index_buf uses global bvh's grid_common_gpu_buffer, **DO NOT** free it! */
bool use_bmesh;
@@ -93,6 +94,12 @@ static struct {
uint pos, nor, msk;
} g_vbo_id = {0};
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name PBVH Utils
+ * \{ */
+
/* Allocates a non-initialized buffer to be sent to GPU.
* Return is false it indicates that the memory map failed. */
static bool gpu_pbvh_vert_buf_data_set(GPU_PBVH_Buffers *buffers, uint vert_len)
@@ -141,8 +148,27 @@ static void gpu_pbvh_batch_init(GPU_PBVH_Buffers *buffers, GPUPrimType prim)
prim, buffers->vert_buf,
buffers->index_buf_fast);
}
+
+ if (buffers->lines == NULL) {
+ BLI_assert(buffers->index_lines_buf != NULL);
+ buffers->lines = GPU_batch_create(
+ GPU_PRIM_LINES, buffers->vert_buf,
+ buffers->index_lines_buf);
+ }
+
+ if ((buffers->lines_fast == NULL) && buffers->index_lines_buf_fast) {
+ buffers->lines_fast = GPU_batch_create(
+ GPU_PRIM_LINES, buffers->vert_buf,
+ buffers->index_lines_buf_fast);
+ }
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Mesh PBVH
+ * \{ */
+
void GPU_pbvh_mesh_buffers_update(
GPU_PBVH_Buffers *buffers, const MVert *mvert,
const int *vert_indices, int totvert, const float *vmask,
@@ -246,12 +272,7 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(
buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers");
/* smooth or flat for all */
-#if 0
buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH;
-#else
- /* for DrawManager we dont support mixed smooth/flat */
- buffers->smooth = (mpoly[0].flag & ME_SMOOTH) != 0;
-#endif
buffers->show_mask = false;
@@ -274,14 +295,19 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(
return buffers;
}
+ GPU_BATCH_DISCARD_SAFE(buffers->triangles);
+ GPU_BATCH_DISCARD_SAFE(buffers->lines);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
+
/* An element index buffer is used for smooth shading, but flat
- * shading requires separate vertex normals so an index buffer is
+ * shading requires separate vertex normals so an index buffer
* can't be used there. */
if (buffers->smooth) {
- /* Fill the triangle buffer */
- buffers->index_buf = NULL;
- GPUIndexBufBuilder elb;
+ /* Fill the triangle and line buffers. */
+ GPUIndexBufBuilder elb, elb_lines;
GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, INT_MAX);
+ GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, INT_MAX);
for (i = 0; i < face_indices_len; ++i) {
const MLoopTri *lt = &looptri[face_indices[i]];
@@ -291,15 +317,33 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(
continue;
GPU_indexbuf_add_tri_verts(&elb, UNPACK3(face_vert_indices[i]));
+
+ /* TODO skip "non-real" edges. */
+ GPU_indexbuf_add_line_verts(&elb_lines, face_vert_indices[i][0], face_vert_indices[i][1]);
+ GPU_indexbuf_add_line_verts(&elb_lines, face_vert_indices[i][1], face_vert_indices[i][2]);
+ GPU_indexbuf_add_line_verts(&elb_lines, face_vert_indices[i][2], face_vert_indices[i][0]);
}
buffers->index_buf = GPU_indexbuf_build(&elb);
+ buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
}
else {
- if (!buffers->is_index_buf_global) {
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
+ /* Fill the only the line buffer. */
+ GPUIndexBufBuilder elb_lines;
+ GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, INT_MAX);
+
+ for (i = 0; i < face_indices_len; ++i) {
+ const MLoopTri *lt = &looptri[face_indices[i]];
+
+ /* Skip hidden faces */
+ if (paint_is_face_hidden(lt, mvert, mloop))
+ continue;
+
+ /* TODO skip "non-real" edges. */
+ GPU_indexbuf_add_line_verts(&elb_lines, i * 3 + 0, i * 3 + 1);
+ GPU_indexbuf_add_line_verts(&elb_lines, i * 3 + 1, i * 3 + 2);
+ GPU_indexbuf_add_line_verts(&elb_lines, i * 3 + 2, i * 3 + 0);
}
- buffers->index_buf = NULL;
- buffers->is_index_buf_global = false;
+ buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
}
buffers->tot_tri = tottri;
@@ -314,21 +358,35 @@ GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(
return buffers;
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Grid PBVH
+ * \{ */
+
static void gpu_pbvh_grid_fill_fast_buffer(GPU_PBVH_Buffers *buffers, int totgrid, int gridsize)
{
- GPUIndexBufBuilder elb;
+ GPUIndexBufBuilder elb, elb_lines;
if (buffers->smooth) {
- GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 6 * totgrid, INT_MAX);
+ GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, 4 * totgrid, INT_MAX);
+ GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 2 * totgrid, INT_MAX);
for (int i = 0; i < totgrid; i++) {
- GPU_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize + gridsize - 1);
- GPU_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize);
- GPU_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - gridsize);
- GPU_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - 1);
- GPU_indexbuf_add_generic_vert(&elb, i * gridsize * gridsize + gridsize - 1);
- GPU_indexbuf_add_generic_vert(&elb, (i + 1) * gridsize * gridsize - gridsize);
+ const uint v0 = i * gridsize * gridsize + gridsize - 1;
+ const uint v1 = i * gridsize * gridsize;
+ const uint v2 = (i + 1) * gridsize * gridsize - gridsize;
+ const uint v3 = (i + 1) * gridsize * gridsize - 1;
+
+ GPU_indexbuf_add_tri_verts(&elb, v0, v1, v2);
+ GPU_indexbuf_add_tri_verts(&elb, v3, v0, v2);
+
+ GPU_indexbuf_add_line_verts(&elb_lines, v0, v1);
+ GPU_indexbuf_add_line_verts(&elb_lines, v1, v2);
+ GPU_indexbuf_add_line_verts(&elb_lines, v2, v3);
+ GPU_indexbuf_add_line_verts(&elb_lines, v3, v0);
}
}
else {
+ GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, 4 * totgrid, INT_MAX);
GPU_indexbuf_init_ex(&elb, GPU_PRIM_TRI_STRIP, 5 * totgrid, INT_MAX, true);
uint vbo_index_offset = 0;
for (int i = 0; i < totgrid; i++) {
@@ -349,13 +407,13 @@ static void gpu_pbvh_grid_fill_fast_buffer(GPU_PBVH_Buffers *buffers, int totgri
if (is_grid_start && is_row_start) {
grid_indices[0] = vbo_index_offset + 0;
}
- else if (is_grid_start && is_row_end) {
+ if (is_grid_start && is_row_end) {
grid_indices[1] = vbo_index_offset + 2;
}
- else if (is_grid_end && is_row_start) {
+ if (is_grid_end && is_row_start) {
grid_indices[2] = vbo_index_offset + 1;
}
- else if (is_grid_end && is_row_end) {
+ if (is_grid_end && is_row_end) {
grid_indices[3] = vbo_index_offset + 3;
}
vbo_index_offset += 4;
@@ -370,9 +428,15 @@ static void gpu_pbvh_grid_fill_fast_buffer(GPU_PBVH_Buffers *buffers, int totgri
GPU_indexbuf_add_generic_vert(&elb, grid_indices[3]);
GPU_indexbuf_add_generic_vert(&elb, grid_indices[2]);
GPU_indexbuf_add_primitive_restart(&elb);
+
+ GPU_indexbuf_add_line_verts(&elb_lines, grid_indices[0], grid_indices[1]);
+ GPU_indexbuf_add_line_verts(&elb_lines, grid_indices[1], grid_indices[3]);
+ GPU_indexbuf_add_line_verts(&elb_lines, grid_indices[2], grid_indices[3]);
+ GPU_indexbuf_add_line_verts(&elb_lines, grid_indices[2], grid_indices[0]);
}
}
buffers->index_buf_fast = GPU_indexbuf_build(&elb);
+ buffers->index_lines_buf_fast = GPU_indexbuf_build(&elb_lines);
}
void GPU_pbvh_grid_buffers_update(
@@ -393,31 +457,30 @@ void GPU_pbvh_grid_buffers_update(
uint vert_count = totgrid * key->grid_area;
if (!buffers->smooth) {
- vert_count = totgrid * (key->grid_size - 1) * (key->grid_size - 1) * 4;
+ vert_count = totgrid * SQUARE(key->grid_size - 1) * 4;
/* Count strip restart verts (2 verts between each row and grid) */
vert_count += ((totgrid - 1) + totgrid * (key->grid_size - 2)) * 2;
}
- if (buffers->smooth && buffers->index_buf == NULL) {
- /* Not sure if really needed. */
- GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
- }
- else if (!buffers->smooth && buffers->index_buf != NULL) {
- /* Discard unnecessary index buffers. */
- GPU_BATCH_DISCARD_SAFE(buffers->triangles);
- GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
- }
+ GPU_BATCH_DISCARD_SAFE(buffers->triangles);
+ GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
+ GPU_BATCH_DISCARD_SAFE(buffers->lines);
+ GPU_BATCH_DISCARD_SAFE(buffers->lines_fast);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf_fast);
- if (buffers->index_buf_fast == NULL) {
+ if (buffers->index_buf_fast == NULL && key->grid_size > 2) {
gpu_pbvh_grid_fill_fast_buffer(buffers, totgrid, key->grid_size);
}
uint vbo_index_offset = 0;
/* Build VBO */
if (gpu_pbvh_vert_buf_data_set(buffers, vert_count)) {
+ GPUIndexBufBuilder elb_lines;
+ GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, totgrid * key->grid_area * 2, vert_count);
+
for (i = 0; i < totgrid; ++i) {
CCGElem *grid = grids[grid_indices[i]];
int vbo_index = vbo_index_offset;
@@ -437,6 +500,13 @@ void GPU_pbvh_grid_buffers_update(
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask);
empty_mask = empty_mask && (fmask == 0.0f);
}
+
+ if (x + 1 < key->grid_size) {
+ GPU_indexbuf_add_line_verts(&elb_lines, vbo_index, vbo_index + 1);
+ }
+ if (y + 1 < key->grid_size) {
+ GPU_indexbuf_add_line_verts(&elb_lines, vbo_index, vbo_index + key->grid_size);
+ }
vbo_index += 1;
}
}
@@ -488,6 +558,15 @@ void GPU_pbvh_grid_buffers_update(
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 3, co[1]);
GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 3, no_short);
+ GPU_indexbuf_add_line_verts(&elb_lines, vbo_index, vbo_index + 1);
+ GPU_indexbuf_add_line_verts(&elb_lines, vbo_index, vbo_index + 2);
+ if (is_row_end) {
+ GPU_indexbuf_add_line_verts(&elb_lines, vbo_index + 2, vbo_index + 3);
+ }
+ if (is_grid_end) {
+ GPU_indexbuf_add_line_verts(&elb_lines, vbo_index + 1, vbo_index + 3);
+ }
+
if (has_mask && show_mask) {
float fmask = (*CCG_elem_mask(key, elems[0]) +
*CCG_elem_mask(key, elems[1]) +
@@ -507,7 +586,6 @@ void GPU_pbvh_grid_buffers_update(
vbo_index += 1;
vbo_index_offset += 1;
}
-
vbo_index += 4;
}
}
@@ -515,6 +593,8 @@ void GPU_pbvh_grid_buffers_update(
}
}
+ buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
+
gpu_pbvh_batch_init(buffers, buffers->smooth ? GPU_PRIM_TRIS : GPU_PRIM_TRI_STRIP);
}
@@ -612,17 +692,12 @@ GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(
* Could be moved to the update function somehow. */
if (totquad == fully_visible_totquad) {
buffers->index_buf = gpu_get_grid_buffer(gridsize, &buffers->tot_quad, totgrid);
- buffers->has_hidden = false;
- buffers->is_index_buf_global = false;
}
else {
uint max_vert = totgrid * gridsize * gridsize;
buffers->tot_quad = totquad;
FILL_QUAD_BUFFER(max_vert, totquad, buffers->index_buf);
-
- buffers->has_hidden = false;
- buffers->is_index_buf_global = false;
}
return buffers;
@@ -630,6 +705,12 @@ GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(
#undef FILL_QUAD_BUFFER
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name BMesh PBVH
+ * \{ */
+
/* Output a BMVert into a VertexBufferFormat array
*
* The vertex is skipped if hidden, otherwise the output goes into
@@ -730,10 +811,15 @@ void GPU_pbvh_bmesh_buffers_update(
if (buffers->smooth) {
/* Smooth needs to recreate index buffer, so we have to invalidate the batch. */
GPU_BATCH_DISCARD_SAFE(buffers->triangles);
+ GPU_BATCH_DISCARD_SAFE(buffers->lines);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
/* Count visible vertices */
totvert = gpu_bmesh_vert_visible_count(bm_unique_verts, bm_other_verts);
}
else {
+ GPU_BATCH_DISCARD_SAFE(buffers->lines);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
totvert = tottri * 3;
}
@@ -774,6 +860,9 @@ void GPU_pbvh_bmesh_buffers_update(
else {
GSetIterator gs_iter;
+ GPUIndexBufBuilder elb_lines;
+ GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, totvert);
+
GSET_ITER (gs_iter, bm_faces) {
BMFace *f = BLI_gsetIterator_getKey(&gs_iter);
@@ -784,9 +873,6 @@ void GPU_pbvh_bmesh_buffers_update(
float fmask = 0.0f;
int i;
-#if 0
- BM_iter_as_array(bm, BM_VERTS_OF_FACE, f, (void **)v, 3);
-#endif
BM_face_as_array_vert_tri(f, v);
/* Average mask value */
@@ -795,6 +881,10 @@ void GPU_pbvh_bmesh_buffers_update(
}
fmask /= 3.0f;
+ GPU_indexbuf_add_line_verts(&elb_lines, v_index + 0, v_index + 1);
+ GPU_indexbuf_add_line_verts(&elb_lines, v_index + 1, v_index + 2);
+ GPU_indexbuf_add_line_verts(&elb_lines, v_index + 2, v_index + 0);
+
for (i = 0; i < 3; i++) {
gpu_bmesh_vert_to_buffer_copy__gwn(
v[i], buffers->vert_buf,
@@ -805,6 +895,7 @@ void GPU_pbvh_bmesh_buffers_update(
}
}
+ buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
buffers->tot_tri = tottri;
}
@@ -818,15 +909,11 @@ void GPU_pbvh_bmesh_buffers_update(
if (buffers->smooth) {
/* Fill the triangle buffer */
- buffers->index_buf = NULL;
- GPUIndexBufBuilder elb;
+ GPUIndexBufBuilder elb, elb_lines;
GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, maxvert);
-
- /* Initialize triangle index buffer */
- buffers->is_index_buf_global = false;
+ GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, maxvert);
/* Fill triangle index buffer */
-
{
GSetIterator gs_iter;
@@ -837,8 +924,13 @@ void GPU_pbvh_bmesh_buffers_update(
BMVert *v[3];
BM_face_as_array_vert_tri(f, v);
- GPU_indexbuf_add_tri_verts(
- &elb, BM_elem_index_get(v[0]), BM_elem_index_get(v[1]), BM_elem_index_get(v[2]));
+
+ uint idx[3] = {BM_elem_index_get(v[0]), BM_elem_index_get(v[1]), BM_elem_index_get(v[2])};
+ GPU_indexbuf_add_tri_verts(&elb, idx[0], idx[1], idx[2]);
+
+ GPU_indexbuf_add_line_verts(&elb_lines, idx[0], idx[1]);
+ GPU_indexbuf_add_line_verts(&elb_lines, idx[1], idx[2]);
+ GPU_indexbuf_add_line_verts(&elb_lines, idx[2], idx[0]);
}
}
@@ -850,21 +942,22 @@ void GPU_pbvh_bmesh_buffers_update(
else {
GPU_indexbuf_build_in_place(&elb, buffers->index_buf);
}
+
+ buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines);
}
}
- else if (buffers->index_buf) {
- if (!buffers->is_index_buf_global) {
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
- }
- buffers->index_buf = NULL;
- buffers->is_index_buf_global = false;
- }
buffers->show_mask = !empty_mask;
gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS);
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Generic
+ * \{ */
+
GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading)
{
GPU_PBVH_Buffers *buffers;
@@ -877,10 +970,16 @@ GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading)
return buffers;
}
-GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast)
+GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool wires)
{
- return (fast && buffers->triangles_fast) ?
- buffers->triangles_fast : buffers->triangles;
+ if (wires) {
+ return (fast && buffers->lines_fast) ?
+ buffers->lines_fast : buffers->lines;
+ }
+ else {
+ return (fast && buffers->triangles_fast) ?
+ buffers->triangles_fast : buffers->triangles;
+ }
}
bool GPU_pbvh_buffers_has_mask(GPU_PBVH_Buffers *buffers)
@@ -891,18 +990,26 @@ bool GPU_pbvh_buffers_has_mask(GPU_PBVH_Buffers *buffers)
void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers)
{
if (buffers) {
+ GPU_BATCH_DISCARD_SAFE(buffers->lines);
+ GPU_BATCH_DISCARD_SAFE(buffers->lines_fast);
GPU_BATCH_DISCARD_SAFE(buffers->triangles);
GPU_BATCH_DISCARD_SAFE(buffers->triangles_fast);
- if (!buffers->is_index_buf_global) {
- GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
- }
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf_fast);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_lines_buf);
GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf_fast);
+ GPU_INDEXBUF_DISCARD_SAFE(buffers->index_buf);
GPU_VERTBUF_DISCARD_SAFE(buffers->vert_buf);
MEM_freeN(buffers);
}
}
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Debug
+ * \{ */
+
/* debug function, draws the pbvh BB */
void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf, uint pos)
{
@@ -959,6 +1066,8 @@ void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf, uint pos)
immEnd();
}
+/** \} */
+
void GPU_pbvh_fix_linking()
{
}