From e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Apr 2019 06:17:24 +0200 Subject: ClangFormat: apply to source, most of intern Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat --- source/blender/gpu/intern/gpu_buffers.c | 1801 +++++++++++++++---------------- 1 file changed, 900 insertions(+), 901 deletions(-) (limited to 'source/blender/gpu/intern/gpu_buffers.c') diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index edf5eb7e7d1..0b5b2e469a0 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -53,45 +53,45 @@ * drawing and doesn't interact at all with the buffer code above */ struct GPU_PBVH_Buffers { - GPUIndexBuf *index_buf, *index_buf_fast; - GPUIndexBuf *index_lines_buf, *index_lines_buf_fast; - GPUVertBuf *vert_buf; + 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; + GPUBatch *lines; + GPUBatch *lines_fast; + GPUBatch *triangles; + GPUBatch *triangles_fast; - /* mesh pointers in case buffer allocation fails */ - const MPoly *mpoly; - const MLoop *mloop; - const MLoopTri *looptri; - const MVert *mvert; + /* mesh pointers in case buffer allocation fails */ + const MPoly *mpoly; + const MLoop *mloop; + const MLoopTri *looptri; + const MVert *mvert; - const int *face_indices; - int face_indices_len; + const int *face_indices; + int face_indices_len; - /* grid pointers */ - CCGKey gridkey; - CCGElem **grids; - const DMFlagMat *grid_flag_mats; - BLI_bitmap * const *grid_hidden; - const int *grid_indices; - int totgrid; + /* grid pointers */ + CCGKey gridkey; + CCGElem **grids; + const DMFlagMat *grid_flag_mats; + BLI_bitmap *const *grid_hidden; + const int *grid_indices; + int totgrid; - bool use_bmesh; + bool use_bmesh; - uint tot_tri, tot_quad; + uint tot_tri, tot_quad; - /* The PBVH ensures that either all faces in the node are - * smooth-shaded or all faces are flat-shaded */ - bool smooth; + /* The PBVH ensures that either all faces in the node are + * smooth-shaded or all faces are flat-shaded */ + bool smooth; - bool show_mask; + bool show_mask; }; static struct { - uint pos, nor, msk; + uint pos, nor, msk; } g_vbo_id = {0}; /** \} */ @@ -104,916 +104,915 @@ static struct { * 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) { - if (buffers->vert_buf == NULL) { - /* Initialize vertex buffer */ - /* match 'VertexBufferFormat' */ - - static GPUVertFormat format = {0}; - if (format.attr_len == 0) { - g_vbo_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); - g_vbo_id.nor = GPU_vertformat_attr_add(&format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); - g_vbo_id.msk = GPU_vertformat_attr_add(&format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); - } + if (buffers->vert_buf == NULL) { + /* Initialize vertex buffer */ + /* match 'VertexBufferFormat' */ + + static GPUVertFormat format = {0}; + if (format.attr_len == 0) { + g_vbo_id.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); + g_vbo_id.nor = GPU_vertformat_attr_add( + &format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); + g_vbo_id.msk = GPU_vertformat_attr_add(&format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); + } #if 0 - buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_DYNAMIC); - GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len); - } - else if (vert_len != buffers->vert_buf->vertex_len) { - GPU_vertbuf_data_resize(buffers->vert_buf, vert_len); - } + buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_DYNAMIC); + GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len); + } + else if (vert_len != buffers->vert_buf->vertex_len) { + GPU_vertbuf_data_resize(buffers->vert_buf, vert_len); + } #else - buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC); - } - GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len); + buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC); + } + GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len); #endif - return buffers->vert_buf->data != NULL; -} - -static void gpu_pbvh_batch_init(GPU_PBVH_Buffers *buffers, GPUPrimType prim) -{ - /* force flushing to the GPU */ - if (buffers->vert_buf->data) { - GPU_vertbuf_use(buffers->vert_buf); - } - - if (buffers->triangles == NULL) { - buffers->triangles = GPU_batch_create( - prim, buffers->vert_buf, - /* can be NULL */ - buffers->index_buf); - } - - if ((buffers->triangles_fast == NULL) && buffers->index_buf_fast) { - buffers->triangles_fast = GPU_batch_create( - 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 + return buffers->vert_buf->data != NULL; + } + + static void gpu_pbvh_batch_init(GPU_PBVH_Buffers * buffers, GPUPrimType prim) + { + /* force flushing to the GPU */ + if (buffers->vert_buf->data) { + GPU_vertbuf_use(buffers->vert_buf); + } + + if (buffers->triangles == NULL) { + buffers->triangles = GPU_batch_create(prim, + buffers->vert_buf, + /* can be NULL */ + buffers->index_buf); + } + + if ((buffers->triangles_fast == NULL) && buffers->index_buf_fast) { + buffers->triangles_fast = GPU_batch_create(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, - const int (*face_vert_indices)[3], - const int update_flags) -{ - const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; - bool empty_mask = true; - - { - int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3)); - - /* Build VBO */ - if (gpu_pbvh_vert_buf_data_set(buffers, totelem)) { - /* Vertex data is shared if smooth-shaded, but separate - * copies are made for flat shading because normals - * shouldn't be shared. */ - if (buffers->smooth) { - for (uint i = 0; i < totvert; ++i) { - const MVert *v = &mvert[vert_indices[i]]; - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, i, v->co); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, i, v->no); - } - - if (vmask && show_mask) { - for (uint i = 0; i < buffers->face_indices_len; i++) { - const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]]; - for (uint j = 0; j < 3; j++) { - int vidx = face_vert_indices[i][j]; - int v_index = buffers->mloop[lt->tri[j]].v; - float fmask = vmask[v_index]; - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vidx, &fmask); - empty_mask = empty_mask && (fmask == 0.0f); - } - } - } - } - else { - /* calculate normal for each polygon only once */ - uint mpoly_prev = UINT_MAX; - short no[3]; - int vbo_index = 0; - - for (uint i = 0; i < buffers->face_indices_len; i++) { - const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]]; - const uint vtri[3] = { - buffers->mloop[lt->tri[0]].v, - buffers->mloop[lt->tri[1]].v, - buffers->mloop[lt->tri[2]].v, - }; - - if (paint_is_face_hidden(lt, mvert, buffers->mloop)) - continue; - - /* Face normal and mask */ - if (lt->poly != mpoly_prev) { - const MPoly *mp = &buffers->mpoly[lt->poly]; - float fno[3]; - BKE_mesh_calc_poly_normal(mp, &buffers->mloop[mp->loopstart], mvert, fno); - normal_float_to_short_v3(no, fno); - mpoly_prev = lt->poly; - } - - float fmask = 0.0f; - if (vmask && show_mask) { - fmask = (vmask[vtri[0]] + vmask[vtri[1]] + vmask[vtri[2]]) / 3.0f; - } - - for (uint j = 0; j < 3; j++) { - const MVert *v = &mvert[vtri[j]]; - - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, v->co); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); - - vbo_index++; - } - - empty_mask = empty_mask && (fmask == 0.0f); - } - } - - gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); - } - } - - buffers->show_mask = !empty_mask; - buffers->mvert = mvert; -} - -GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build( - const int (*face_vert_indices)[3], - const MPoly *mpoly, const MLoop *mloop, const MLoopTri *looptri, - const MVert *mvert, - const int *face_indices, - const int face_indices_len) -{ - GPU_PBVH_Buffers *buffers; - int i, tottri; - - buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers"); - - /* smooth or flat for all */ - buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH; - - buffers->show_mask = false; - - /* Count the number of visible triangles */ - for (i = 0, tottri = 0; i < face_indices_len; ++i) { - const MLoopTri *lt = &looptri[face_indices[i]]; - if (!paint_is_face_hidden(lt, mvert, mloop)) - tottri++; - } - - if (tottri == 0) { - buffers->tot_tri = 0; - - buffers->mpoly = mpoly; - buffers->mloop = mloop; - buffers->looptri = looptri; - buffers->face_indices = face_indices; - buffers->face_indices_len = 0; - - 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 - * can't be used there. */ - if (buffers->smooth) { - /* 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]]; - - /* Skip hidden faces */ - if (paint_is_face_hidden(lt, mvert, mloop)) - 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 { - /* 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_lines_buf = GPU_indexbuf_build(&elb_lines); - } - - buffers->tot_tri = tottri; - - buffers->mpoly = mpoly; - buffers->mloop = mloop; - buffers->looptri = looptri; - - buffers->face_indices = face_indices; - buffers->face_indices_len = face_indices_len; - - return buffers; -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Grid PBVH + void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers * buffers, + const MVert *mvert, + const int *vert_indices, + int totvert, + const float *vmask, + const int(*face_vert_indices)[3], + const int update_flags) + { + const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; + bool empty_mask = true; + + { + int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3)); + + /* Build VBO */ + if (gpu_pbvh_vert_buf_data_set(buffers, totelem)) { + /* Vertex data is shared if smooth-shaded, but separate + * copies are made for flat shading because normals + * shouldn't be shared. */ + if (buffers->smooth) { + for (uint i = 0; i < totvert; ++i) { + const MVert *v = &mvert[vert_indices[i]]; + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, i, v->co); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, i, v->no); + } + + if (vmask && show_mask) { + for (uint i = 0; i < buffers->face_indices_len; i++) { + const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]]; + for (uint j = 0; j < 3; j++) { + int vidx = face_vert_indices[i][j]; + int v_index = buffers->mloop[lt->tri[j]].v; + float fmask = vmask[v_index]; + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vidx, &fmask); + empty_mask = empty_mask && (fmask == 0.0f); + } + } + } + } + else { + /* calculate normal for each polygon only once */ + uint mpoly_prev = UINT_MAX; + short no[3]; + int vbo_index = 0; + + for (uint i = 0; i < buffers->face_indices_len; i++) { + const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]]; + const uint vtri[3] = { + buffers->mloop[lt->tri[0]].v, + buffers->mloop[lt->tri[1]].v, + buffers->mloop[lt->tri[2]].v, + }; + + if (paint_is_face_hidden(lt, mvert, buffers->mloop)) + continue; + + /* Face normal and mask */ + if (lt->poly != mpoly_prev) { + const MPoly *mp = &buffers->mpoly[lt->poly]; + float fno[3]; + BKE_mesh_calc_poly_normal(mp, &buffers->mloop[mp->loopstart], mvert, fno); + normal_float_to_short_v3(no, fno); + mpoly_prev = lt->poly; + } + + float fmask = 0.0f; + if (vmask && show_mask) { + fmask = (vmask[vtri[0]] + vmask[vtri[1]] + vmask[vtri[2]]) / 3.0f; + } + + for (uint j = 0; j < 3; j++) { + const MVert *v = &mvert[vtri[j]]; + + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, v->co); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); + + vbo_index++; + } + + empty_mask = empty_mask && (fmask == 0.0f); + } + } + + gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); + } + } + + buffers->show_mask = !empty_mask; + buffers->mvert = mvert; + } + + GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(const int(*face_vert_indices)[3], + const MPoly *mpoly, + const MLoop *mloop, + const MLoopTri *looptri, + const MVert *mvert, + const int *face_indices, + const int face_indices_len) + { + GPU_PBVH_Buffers *buffers; + int i, tottri; + + buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers"); + + /* smooth or flat for all */ + buffers->smooth = mpoly[looptri[face_indices[0]].poly].flag & ME_SMOOTH; + + buffers->show_mask = false; + + /* Count the number of visible triangles */ + for (i = 0, tottri = 0; i < face_indices_len; ++i) { + const MLoopTri *lt = &looptri[face_indices[i]]; + if (!paint_is_face_hidden(lt, mvert, mloop)) + tottri++; + } + + if (tottri == 0) { + buffers->tot_tri = 0; + + buffers->mpoly = mpoly; + buffers->mloop = mloop; + buffers->looptri = looptri; + buffers->face_indices = face_indices; + buffers->face_indices_len = 0; + + 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 + * can't be used there. */ + if (buffers->smooth) { + /* 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]]; + + /* Skip hidden faces */ + if (paint_is_face_hidden(lt, mvert, mloop)) + 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 { + /* 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_lines_buf = GPU_indexbuf_build(&elb_lines); + } + + buffers->tot_tri = tottri; + + buffers->mpoly = mpoly; + buffers->mloop = mloop; + buffers->looptri = looptri; + + buffers->face_indices = face_indices; + buffers->face_indices_len = face_indices_len; + + return buffers; + } + + /** \} */ + + /* -------------------------------------------------------------------- */ + /** \name Grid PBVH * \{ */ -static void gpu_pbvh_grid_fill_index_buffers( - GPU_PBVH_Buffers *buffers, - int *grid_indices, - uint visible_quad_len, - int totgrid, - int gridsize) -{ - GPUIndexBufBuilder elb, elb_lines; - GPUIndexBufBuilder elb_fast, elb_lines_fast; - - GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 2 * visible_quad_len, INT_MAX); - GPU_indexbuf_init(&elb_fast, GPU_PRIM_TRIS, 2 * totgrid, INT_MAX); - GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, 2 * totgrid * gridsize * (gridsize - 1), INT_MAX); - GPU_indexbuf_init(&elb_lines_fast, GPU_PRIM_LINES, 4 * totgrid, INT_MAX); - - if (buffers->smooth) { - uint offset = 0; - const uint grid_vert_len = gridsize * gridsize; - for (int i = 0; i < totgrid; i++, offset += grid_vert_len) { - uint v0, v1, v2, v3; - bool grid_visible = false; - - BLI_bitmap *gh = buffers->grid_hidden[grid_indices[i]]; - - for (int j = 0; j < gridsize - 1; ++j) { - for (int k = 0; k < gridsize - 1; ++k) { - /* Skip hidden grid face */ - if (gh && paint_is_grid_face_hidden( - gh, gridsize, k, j)) - { - continue; - } - /* Indices in a Clockwise QUAD disposition. */ - v0 = offset + j * gridsize + k; - v1 = v0 + 1; - v2 = v1 + gridsize; - v3 = v2 - 1; - - GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1); - GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2); - - GPU_indexbuf_add_line_verts(&elb_lines, v0, v1); - GPU_indexbuf_add_line_verts(&elb_lines, v0, v3); - - if (j + 2 == gridsize) { - GPU_indexbuf_add_line_verts(&elb_lines, v2, v3); - } - grid_visible = true; - } - GPU_indexbuf_add_line_verts(&elb_lines, v1, v2); - } - - if (grid_visible) { - /* Grid corners */ - v0 = offset; - v1 = offset + gridsize - 1; - v2 = offset + grid_vert_len - 1; - v3 = offset + grid_vert_len - gridsize; - - GPU_indexbuf_add_tri_verts(&elb_fast, v0, v2, v1); - GPU_indexbuf_add_tri_verts(&elb_fast, v0, v3, v2); - - GPU_indexbuf_add_line_verts(&elb_lines_fast, v0, v1); - GPU_indexbuf_add_line_verts(&elb_lines_fast, v1, v2); - GPU_indexbuf_add_line_verts(&elb_lines_fast, v2, v3); - GPU_indexbuf_add_line_verts(&elb_lines_fast, v3, v0); - } - } - } - else { - uint offset = 0; - const uint grid_vert_len = SQUARE(gridsize - 1) * 4; - for (int i = 0; i < totgrid; i++, offset += grid_vert_len) { - bool grid_visible = false; - - BLI_bitmap *gh = buffers->grid_hidden[grid_indices[i]]; - - uint v0, v1, v2, v3; - for (int j = 0; j < gridsize - 1; j++) { - for (int k = 0; k < gridsize - 1; k++) { - /* Skip hidden grid face */ - if (gh && paint_is_grid_face_hidden( - gh, gridsize, k, j)) - { - continue; - } - /* VBO data are in a Clockwise QUAD disposition. */ - v0 = offset + (j * (gridsize - 1) + k) * 4; - v1 = v0 + 1; - v2 = v0 + 2; - v3 = v0 + 3; - - GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1); - GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2); - - GPU_indexbuf_add_line_verts(&elb_lines, v0, v1); - GPU_indexbuf_add_line_verts(&elb_lines, v0, v3); - - if (j + 2 == gridsize) { - GPU_indexbuf_add_line_verts(&elb_lines, v2, v3); - } - grid_visible = true; - } - GPU_indexbuf_add_line_verts(&elb_lines, v1, v2); - } - - if (grid_visible) { - /* Grid corners */ - v0 = offset; - v1 = offset + (gridsize - 1) * 4 - 3; - v2 = offset + grid_vert_len - 2; - v3 = offset + grid_vert_len - (gridsize - 1) * 4 + 3; - - GPU_indexbuf_add_tri_verts(&elb_fast, v0, v2, v1); - GPU_indexbuf_add_tri_verts(&elb_fast, v0, v3, v2); - - GPU_indexbuf_add_line_verts(&elb_lines_fast, v0, v1); - GPU_indexbuf_add_line_verts(&elb_lines_fast, v1, v2); - GPU_indexbuf_add_line_verts(&elb_lines_fast, v2, v3); - GPU_indexbuf_add_line_verts(&elb_lines_fast, v3, v0); - } - } - } - - buffers->index_buf = GPU_indexbuf_build(&elb); - buffers->index_buf_fast = GPU_indexbuf_build(&elb_fast); - buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines); - buffers->index_lines_buf_fast = GPU_indexbuf_build(&elb_lines_fast); -} - -void GPU_pbvh_grid_buffers_update( - GPU_PBVH_Buffers *buffers, CCGElem **grids, - const DMFlagMat *grid_flag_mats, int *grid_indices, - int totgrid, const CCGKey *key, - const int update_flags) -{ - const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; - bool empty_mask = true; - int i, j, k, x, y; - - const bool smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH; - - /* Build VBO */ - const int has_mask = key->has_mask; - - uint vert_per_grid = (smooth) ? key->grid_area : (SQUARE(key->grid_size - 1) * 4); - uint vert_count = totgrid * vert_per_grid; - - if (buffers->smooth != smooth) { - buffers->smooth = smooth; - 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 == NULL) { - uint visible_quad_len = BKE_pbvh_count_grid_quads((BLI_bitmap **)buffers->grid_hidden, - grid_indices, - totgrid, - key->grid_size); - - /* totally hidden node, return here to avoid BufferData with zero below. */ - if (visible_quad_len == 0) { - return; - } - - gpu_pbvh_grid_fill_index_buffers(buffers, grid_indices, visible_quad_len, totgrid, key->grid_size); - } - - uint vbo_index_offset = 0; - /* Build VBO */ - if (gpu_pbvh_vert_buf_data_set(buffers, vert_count)) { - GPUIndexBufBuilder elb_lines; - - if (buffers->index_lines_buf == NULL) { - 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; - - if (buffers->smooth) { - for (y = 0; y < key->grid_size; y++) { - for (x = 0; x < key->grid_size; x++) { - CCGElem *elem = CCG_grid_elem(key, grid, x, y); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index, CCG_elem_co(key, elem)); - - short no_short[3]; - normal_float_to_short_v3(no_short, CCG_elem_no(key, elem)); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short); - - if (has_mask && show_mask) { - float fmask = *CCG_elem_mask(key, elem); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); - empty_mask = empty_mask && (fmask == 0.0f); - } - vbo_index += 1; - } - } - vbo_index_offset += key->grid_area; - } - else { - for (j = 0; j < key->grid_size - 1; j++) { - for (k = 0; k < key->grid_size - 1; k++) { - CCGElem *elems[4] = { - CCG_grid_elem(key, grid, k, j), - CCG_grid_elem(key, grid, k + 1, j), - CCG_grid_elem(key, grid, k + 1, j + 1), - CCG_grid_elem(key, grid, k, j + 1), - }; - float *co[4] = { - CCG_elem_co(key, elems[0]), - CCG_elem_co(key, elems[1]), - CCG_elem_co(key, elems[2]), - CCG_elem_co(key, elems[3]), - }; - - float fno[3]; - short no_short[3]; - /* Note: Clockwise indices ordering, that's why we invert order here. */ - normal_quad_v3(fno, co[3], co[2], co[1], co[0]); - normal_float_to_short_v3(no_short, fno); - - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 0, co[0]); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 0, no_short); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 1, co[1]); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 1, no_short); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 2, co[2]); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 2, no_short); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 3, co[3]); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 3, no_short); - - if (has_mask && show_mask) { - float fmask = (*CCG_elem_mask(key, elems[0]) + - *CCG_elem_mask(key, elems[1]) + - *CCG_elem_mask(key, elems[2]) + - *CCG_elem_mask(key, elems[3])) * 0.25f; - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 0, &fmask); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 1, &fmask); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 2, &fmask); - GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 3, &fmask); - empty_mask = empty_mask && (fmask == 0.0f); - } - vbo_index += 4; - } - } - vbo_index_offset += SQUARE(key->grid_size - 1) * 4; - } - } - - gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); - } - - buffers->grids = grids; - buffers->grid_indices = grid_indices; - buffers->totgrid = totgrid; - buffers->grid_flag_mats = grid_flag_mats; - buffers->gridkey = *key; - buffers->show_mask = !empty_mask; - - //printf("node updated %p\n", buffers); -} - -GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build( - int totgrid, - BLI_bitmap **grid_hidden) -{ - GPU_PBVH_Buffers *buffers; - - buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers"); - buffers->grid_hidden = grid_hidden; - buffers->totgrid = totgrid; - - buffers->show_mask = false; - - return buffers; -} + static void gpu_pbvh_grid_fill_index_buffers(GPU_PBVH_Buffers * buffers, + int *grid_indices, + uint visible_quad_len, + int totgrid, + int gridsize) + { + GPUIndexBufBuilder elb, elb_lines; + GPUIndexBufBuilder elb_fast, elb_lines_fast; + + GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, 2 * visible_quad_len, INT_MAX); + GPU_indexbuf_init(&elb_fast, GPU_PRIM_TRIS, 2 * totgrid, INT_MAX); + GPU_indexbuf_init( + &elb_lines, GPU_PRIM_LINES, 2 * totgrid * gridsize * (gridsize - 1), INT_MAX); + GPU_indexbuf_init(&elb_lines_fast, GPU_PRIM_LINES, 4 * totgrid, INT_MAX); + + if (buffers->smooth) { + uint offset = 0; + const uint grid_vert_len = gridsize * gridsize; + for (int i = 0; i < totgrid; i++, offset += grid_vert_len) { + uint v0, v1, v2, v3; + bool grid_visible = false; + + BLI_bitmap *gh = buffers->grid_hidden[grid_indices[i]]; + + for (int j = 0; j < gridsize - 1; ++j) { + for (int k = 0; k < gridsize - 1; ++k) { + /* Skip hidden grid face */ + if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) { + continue; + } + /* Indices in a Clockwise QUAD disposition. */ + v0 = offset + j * gridsize + k; + v1 = v0 + 1; + v2 = v1 + gridsize; + v3 = v2 - 1; + + GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1); + GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2); + + GPU_indexbuf_add_line_verts(&elb_lines, v0, v1); + GPU_indexbuf_add_line_verts(&elb_lines, v0, v3); + + if (j + 2 == gridsize) { + GPU_indexbuf_add_line_verts(&elb_lines, v2, v3); + } + grid_visible = true; + } + GPU_indexbuf_add_line_verts(&elb_lines, v1, v2); + } + + if (grid_visible) { + /* Grid corners */ + v0 = offset; + v1 = offset + gridsize - 1; + v2 = offset + grid_vert_len - 1; + v3 = offset + grid_vert_len - gridsize; + + GPU_indexbuf_add_tri_verts(&elb_fast, v0, v2, v1); + GPU_indexbuf_add_tri_verts(&elb_fast, v0, v3, v2); + + GPU_indexbuf_add_line_verts(&elb_lines_fast, v0, v1); + GPU_indexbuf_add_line_verts(&elb_lines_fast, v1, v2); + GPU_indexbuf_add_line_verts(&elb_lines_fast, v2, v3); + GPU_indexbuf_add_line_verts(&elb_lines_fast, v3, v0); + } + } + } + else { + uint offset = 0; + const uint grid_vert_len = SQUARE(gridsize - 1) * 4; + for (int i = 0; i < totgrid; i++, offset += grid_vert_len) { + bool grid_visible = false; + + BLI_bitmap *gh = buffers->grid_hidden[grid_indices[i]]; + + uint v0, v1, v2, v3; + for (int j = 0; j < gridsize - 1; j++) { + for (int k = 0; k < gridsize - 1; k++) { + /* Skip hidden grid face */ + if (gh && paint_is_grid_face_hidden(gh, gridsize, k, j)) { + continue; + } + /* VBO data are in a Clockwise QUAD disposition. */ + v0 = offset + (j * (gridsize - 1) + k) * 4; + v1 = v0 + 1; + v2 = v0 + 2; + v3 = v0 + 3; + + GPU_indexbuf_add_tri_verts(&elb, v0, v2, v1); + GPU_indexbuf_add_tri_verts(&elb, v0, v3, v2); + + GPU_indexbuf_add_line_verts(&elb_lines, v0, v1); + GPU_indexbuf_add_line_verts(&elb_lines, v0, v3); + + if (j + 2 == gridsize) { + GPU_indexbuf_add_line_verts(&elb_lines, v2, v3); + } + grid_visible = true; + } + GPU_indexbuf_add_line_verts(&elb_lines, v1, v2); + } + + if (grid_visible) { + /* Grid corners */ + v0 = offset; + v1 = offset + (gridsize - 1) * 4 - 3; + v2 = offset + grid_vert_len - 2; + v3 = offset + grid_vert_len - (gridsize - 1) * 4 + 3; + + GPU_indexbuf_add_tri_verts(&elb_fast, v0, v2, v1); + GPU_indexbuf_add_tri_verts(&elb_fast, v0, v3, v2); + + GPU_indexbuf_add_line_verts(&elb_lines_fast, v0, v1); + GPU_indexbuf_add_line_verts(&elb_lines_fast, v1, v2); + GPU_indexbuf_add_line_verts(&elb_lines_fast, v2, v3); + GPU_indexbuf_add_line_verts(&elb_lines_fast, v3, v0); + } + } + } + + buffers->index_buf = GPU_indexbuf_build(&elb); + buffers->index_buf_fast = GPU_indexbuf_build(&elb_fast); + buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines); + buffers->index_lines_buf_fast = GPU_indexbuf_build(&elb_lines_fast); + } + + void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers * buffers, + CCGElem * *grids, + const DMFlagMat *grid_flag_mats, + int *grid_indices, + int totgrid, + const CCGKey *key, + const int update_flags) + { + const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; + bool empty_mask = true; + int i, j, k, x, y; + + const bool smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH; + + /* Build VBO */ + const int has_mask = key->has_mask; + + uint vert_per_grid = (smooth) ? key->grid_area : (SQUARE(key->grid_size - 1) * 4); + uint vert_count = totgrid * vert_per_grid; + + if (buffers->smooth != smooth) { + buffers->smooth = smooth; + 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 == NULL) { + uint visible_quad_len = BKE_pbvh_count_grid_quads( + (BLI_bitmap **)buffers->grid_hidden, grid_indices, totgrid, key->grid_size); + + /* totally hidden node, return here to avoid BufferData with zero below. */ + if (visible_quad_len == 0) { + return; + } + + gpu_pbvh_grid_fill_index_buffers( + buffers, grid_indices, visible_quad_len, totgrid, key->grid_size); + } + + uint vbo_index_offset = 0; + /* Build VBO */ + if (gpu_pbvh_vert_buf_data_set(buffers, vert_count)) { + GPUIndexBufBuilder elb_lines; + + if (buffers->index_lines_buf == NULL) { + 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; + + if (buffers->smooth) { + for (y = 0; y < key->grid_size; y++) { + for (x = 0; x < key->grid_size; x++) { + CCGElem *elem = CCG_grid_elem(key, grid, x, y); + GPU_vertbuf_attr_set( + buffers->vert_buf, g_vbo_id.pos, vbo_index, CCG_elem_co(key, elem)); + + short no_short[3]; + normal_float_to_short_v3(no_short, CCG_elem_no(key, elem)); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short); + + if (has_mask && show_mask) { + float fmask = *CCG_elem_mask(key, elem); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); + empty_mask = empty_mask && (fmask == 0.0f); + } + vbo_index += 1; + } + } + vbo_index_offset += key->grid_area; + } + else { + for (j = 0; j < key->grid_size - 1; j++) { + for (k = 0; k < key->grid_size - 1; k++) { + CCGElem *elems[4] = { + CCG_grid_elem(key, grid, k, j), + CCG_grid_elem(key, grid, k + 1, j), + CCG_grid_elem(key, grid, k + 1, j + 1), + CCG_grid_elem(key, grid, k, j + 1), + }; + float *co[4] = { + CCG_elem_co(key, elems[0]), + CCG_elem_co(key, elems[1]), + CCG_elem_co(key, elems[2]), + CCG_elem_co(key, elems[3]), + }; + + float fno[3]; + short no_short[3]; + /* Note: Clockwise indices ordering, that's why we invert order here. */ + normal_quad_v3(fno, co[3], co[2], co[1], co[0]); + normal_float_to_short_v3(no_short, fno); + + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 0, co[0]); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 0, no_short); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 1, co[1]); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 1, no_short); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 2, co[2]); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 2, no_short); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, vbo_index + 3, co[3]); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index + 3, no_short); + + if (has_mask && show_mask) { + float fmask = (*CCG_elem_mask(key, elems[0]) + *CCG_elem_mask(key, elems[1]) + + *CCG_elem_mask(key, elems[2]) + *CCG_elem_mask(key, elems[3])) * + 0.25f; + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 0, &fmask); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 1, &fmask); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 2, &fmask); + GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 3, &fmask); + empty_mask = empty_mask && (fmask == 0.0f); + } + vbo_index += 4; + } + } + vbo_index_offset += SQUARE(key->grid_size - 1) * 4; + } + } + + gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); + } + + buffers->grids = grids; + buffers->grid_indices = grid_indices; + buffers->totgrid = totgrid; + buffers->grid_flag_mats = grid_flag_mats; + buffers->gridkey = *key; + buffers->show_mask = !empty_mask; + + //printf("node updated %p\n", buffers); + } + + GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, BLI_bitmap **grid_hidden) + { + GPU_PBVH_Buffers *buffers; + + buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers"); + buffers->grid_hidden = grid_hidden; + buffers->totgrid = totgrid; + + buffers->show_mask = false; + + return buffers; + } #undef FILL_QUAD_BUFFER -/** \} */ + /** \} */ -/* -------------------------------------------------------------------- */ -/** \name BMesh PBVH + /* -------------------------------------------------------------------- */ + /** \name BMesh PBVH * \{ */ -/* Output a BMVert into a VertexBufferFormat array + /* Output a BMVert into a VertexBufferFormat array * * The vertex is skipped if hidden, otherwise the output goes into * index '*v_index' in the 'vert_data' array and '*v_index' is * incremented. */ -static void gpu_bmesh_vert_to_buffer_copy__gwn( - BMVert *v, - GPUVertBuf *vert_buf, - int *v_index, - const float fno[3], - const float *fmask, - const int cd_vert_mask_offset, - const bool show_mask, - bool *empty_mask) -{ - if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { - - /* Set coord, normal, and mask */ - GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, *v_index, v->co); - - short no_short[3]; - normal_float_to_short_v3(no_short, fno ? fno : v->no); - GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, *v_index, no_short); - - if (show_mask) { - float effective_mask = fmask ? *fmask - : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset); - GPU_vertbuf_attr_set(vert_buf, g_vbo_id.msk, *v_index, &effective_mask); - *empty_mask = *empty_mask && (effective_mask == 0.0f); - } - - /* Assign index for use in the triangle index buffer */ - /* note: caller must set: bm->elem_index_dirty |= BM_VERT; */ - BM_elem_index_set(v, (*v_index)); /* set_dirty! */ - - (*v_index)++; - } -} - -/* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */ -static int gpu_bmesh_vert_visible_count(GSet *bm_unique_verts, - GSet *bm_other_verts) -{ - GSetIterator gs_iter; - int totvert = 0; - - GSET_ITER (gs_iter, bm_unique_verts) { - BMVert *v = BLI_gsetIterator_getKey(&gs_iter); - if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) - totvert++; - } - GSET_ITER (gs_iter, bm_other_verts) { - BMVert *v = BLI_gsetIterator_getKey(&gs_iter); - if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) - totvert++; - } - - return totvert; -} - -/* Return the total number of visible faces */ -static int gpu_bmesh_face_visible_count(GSet *bm_faces) -{ - GSetIterator gh_iter; - int totface = 0; - - GSET_ITER (gh_iter, bm_faces) { - BMFace *f = BLI_gsetIterator_getKey(&gh_iter); - - if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) - totface++; - } - - return totface; -} - -/* Creates a vertex buffer (coordinate, normal, color) and, if smooth + static void gpu_bmesh_vert_to_buffer_copy__gwn(BMVert * v, + GPUVertBuf * vert_buf, + int *v_index, + const float fno[3], + const float *fmask, + const int cd_vert_mask_offset, + const bool show_mask, + bool *empty_mask) + { + if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { + + /* Set coord, normal, and mask */ + GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, *v_index, v->co); + + short no_short[3]; + normal_float_to_short_v3(no_short, fno ? fno : v->no); + GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, *v_index, no_short); + + if (show_mask) { + float effective_mask = fmask ? *fmask : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset); + GPU_vertbuf_attr_set(vert_buf, g_vbo_id.msk, *v_index, &effective_mask); + *empty_mask = *empty_mask && (effective_mask == 0.0f); + } + + /* Assign index for use in the triangle index buffer */ + /* note: caller must set: bm->elem_index_dirty |= BM_VERT; */ + BM_elem_index_set(v, (*v_index)); /* set_dirty! */ + + (*v_index)++; + } + } + + /* Return the total number of vertices that don't have BM_ELEM_HIDDEN set */ + static int gpu_bmesh_vert_visible_count(GSet * bm_unique_verts, GSet * bm_other_verts) + { + GSetIterator gs_iter; + int totvert = 0; + + GSET_ITER (gs_iter, bm_unique_verts) { + BMVert *v = BLI_gsetIterator_getKey(&gs_iter); + if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) + totvert++; + } + GSET_ITER (gs_iter, bm_other_verts) { + BMVert *v = BLI_gsetIterator_getKey(&gs_iter); + if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) + totvert++; + } + + return totvert; + } + + /* Return the total number of visible faces */ + static int gpu_bmesh_face_visible_count(GSet * bm_faces) + { + GSetIterator gh_iter; + int totface = 0; + + GSET_ITER (gh_iter, bm_faces) { + BMFace *f = BLI_gsetIterator_getKey(&gh_iter); + + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) + totface++; + } + + return totface; + } + + /* Creates a vertex buffer (coordinate, normal, color) and, if smooth * shading, an element index buffer. */ -void GPU_pbvh_bmesh_buffers_update( - GPU_PBVH_Buffers *buffers, - BMesh *bm, - GSet *bm_faces, - GSet *bm_unique_verts, - GSet *bm_other_verts, - const int update_flags) -{ - const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; - int tottri, totvert, maxvert = 0; - bool empty_mask = true; - - /* TODO, make mask layer optional for bmesh buffer */ - const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK); - - /* Count visible triangles */ - tottri = gpu_bmesh_face_visible_count(bm_faces); - - 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; - } - - if (!tottri) { - buffers->tot_tri = 0; - return; - } - - /* Fill vertex buffer */ - if (gpu_pbvh_vert_buf_data_set(buffers, totvert)) { - int v_index = 0; - - if (buffers->smooth) { - GSetIterator gs_iter; - - /* Vertices get an index assigned for use in the triangle - * index buffer */ - bm->elem_index_dirty |= BM_VERT; - - GSET_ITER (gs_iter, bm_unique_verts) { - gpu_bmesh_vert_to_buffer_copy__gwn( - BLI_gsetIterator_getKey(&gs_iter), - buffers->vert_buf, &v_index, NULL, NULL, - cd_vert_mask_offset, - show_mask, &empty_mask); - } - - GSET_ITER (gs_iter, bm_other_verts) { - gpu_bmesh_vert_to_buffer_copy__gwn( - BLI_gsetIterator_getKey(&gs_iter), - buffers->vert_buf, &v_index, NULL, NULL, - cd_vert_mask_offset, - show_mask, &empty_mask); - } - - maxvert = v_index; - } - 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); - - BLI_assert(f->len == 3); - - if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { - BMVert *v[3]; - float fmask = 0.0f; - int i; - - BM_face_as_array_vert_tri(f, v); - - /* Average mask value */ - for (i = 0; i < 3; i++) { - fmask += BM_ELEM_CD_GET_FLOAT(v[i], cd_vert_mask_offset); - } - 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, - &v_index, f->no, &fmask, - cd_vert_mask_offset, - show_mask, &empty_mask); - } - } - } - - buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines); - buffers->tot_tri = tottri; - } - - /* gpu_bmesh_vert_to_buffer_copy sets dirty index values */ - bm->elem_index_dirty |= BM_VERT; - } - else { - /* Memory map failed */ - return; - } - - if (buffers->smooth) { - /* Fill the triangle buffer */ - GPUIndexBufBuilder elb, elb_lines; - GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, maxvert); - GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, maxvert); - - /* Fill triangle index buffer */ - { - GSetIterator gs_iter; - - GSET_ITER (gs_iter, bm_faces) { - BMFace *f = BLI_gsetIterator_getKey(&gs_iter); - - if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { - BMVert *v[3]; - - BM_face_as_array_vert_tri(f, v); - - 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]); - } - } - - buffers->tot_tri = tottri; - - if (buffers->index_buf == NULL) { - buffers->index_buf = GPU_indexbuf_build(&elb); - } - else { - GPU_indexbuf_build_in_place(&elb, buffers->index_buf); - } - - buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines); - } - } - - buffers->show_mask = !empty_mask; - - gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); -} - -/** \} */ - -/* -------------------------------------------------------------------- */ -/** \name Generic + void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers * buffers, + BMesh * bm, + GSet * bm_faces, + GSet * bm_unique_verts, + GSet * bm_other_verts, + const int update_flags) + { + const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; + int tottri, totvert, maxvert = 0; + bool empty_mask = true; + + /* TODO, make mask layer optional for bmesh buffer */ + const int cd_vert_mask_offset = CustomData_get_offset(&bm->vdata, CD_PAINT_MASK); + + /* Count visible triangles */ + tottri = gpu_bmesh_face_visible_count(bm_faces); + + 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; + } + + if (!tottri) { + buffers->tot_tri = 0; + return; + } + + /* Fill vertex buffer */ + if (gpu_pbvh_vert_buf_data_set(buffers, totvert)) { + int v_index = 0; + + if (buffers->smooth) { + GSetIterator gs_iter; + + /* Vertices get an index assigned for use in the triangle + * index buffer */ + bm->elem_index_dirty |= BM_VERT; + + GSET_ITER (gs_iter, bm_unique_verts) { + gpu_bmesh_vert_to_buffer_copy__gwn(BLI_gsetIterator_getKey(&gs_iter), + buffers->vert_buf, + &v_index, + NULL, + NULL, + cd_vert_mask_offset, + show_mask, + &empty_mask); + } + + GSET_ITER (gs_iter, bm_other_verts) { + gpu_bmesh_vert_to_buffer_copy__gwn(BLI_gsetIterator_getKey(&gs_iter), + buffers->vert_buf, + &v_index, + NULL, + NULL, + cd_vert_mask_offset, + show_mask, + &empty_mask); + } + + maxvert = v_index; + } + 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); + + BLI_assert(f->len == 3); + + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { + BMVert *v[3]; + float fmask = 0.0f; + int i; + + BM_face_as_array_vert_tri(f, v); + + /* Average mask value */ + for (i = 0; i < 3; i++) { + fmask += BM_ELEM_CD_GET_FLOAT(v[i], cd_vert_mask_offset); + } + 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, + &v_index, + f->no, + &fmask, + cd_vert_mask_offset, + show_mask, + &empty_mask); + } + } + } + + buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines); + buffers->tot_tri = tottri; + } + + /* gpu_bmesh_vert_to_buffer_copy sets dirty index values */ + bm->elem_index_dirty |= BM_VERT; + } + else { + /* Memory map failed */ + return; + } + + if (buffers->smooth) { + /* Fill the triangle buffer */ + GPUIndexBufBuilder elb, elb_lines; + GPU_indexbuf_init(&elb, GPU_PRIM_TRIS, tottri, maxvert); + GPU_indexbuf_init(&elb_lines, GPU_PRIM_LINES, tottri * 3, maxvert); + + /* Fill triangle index buffer */ + { + GSetIterator gs_iter; + + GSET_ITER (gs_iter, bm_faces) { + BMFace *f = BLI_gsetIterator_getKey(&gs_iter); + + if (!BM_elem_flag_test(f, BM_ELEM_HIDDEN)) { + BMVert *v[3]; + + BM_face_as_array_vert_tri(f, v); + + 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]); + } + } + + buffers->tot_tri = tottri; + + if (buffers->index_buf == NULL) { + buffers->index_buf = GPU_indexbuf_build(&elb); + } + else { + GPU_indexbuf_build_in_place(&elb, buffers->index_buf); + } + + buffers->index_lines_buf = GPU_indexbuf_build(&elb_lines); + } + } + + 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; - - buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers"); - buffers->use_bmesh = true; - buffers->smooth = smooth_shading; - buffers->show_mask = true; - - return buffers; -} - -GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers *buffers, bool fast, bool wires) -{ - 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) -{ - return buffers->show_mask; -} - -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); - 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 + GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading) + { + GPU_PBVH_Buffers *buffers; + + buffers = MEM_callocN(sizeof(GPU_PBVH_Buffers), "GPU_Buffers"); + buffers->use_bmesh = true; + buffers->smooth = smooth_shading; + buffers->show_mask = true; + + return buffers; + } + + GPUBatch *GPU_pbvh_buffers_batch_get(GPU_PBVH_Buffers * buffers, bool fast, bool wires) + { + 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) + { + return buffers->show_mask; + } + + 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); + 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) -{ - if (leaf) - immUniformColor4f(0.0, 1.0, 0.0, 0.5); - else - immUniformColor4f(1.0, 0.0, 0.0, 0.5); + /* debug function, draws the pbvh BB */ + void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf, uint pos) + { + if (leaf) + immUniformColor4f(0.0, 1.0, 0.0, 0.5); + else + immUniformColor4f(1.0, 0.0, 0.0, 0.5); - /* TODO(merwin): revisit this after we have mutable VertexBuffers - * could keep a static batch & index buffer, change the VBO contents per draw - */ + /* TODO(merwin): revisit this after we have mutable VertexBuffers + * could keep a static batch & index buffer, change the VBO contents per draw + */ - immBegin(GPU_PRIM_LINES, 24); + immBegin(GPU_PRIM_LINES, 24); - /* top */ - immVertex3f(pos, min[0], min[1], max[2]); - immVertex3f(pos, min[0], max[1], max[2]); + /* top */ + immVertex3f(pos, min[0], min[1], max[2]); + immVertex3f(pos, min[0], max[1], max[2]); - immVertex3f(pos, min[0], max[1], max[2]); - immVertex3f(pos, max[0], max[1], max[2]); + immVertex3f(pos, min[0], max[1], max[2]); + immVertex3f(pos, max[0], max[1], max[2]); - immVertex3f(pos, max[0], max[1], max[2]); - immVertex3f(pos, max[0], min[1], max[2]); + immVertex3f(pos, max[0], max[1], max[2]); + immVertex3f(pos, max[0], min[1], max[2]); - immVertex3f(pos, max[0], min[1], max[2]); - immVertex3f(pos, min[0], min[1], max[2]); + immVertex3f(pos, max[0], min[1], max[2]); + immVertex3f(pos, min[0], min[1], max[2]); - /* bottom */ - immVertex3f(pos, min[0], min[1], min[2]); - immVertex3f(pos, min[0], max[1], min[2]); + /* bottom */ + immVertex3f(pos, min[0], min[1], min[2]); + immVertex3f(pos, min[0], max[1], min[2]); - immVertex3f(pos, min[0], max[1], min[2]); - immVertex3f(pos, max[0], max[1], min[2]); + immVertex3f(pos, min[0], max[1], min[2]); + immVertex3f(pos, max[0], max[1], min[2]); - immVertex3f(pos, max[0], max[1], min[2]); - immVertex3f(pos, max[0], min[1], min[2]); + immVertex3f(pos, max[0], max[1], min[2]); + immVertex3f(pos, max[0], min[1], min[2]); - immVertex3f(pos, max[0], min[1], min[2]); - immVertex3f(pos, min[0], min[1], min[2]); + immVertex3f(pos, max[0], min[1], min[2]); + immVertex3f(pos, min[0], min[1], min[2]); - /* sides */ - immVertex3f(pos, min[0], min[1], min[2]); - immVertex3f(pos, min[0], min[1], max[2]); + /* sides */ + immVertex3f(pos, min[0], min[1], min[2]); + immVertex3f(pos, min[0], min[1], max[2]); - immVertex3f(pos, min[0], max[1], min[2]); - immVertex3f(pos, min[0], max[1], max[2]); + immVertex3f(pos, min[0], max[1], min[2]); + immVertex3f(pos, min[0], max[1], max[2]); - immVertex3f(pos, max[0], max[1], min[2]); - immVertex3f(pos, max[0], max[1], max[2]); + immVertex3f(pos, max[0], max[1], min[2]); + immVertex3f(pos, max[0], max[1], max[2]); - immVertex3f(pos, max[0], min[1], min[2]); - immVertex3f(pos, max[0], min[1], max[2]); + immVertex3f(pos, max[0], min[1], min[2]); + immVertex3f(pos, max[0], min[1], max[2]); - immEnd(); -} + immEnd(); + } -/** \} */ + /** \} */ -void GPU_pbvh_fix_linking() -{ -} + void GPU_pbvh_fix_linking() + { + } -- cgit v1.2.3