diff options
author | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-03-02 17:10:26 +0300 |
---|---|---|
committer | Kévin Dietrich <kevin.dietrich@mailoo.org> | 2022-03-02 17:19:55 +0300 |
commit | 6883c47bb5930be5a95d1c2e8e06fce2d3b68681 (patch) | |
tree | 9c5fc32c03e6994a33827f2e7eaaa6d857f5554d /source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc | |
parent | 4a95c3466fafcd3e9116cd0d7fdcc63f2dc38bd2 (diff) |
Fix T94729: GPU subdivision does not support meshes without polygons
There are two issues revealed in the bug report:
- the GPU subdivision does not support meshes with only loose geometry
- the loose geometry is not subdivided
For the first case, checks are added to ensure we still fill the
buffers with loose geometry even if no polygons are present.
For the second case, this adds
`BKE_subdiv_mesh_interpolate_position_on_edge` which encapsulates the
loose vertex interpolation mechanism previously found in
`subdiv_mesh_vertex_of_loose_edge`.
The subdivided loose geometry is stored in a new specific data structure
`DRWSubdivLooseGeom` so as to not pollute `MeshExtractLooseGeom`. These
structures store the corresponding coarse element data, which will be
used for filling GPU buffers appropriately.
Differential Revision: https://developer.blender.org/D14171
Diffstat (limited to 'source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc')
-rw-r--r-- | source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc index 3d9729dea56..247d4c399e8 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_ibo_lines.cc @@ -158,30 +158,35 @@ static void extract_lines_finish(const MeshRenderData *UNUSED(mr), } static void extract_lines_init_subdiv(const DRWSubdivCache *subdiv_cache, - const MeshRenderData *mr, + const MeshRenderData *UNUSED(mr), struct MeshBatchCache *UNUSED(cache), void *buffer, void *UNUSED(data)) { + const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom; GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buffer); GPU_indexbuf_init_build_on_device(ibo, - subdiv_cache->num_subdiv_loops * 2 + mr->edge_loose_len * 2); + subdiv_cache->num_subdiv_loops * 2 + loose_geom.edge_len * 2); + + if (subdiv_cache->num_subdiv_loops == 0) { + return; + } draw_subdiv_build_lines_buffer(subdiv_cache, ibo); } static void extract_lines_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache, const MeshRenderData *UNUSED(mr), - const MeshExtractLooseGeom *loose_geom, void *buffer, void *UNUSED(data)) { - if (loose_geom->edge_len == 0) { + const DRWSubdivLooseGeom &loose_geom = subdiv_cache->loose_geom; + if (loose_geom.edge_len == 0) { return; } GPUIndexBuf *ibo = static_cast<GPUIndexBuf *>(buffer); - draw_subdiv_build_lines_loose_buffer(subdiv_cache, ibo, static_cast<uint>(loose_geom->edge_len)); + draw_subdiv_build_lines_loose_buffer(subdiv_cache, ibo, static_cast<uint>(loose_geom.edge_len)); } constexpr MeshExtract create_extractor_lines() @@ -231,6 +236,20 @@ static void extract_lines_with_lines_loose_finish(const MeshRenderData *mr, extract_lines_loose_subbuffer(mr, cache); } +static void extract_lines_with_lines_loose_finish_subdiv(const struct DRWSubdivCache *subdiv_cache, + const MeshRenderData *UNUSED(mr), + struct MeshBatchCache *cache, + void *UNUSED(buf), + void *UNUSED(_data)) +{ + /* Multiply by 2 because these are edges indices. */ + const int start = subdiv_cache->num_subdiv_loops * 2; + const int len = subdiv_cache->loose_geom.edge_len * 2; + GPU_indexbuf_create_subrange_in_place( + cache->final.buff.ibo.lines_loose, cache->final.buff.ibo.lines, start, len); + cache->no_loose_wire = (len == 0); +} + constexpr MeshExtract create_extractor_lines_with_lines_loose() { MeshExtract extractor = {nullptr}; @@ -241,6 +260,9 @@ constexpr MeshExtract create_extractor_lines_with_lines_loose() extractor.iter_ledge_mesh = extract_lines_iter_ledge_mesh; extractor.task_reduce = extract_lines_task_reduce; extractor.finish = extract_lines_with_lines_loose_finish; + extractor.init_subdiv = extract_lines_init_subdiv; + extractor.iter_loose_geom_subdiv = extract_lines_loose_geom_subdiv; + extractor.finish_subdiv = extract_lines_with_lines_loose_finish_subdiv; extractor.data_type = MR_DATA_NONE; extractor.data_size = sizeof(GPUIndexBufBuilder); extractor.use_threading = true; @@ -264,10 +286,22 @@ static void extract_lines_loose_only_init(const MeshRenderData *mr, extract_lines_loose_subbuffer(mr, cache); } +static void extract_lines_loose_only_init_subdiv(const DRWSubdivCache *UNUSED(subdiv_cache), + const MeshRenderData *mr, + struct MeshBatchCache *cache, + void *buffer, + void *UNUSED(data)) +{ + BLI_assert(buffer == cache->final.buff.ibo.lines_loose); + UNUSED_VARS_NDEBUG(buffer); + extract_lines_loose_subbuffer(mr, cache); +} + constexpr MeshExtract create_extractor_lines_loose_only() { MeshExtract extractor = {nullptr}; extractor.init = extract_lines_loose_only_init; + extractor.init_subdiv = extract_lines_loose_only_init_subdiv; extractor.data_type = MR_DATA_LOOSE_GEOM; extractor.data_size = 0; extractor.use_threading = false; |