diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-07-31 21:10:14 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-07-31 21:10:14 +0300 |
commit | 3667a5402e3d548073b4a9c031868dd0e55ed72f (patch) | |
tree | 4a2c35942477c8f24fba8735a89b94b7dbfa525e /source/blender/editors/mesh/editmesh_knife.c | |
parent | 6ba70d5996a4fdb82516d199dacfee066f2b3bfc (diff) |
KnifeTool: Use GPUBatch API instead of IMM to fix buffer overflow issue
This also include a small optimisation (remove of a double loop and half of
the memory allocation for hit points)
This should fix T55946 Crash using knife tool on mesh with large number of
vertices.
Tried with a 500K vert suzanne and it seems fine.
Diffstat (limited to 'source/blender/editors/mesh/editmesh_knife.c')
-rw-r--r-- | source/blender/editors/mesh/editmesh_knife.c | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 61f55451b17..c98aef74ae7 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1040,7 +1040,6 @@ static void knife_init_colors(KnifeColors *colors) static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *arg) { const KnifeTool_OpData *kcd = arg; - GPU_depth_test(false); glPolygonOffset(1.0f, 1.0f); @@ -1052,7 +1051,8 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void knifetool_draw_angle_snapping(kcd); } - uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + GPUVertFormat *format = immVertexFormat(); + uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); @@ -1113,40 +1113,43 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void if (kcd->totlinehit > 0) { KnifeLineHit *lh; - int i; + int i, v, vs; + float fcol[4]; GPU_blend(true); GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA); - /* draw any snapped verts first */ - immUniformColor4ubv(kcd->colors.point_a); - GPU_point_size(11); - - immBeginAtMost(GPU_PRIM_POINTS, kcd->totlinehit); + GPUVertBuf *vert = GPU_vertbuf_create_with_format(format); + GPU_vertbuf_data_alloc(vert, kcd->totlinehit); lh = kcd->linehits; - for (i = 0; i < kcd->totlinehit; i++, lh++) { + for (i = 0, v = 0, vs = kcd->totlinehit - 1; i < kcd->totlinehit; i++, lh++) { if (lh->v) { - immVertex3fv(pos, lh->cagehit); + GPU_vertbuf_attr_set(vert, pos, v++, lh->cagehit); + } + else { + GPU_vertbuf_attr_set(vert, pos, vs--, lh->cagehit); } } - immEnd(); + GPUBatch *batch = GPU_batch_create_ex(GPU_PRIM_POINTS, vert, NULL, GPU_BATCH_OWNS_VBO); + GPU_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR); + + /* draw any snapped verts first */ + rgba_uchar_to_float(fcol, kcd->colors.point_a); + GPU_batch_uniform_4fv(batch, "color", fcol); + GPU_matrix_bind(batch->interface); + GPU_point_size(11); + GPU_batch_draw_range_ex(batch, 0, v - 1, false); /* now draw the rest */ - immUniformColor4ubv(kcd->colors.curpoint_a); + rgba_uchar_to_float(fcol, kcd->colors.curpoint_a); + GPU_batch_uniform_4fv(batch, "color", fcol); GPU_point_size(7); + GPU_batch_draw_range_ex(batch, vs + 1, kcd->totlinehit - (vs + 1), false); - immBeginAtMost(GPU_PRIM_POINTS, kcd->totlinehit); - - lh = kcd->linehits; - for (i = 0; i < kcd->totlinehit; i++, lh++) { - if (!lh->v) { - immVertex3fv(pos, lh->cagehit); - } - } - - immEnd(); + GPU_batch_program_use_end(batch); + GPU_batch_discard(batch); GPU_blend(false); } @@ -1158,7 +1161,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.line); GPU_line_width(1.0); - immBeginAtMost(GPU_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2); + GPUBatch *batch = immBeginBatchAtMost(GPU_PRIM_LINES, BLI_mempool_len(kcd->kedges) * 2); BLI_mempool_iternew(kcd->kedges, &iter); for (kfe = BLI_mempool_iterstep(&iter); kfe; kfe = BLI_mempool_iterstep(&iter)) { @@ -1170,6 +1173,9 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void } immEnd(); + + GPU_batch_draw(batch); + GPU_batch_discard(batch); } if (kcd->totkvert > 0) { @@ -1179,7 +1185,7 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void immUniformColor3ubv(kcd->colors.point); GPU_point_size(5.0); - immBeginAtMost(GPU_PRIM_POINTS, BLI_mempool_len(kcd->kverts)); + GPUBatch *batch = immBeginBatchAtMost(GPU_PRIM_POINTS, BLI_mempool_len(kcd->kverts)); BLI_mempool_iternew(kcd->kverts, &iter); for (kfv = BLI_mempool_iterstep(&iter); kfv; kfv = BLI_mempool_iterstep(&iter)) { @@ -1190,6 +1196,9 @@ static void knifetool_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void } immEnd(); + + GPU_batch_draw(batch); + GPU_batch_discard(batch); } immUnbindProgram(); |