Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc')
-rw-r--r--source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc109
1 files changed, 57 insertions, 52 deletions
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
index 93f71f920eb..3b2da9879c5 100644
--- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
+++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_tris.cc
@@ -27,59 +27,70 @@
namespace blender::draw {
+static void extract_tris_mat_task_reduce(void *_userdata_to, void *_userdata_from)
+{
+ GPUIndexBufBuilder *elb_to = static_cast<GPUIndexBufBuilder *>(_userdata_to);
+ GPUIndexBufBuilder *elb_from = static_cast<GPUIndexBufBuilder *>(_userdata_from);
+ GPU_indexbuf_join(elb_to, elb_from);
+}
+
/* ---------------------------------------------------------------------- */
/** \name Extract Triangles Indices (multi material)
* \{ */
-struct MeshExtract_Tri_Data {
- GPUIndexBufBuilder elb;
- const int *tri_mat_start;
- int *tri_mat_end;
-};
-
static void extract_tris_init(const MeshRenderData *mr,
struct MeshBatchCache *UNUSED(cache),
void *UNUSED(ibo),
void *tls_data)
{
- MeshExtract_Tri_Data *data = static_cast<MeshExtract_Tri_Data *>(tls_data);
- data->tri_mat_start = mr->mat_offsets.tri;
- data->tri_mat_end = static_cast<int *>(MEM_dupallocN(data->tri_mat_start));
- GPU_indexbuf_init(&data->elb, GPU_PRIM_TRIS, mr->mat_offsets.visible_tri_len, mr->loop_len);
+ GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(tls_data);
+ GPU_indexbuf_init(elb, GPU_PRIM_TRIS, mr->poly_sorted.visible_tri_len, mr->loop_len);
}
-static void extract_tris_iter_looptri_bm(const MeshRenderData *mr,
- BMLoop **elt,
- const int UNUSED(elt_index),
- void *_data)
+static void extract_tris_iter_poly_bm(const MeshRenderData *mr,
+ const BMFace *f,
+ const int f_index,
+ void *_data)
{
- MeshExtract_Tri_Data *data = static_cast<MeshExtract_Tri_Data *>(_data);
- const int mat_last = mr->mat_len - 1;
+ int tri_first_index = mr->poly_sorted.tri_first_index[f_index];
+ if (tri_first_index == -1) {
+ return;
+ }
- if (!BM_elem_flag_test(elt[0]->f, BM_ELEM_HIDDEN)) {
- int *mat_tri_ofs = data->tri_mat_end;
- const int mat = min_ii(elt[0]->f->mat_nr, mat_last);
- GPU_indexbuf_set_tri_verts(&data->elb,
- mat_tri_ofs[mat]++,
+ GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
+ int tri_first_index_real = poly_to_tri_count(f_index, BM_elem_index_get(f->l_first));
+
+ struct BMLoop *(*looptris)[3] = mr->edit_bmesh->looptris;
+ int tri_len = f->len - 2;
+ for (int offs = 0; offs < tri_len; offs++) {
+ BMLoop **elt = looptris[tri_first_index_real + offs];
+ int tri_index = tri_first_index + offs;
+ GPU_indexbuf_set_tri_verts(elb,
+ tri_index,
BM_elem_index_get(elt[0]),
BM_elem_index_get(elt[1]),
BM_elem_index_get(elt[2]));
}
}
-static void extract_tris_iter_looptri_mesh(const MeshRenderData *mr,
- const MLoopTri *mlt,
- const int UNUSED(elt_index),
- void *_data)
+static void extract_tris_iter_poly_mesh(const MeshRenderData *mr,
+ const MPoly *mp,
+ const int mp_index,
+ void *_data)
{
- MeshExtract_Tri_Data *data = static_cast<MeshExtract_Tri_Data *>(_data);
- const int mat_last = mr->mat_len - 1;
- const MPoly *mp = &mr->mpoly[mlt->poly];
- if (!(mr->use_hide && (mp->flag & ME_HIDE))) {
- int *mat_tri_ofs = data->tri_mat_end;
- const int mat = min_ii(mp->mat_nr, mat_last);
- GPU_indexbuf_set_tri_verts(
- &data->elb, mat_tri_ofs[mat]++, mlt->tri[0], mlt->tri[1], mlt->tri[2]);
+ int tri_first_index = mr->poly_sorted.tri_first_index[mp_index];
+ if (tri_first_index == -1) {
+ return;
+ }
+
+ GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
+ int tri_first_index_real = poly_to_tri_count(mp_index, mp->loopstart);
+
+ int tri_len = mp->totloop - 2;
+ for (int offs = 0; offs < tri_len; offs++) {
+ const MLoopTri *mlt = &mr->mlooptri[tri_first_index_real + offs];
+ int tri_index = tri_first_index + offs;
+ GPU_indexbuf_set_tri_verts(elb, tri_index, mlt->tri[0], mlt->tri[1], mlt->tri[2]);
}
}
@@ -89,40 +100,41 @@ static void extract_tris_finish(const MeshRenderData *mr,
void *_data)
{
GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buf);
- MeshExtract_Tri_Data *data = static_cast<MeshExtract_Tri_Data *>(_data);
- GPU_indexbuf_build_in_place(&data->elb, ibo);
+ GPUIndexBufBuilder *elb = static_cast<GPUIndexBufBuilder *>(_data);
+ GPU_indexbuf_build_in_place(elb, ibo);
/* Create ibo sub-ranges. Always do this to avoid error when the standard surface batch
* is created before the surfaces-per-material. */
if (mr->use_final_mesh && cache->final.tris_per_mat) {
MeshBufferCache *mbc_final = &cache->final;
+ int mat_start = 0;
for (int i = 0; i < mr->mat_len; i++) {
/* These IBOs have not been queried yet but we create them just in case they are needed
* later since they are not tracked by mesh_buffer_cache_create_requested(). */
if (mbc_final->tris_per_mat[i] == nullptr) {
mbc_final->tris_per_mat[i] = GPU_indexbuf_calloc();
}
+ const int mat_tri_len = mr->poly_sorted.mat_tri_len[i];
/* Multiply by 3 because these are triangle indices. */
- const int mat_start = data->tri_mat_start[i];
- const int mat_end = data->tri_mat_end[i];
const int start = mat_start * 3;
- const int len = (mat_end - mat_start) * 3;
+ const int len = mat_tri_len * 3;
GPU_indexbuf_create_subrange_in_place(mbc_final->tris_per_mat[i], ibo, start, len);
+ mat_start += mat_tri_len;
}
}
- MEM_freeN(data->tri_mat_end);
}
constexpr MeshExtract create_extractor_tris()
{
MeshExtract extractor = {nullptr};
extractor.init = extract_tris_init;
- extractor.iter_looptri_bm = extract_tris_iter_looptri_bm;
- extractor.iter_looptri_mesh = extract_tris_iter_looptri_mesh;
+ extractor.iter_poly_bm = extract_tris_iter_poly_bm;
+ extractor.iter_poly_mesh = extract_tris_iter_poly_mesh;
+ extractor.task_reduce = extract_tris_mat_task_reduce;
extractor.finish = extract_tris_finish;
- extractor.data_type = MR_DATA_MAT_OFFSETS;
- extractor.data_size = sizeof(MeshExtract_Tri_Data);
- extractor.use_threading = false;
+ extractor.data_type = MR_DATA_LOOPTRI | MR_DATA_POLYS_SORTED;
+ extractor.data_size = sizeof(GPUIndexBufBuilder);
+ extractor.use_threading = true;
extractor.mesh_buffer_offset = offsetof(MeshBufferCache, ibo.tris);
return extractor;
}
@@ -174,13 +186,6 @@ static void extract_tris_single_mat_iter_looptri_mesh(const MeshRenderData *mr,
}
}
-static void extract_tris_single_mat_task_reduce(void *_userdata_to, void *_userdata_from)
-{
- GPUIndexBufBuilder *elb_to = static_cast<GPUIndexBufBuilder *>(_userdata_to);
- GPUIndexBufBuilder *elb_from = static_cast<GPUIndexBufBuilder *>(_userdata_from);
- GPU_indexbuf_join(elb_to, elb_from);
-}
-
static void extract_tris_single_mat_finish(const MeshRenderData *mr,
struct MeshBatchCache *cache,
void *buf,
@@ -213,7 +218,7 @@ constexpr MeshExtract create_extractor_tris_single_mat()
extractor.init = extract_tris_single_mat_init;
extractor.iter_looptri_bm = extract_tris_single_mat_iter_looptri_bm;
extractor.iter_looptri_mesh = extract_tris_single_mat_iter_looptri_mesh;
- extractor.task_reduce = extract_tris_single_mat_task_reduce;
+ extractor.task_reduce = extract_tris_mat_task_reduce;
extractor.finish = extract_tris_single_mat_finish;
extractor.data_type = MR_DATA_NONE;
extractor.data_size = sizeof(GPUIndexBufBuilder);