diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-08-19 18:02:21 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-08-19 18:02:27 +0300 |
commit | 3cbf2462391c4adecd5be0bcd3e9654d494d9ed2 (patch) | |
tree | 6a2aaf3a589e0395bd968d027132ef8b8f69f648 /source/blender/draw | |
parent | 0b2e0877de97c79dfe0579f175f29c615a914140 (diff) |
Fix T68719 Viewport: Wrong material index when switching between view mode
This was due to the GPUIndexBuf ranges only computed when requesting
the triangles indices. If the tris were already calculated, the new shading
batches would never have the GPUIndexBuf ranges and instead use the full
triangle index buffer.
So since this only happen when shading data does not match, we just save
the previous GPUIndexBuf ranges and reuse them for the new batch.
This patch is a bit of a hack on top of a hack but it works fine.
Diffstat (limited to 'source/blender/draw')
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c index 12c6a715685..abc45f5e0a2 100644 --- a/source/blender/draw/intern/draw_cache_impl_mesh.c +++ b/source/blender/draw/intern/draw_cache_impl_mesh.c @@ -969,6 +969,7 @@ void DRW_mesh_batch_cache_free_old(Mesh *me, int ctime) void DRW_mesh_batch_cache_create_requested( Object *ob, Mesh *me, const Scene *scene, const bool is_paint_mode, const bool use_hide) { + GPUIndexBuf **saved_elem_ranges = NULL; const ToolSettings *ts = NULL; if (scene) { ts = scene->toolsettings; @@ -1031,6 +1032,17 @@ void DRW_mesh_batch_cache_create_requested( GPU_VERTBUF_DISCARD_SAFE(mbuffercache->vbo.vcol); } } + /* XXX save element buffer to avoid recreating them. + * This is only if the cd_needed changes so it is ok to keep them.*/ + if (cache->surface_per_mat[0]->elem) { + saved_elem_ranges = MEM_callocN(sizeof(saved_elem_ranges) * cache->mat_len, __func__); + for (int i = 0; i < cache->mat_len; ++i) { + saved_elem_ranges[i] = cache->surface_per_mat[i]->elem; + /* Avoid deletion as the batch is owner. */ + cache->surface_per_mat[i]->elem = NULL; + cache->surface_per_mat[i]->owns_flag &= ~GPU_BATCH_OWNS_INDEX; + } + } /* We can't discard batches at this point as they have been * referenced for drawing. Just clear them in place. */ for (int i = 0; i < cache->mat_len; ++i) { @@ -1151,7 +1163,13 @@ void DRW_mesh_batch_cache_create_requested( /* Per Material */ for (int i = 0; i < cache->mat_len; ++i) { if (DRW_batch_requested(cache->surface_per_mat[i], GPU_PRIM_TRIS)) { - DRW_ibo_request(cache->surface_per_mat[i], &mbufcache->ibo.tris); + if (saved_elem_ranges && saved_elem_ranges[i]) { + /* XXX assign old element buffer range (it did not change).*/ + GPU_batch_elembuf_set(cache->surface_per_mat[i], saved_elem_ranges[i], true); + } + else { + DRW_ibo_request(cache->surface_per_mat[i], &mbufcache->ibo.tris); + } /* Order matters. First ones override latest vbos' attribs. */ DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.lnor); DRW_vbo_request(cache->surface_per_mat[i], &mbufcache->vbo.pos_nor); @@ -1170,6 +1188,8 @@ void DRW_mesh_batch_cache_create_requested( } } + MEM_SAFE_FREE(saved_elem_ranges); + mbufcache = (do_cage) ? &cache->cage : &cache->final; /* Edit Mesh */ |