Changeset View
Changeset View
Standalone View
Standalone View
source/blender/gpu/intern/gpu_buffers.c
| Show First 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | struct GPU_PBVH_Buffers { | ||||
| /* The PBVH ensures that either all faces in the node are | /* The PBVH ensures that either all faces in the node are | ||||
| * smooth-shaded or all faces are flat-shaded */ | * smooth-shaded or all faces are flat-shaded */ | ||||
| bool smooth; | bool smooth; | ||||
| bool show_mask; | bool show_mask; | ||||
| }; | }; | ||||
| static struct { | static struct { | ||||
| uint pos, nor, msk; | uint pos, nor, msk, col; | ||||
| } g_vbo_id = {0}; | } g_vbo_id = {0}; | ||||
| /** \} */ | /** \} */ | ||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /** \name PBVH Utils | /** \name PBVH Utils | ||||
| * \{ */ | * \{ */ | ||||
| Show All 24 Lines | #else | ||||
| if (buffers->vert_buf == NULL) { | if (buffers->vert_buf == NULL) { | ||||
| /* Initialize vertex buffer (match 'VertexBufferFormat'). */ | /* Initialize vertex buffer (match 'VertexBufferFormat'). */ | ||||
| static GPUVertFormat format = {0}; | static GPUVertFormat format = {0}; | ||||
| if (format.attr_len == 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.pos = GPU_vertformat_attr_add(&format, "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); | ||||
| g_vbo_id.nor = GPU_vertformat_attr_add( | g_vbo_id.nor = GPU_vertformat_attr_add( | ||||
| &format, "nor", GPU_COMP_I16, 3, GPU_FETCH_INT_TO_FLOAT_UNIT); | &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); | g_vbo_id.msk = GPU_vertformat_attr_add(&format, "msk", GPU_COMP_F32, 1, GPU_FETCH_FLOAT); | ||||
| g_vbo_id.col = GPU_vertformat_attr_add( | |||||
fclem: I'm not really happy with that but we have the same issue with the "msk" attrib. It's always… | |||||
| &format, "c", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT); | |||||
| } | } | ||||
| buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC); | buffers->vert_buf = GPU_vertbuf_create_with_format_ex(&format, GPU_USAGE_STATIC); | ||||
| } | } | ||||
| GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len); | GPU_vertbuf_data_alloc(buffers->vert_buf, vert_len); | ||||
| #endif | #endif | ||||
| return buffers->vert_buf->data != NULL; | return buffers->vert_buf->data != NULL; | ||||
| } | } | ||||
| Show All 35 Lines | |||||
| /** \name Mesh PBVH | /** \name Mesh PBVH | ||||
| * \{ */ | * \{ */ | ||||
| void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, | void GPU_pbvh_mesh_buffers_update(GPU_PBVH_Buffers *buffers, | ||||
| const MVert *mvert, | const MVert *mvert, | ||||
| const int *vert_indices, | const int *vert_indices, | ||||
| int totvert, | int totvert, | ||||
| const float *vmask, | const float *vmask, | ||||
| const MLoopCol *vcol, | |||||
| const int (*face_vert_indices)[3], | const int (*face_vert_indices)[3], | ||||
| const int update_flags) | const int update_flags) | ||||
| { | { | ||||
| const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; | const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; | ||||
| bool empty_mask = true; | bool empty_mask = true; | ||||
| { | { | ||||
| int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3)); | int totelem = (buffers->smooth ? totvert : (buffers->tot_tri * 3)); | ||||
| /* Build VBO */ | /* Build VBO */ | ||||
| if (gpu_pbvh_vert_buf_data_set(buffers, totelem)) { | if (gpu_pbvh_vert_buf_data_set(buffers, totelem)) { | ||||
| /* Vertex data is shared if smooth-shaded, but separate | /* Vertex data is shared if smooth-shaded, but separate | ||||
| * copies are made for flat shading because normals | * copies are made for flat shading because normals | ||||
| * shouldn't be shared. */ | * shouldn't be shared. */ | ||||
| if (buffers->smooth) { | if (buffers->smooth) { | ||||
| for (uint i = 0; i < totvert; ++i) { | for (uint i = 0; i < totvert; ++i) { | ||||
| const MVert *v = &mvert[vert_indices[i]]; | const uint v_index = vert_indices[i]; | ||||
| const MVert *v = &mvert[v_index]; | |||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.pos, i, v->co); | 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); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, i, v->no); | ||||
| // if (vcol) { | |||||
| // // static char elem[4] = {255, 0, 0, 255}; | |||||
| // const uchar *elem = &vcol[i].r; | |||||
| // GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, i, elem); | |||||
| // } | |||||
| } | } | ||||
| if (vmask && show_mask) { | if (vmask && show_mask) { | ||||
| for (uint i = 0; i < buffers->face_indices_len; i++) { | for (uint i = 0; i < buffers->face_indices_len; i++) { | ||||
| const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]]; | const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]]; | ||||
| for (uint j = 0; j < 3; j++) { | for (uint j = 0; j < 3; j++) { | ||||
| int vidx = face_vert_indices[i][j]; | int vidx = face_vert_indices[i][j]; | ||||
| int v_index = buffers->mloop[lt->tri[j]].v; | int v_index = buffers->mloop[lt->tri[j]].v; | ||||
| float fmask = vmask[v_index]; | float fmask = vmask[v_index]; | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vidx, &fmask); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vidx, &fmask); | ||||
| empty_mask = empty_mask && (fmask == 0.0f); | empty_mask = empty_mask && (fmask == 0.0f); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (vcol) { | |||||
Done Inline ActionsI think we should only do that if the vcol is also being displayed. (i.e. have a bool show_vcol) fclem: I think we should only do that if the vcol is also being displayed. (i.e. have a bool show_vcol) | |||||
| // 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; | |||||
| // const uchar *elem = &vcol[v_index].r; | |||||
| // GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vidx, elem); | |||||
| // } | |||||
| // } | |||||
| 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; | |||||
| const uchar *elem = &vcol[v_index].r; | |||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vidx, elem); | |||||
| } | |||||
| } | |||||
| // for (uint i = 0; i < totvert; i++) { | |||||
| // const uchar *elem = &vcol[i].r; | |||||
| // GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, i, elem); | |||||
| // } | |||||
| } | |||||
| } | } | ||||
| else { | else { | ||||
| /* calculate normal for each polygon only once */ | /* calculate normal for each polygon only once */ | ||||
| uint mpoly_prev = UINT_MAX; | uint mpoly_prev = UINT_MAX; | ||||
| short no[3]; | short no[3]; | ||||
| int vbo_index = 0; | int vbo_index = 0; | ||||
| for (uint i = 0; i < buffers->face_indices_len; i++) { | for (uint i = 0; i < buffers->face_indices_len; i++) { | ||||
| Show All 16 Lines | if (gpu_pbvh_vert_buf_data_set(buffers, totelem)) { | ||||
| mpoly_prev = lt->poly; | mpoly_prev = lt->poly; | ||||
| } | } | ||||
| float fmask = 0.0f; | float fmask = 0.0f; | ||||
| if (vmask && show_mask) { | if (vmask && show_mask) { | ||||
| fmask = (vmask[vtri[0]] + vmask[vtri[1]] + vmask[vtri[2]]) / 3.0f; | fmask = (vmask[vtri[0]] + vmask[vtri[1]] + vmask[vtri[2]]) / 3.0f; | ||||
| } | } | ||||
| for (uint j = 0; j < 3; j++) { | for (uint j = 0; j < 3; j++) { | ||||
| const MVert *v = &mvert[vtri[j]]; | const uint mvi = vtri[j]; | ||||
| const MVert *v = &mvert[mvi]; | |||||
| char col[4]; | |||||
| if (vcol) { | |||||
| col[0] = vcol[mvi].r; | |||||
| col[1] = vcol[mvi].g; | |||||
| col[2] = vcol[mvi].b; | |||||
| col[3] = vcol[mvi].a; | |||||
| } | |||||
| 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.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.nor, vbo_index, no); | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, &col); | |||||
| vbo_index++; | vbo_index++; | ||||
| } | } | ||||
| empty_mask = empty_mask && (fmask == 0.0f); | empty_mask = empty_mask && (fmask == 0.0f); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 241 Lines • ▼ Show 20 Lines | void GPU_pbvh_grid_buffers_update(GPU_PBVH_Buffers *buffers, | ||||
| const CCGKey *key, | const CCGKey *key, | ||||
| const int update_flags) | const int update_flags) | ||||
| { | { | ||||
| const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; | const bool show_mask = (update_flags & GPU_PBVH_BUFFERS_SHOW_MASK) != 0; | ||||
| bool empty_mask = true; | bool empty_mask = true; | ||||
| int i, j, k, x, y; | int i, j, k, x, y; | ||||
| const bool smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH; | const bool smooth = grid_flag_mats[grid_indices[0]].flag & ME_SMOOTH; | ||||
| static char col[4] = {255, 255, 255, 255}; | |||||
| /* Build VBO */ | /* Build VBO */ | ||||
| const int has_mask = key->has_mask; | const int has_mask = key->has_mask; | ||||
| uint vert_per_grid = (smooth) ? key->grid_area : (SQUARE(key->grid_size - 1) * 4); | uint vert_per_grid = (smooth) ? key->grid_area : (SQUARE(key->grid_size - 1) * 4); | ||||
| uint vert_count = totgrid * vert_per_grid; | uint vert_count = totgrid * vert_per_grid; | ||||
| if (buffers->smooth != smooth) { | if (buffers->smooth != smooth) { | ||||
| ▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Lines | for (i = 0; i < totgrid; ++i) { | ||||
| normal_float_to_short_v3(no_short, CCG_elem_no(key, elem)); | 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); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.nor, vbo_index, no_short); | ||||
| if (has_mask && show_mask) { | if (has_mask && show_mask) { | ||||
| float fmask = *CCG_elem_mask(key, elem); | float fmask = *CCG_elem_mask(key, elem); | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index, &fmask); | ||||
| empty_mask = empty_mask && (fmask == 0.0f); | empty_mask = empty_mask && (fmask == 0.0f); | ||||
| } | } | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index, &col); | |||||
| vbo_index += 1; | vbo_index += 1; | ||||
| } | } | ||||
| } | } | ||||
| vbo_index_offset += key->grid_area; | vbo_index_offset += key->grid_area; | ||||
| } | } | ||||
| else { | else { | ||||
| for (j = 0; j < key->grid_size - 1; j++) { | for (j = 0; j < key->grid_size - 1; j++) { | ||||
| for (k = 0; k < key->grid_size - 1; k++) { | for (k = 0; k < key->grid_size - 1; k++) { | ||||
| Show All 30 Lines | for (i = 0; i < totgrid; ++i) { | ||||
| *CCG_elem_mask(key, elems[2]) + *CCG_elem_mask(key, elems[3])) * | *CCG_elem_mask(key, elems[2]) + *CCG_elem_mask(key, elems[3])) * | ||||
| 0.25f; | 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 + 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 + 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 + 2, &fmask); | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 3, &fmask); | GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.msk, vbo_index + 3, &fmask); | ||||
| empty_mask = empty_mask && (fmask == 0.0f); | empty_mask = empty_mask && (fmask == 0.0f); | ||||
| } | } | ||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 0, &col); | |||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 1, &col); | |||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 2, &col); | |||||
| GPU_vertbuf_attr_set(buffers->vert_buf, g_vbo_id.col, vbo_index + 3, &col); | |||||
| vbo_index += 4; | vbo_index += 4; | ||||
| } | } | ||||
| } | } | ||||
| vbo_index_offset += SQUARE(key->grid_size - 1) * 4; | vbo_index_offset += SQUARE(key->grid_size - 1) * 4; | ||||
| } | } | ||||
| } | } | ||||
| gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); | gpu_pbvh_batch_init(buffers, GPU_PRIM_TRIS); | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | if (!BM_elem_flag_test(v, BM_ELEM_HIDDEN)) { | ||||
| normal_float_to_short_v3(no_short, fno ? fno : v->no); | 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); | GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, *v_index, no_short); | ||||
| if (show_mask) { | if (show_mask) { | ||||
| float effective_mask = fmask ? *fmask : BM_ELEM_CD_GET_FLOAT(v, cd_vert_mask_offset); | 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); | GPU_vertbuf_attr_set(vert_buf, g_vbo_id.msk, *v_index, &effective_mask); | ||||
| *empty_mask = *empty_mask && (effective_mask == 0.0f); | *empty_mask = *empty_mask && (effective_mask == 0.0f); | ||||
| } | } | ||||
| static char col[4] = {255, 255, 255, 255}; | |||||
| GPU_vertbuf_attr_set(vert_buf, g_vbo_id.col, *v_index, &col); | |||||
| /* Assign index for use in the triangle index buffer */ | /* Assign index for use in the triangle index buffer */ | ||||
| /* note: caller must set: bm->elem_index_dirty |= BM_VERT; */ | /* note: caller must set: bm->elem_index_dirty |= BM_VERT; */ | ||||
| BM_elem_index_set(v, (*v_index)); /* set_dirty! */ | BM_elem_index_set(v, (*v_index)); /* set_dirty! */ | ||||
| (*v_index)++; | (*v_index)++; | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 327 Lines • Show Last 20 Lines | |||||
I'm not really happy with that but we have the same issue with the "msk" attrib. It's always allocated even if not used.
I have no real solution for this at the moment. So maybe add a TODO about this as comment.