diff options
-rw-r--r-- | source/blender/blenkernel/BKE_pbvh.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/pbvh.c | 10 | ||||
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager_data.c | 34 | ||||
-rw-r--r-- | source/blender/draw/modes/overlay_mode.c | 12 | ||||
-rw-r--r-- | source/blender/draw/modes/sculpt_mode.c | 2 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/overlay_face_wireframe_vert.glsl | 2 | ||||
-rw-r--r-- | source/blender/gpu/GPU_buffers.h | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_buffers.c | 249 |
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() { } |