Wireframe: Optimization: Only draw triangles that have edges
authorClément Foucault <foucault.clem@gmail.com>
Tue, 4 Dec 2018 14:39:30 +0000 (15:39 +0100)
committerClément Foucault <foucault.clem@gmail.com>
Tue, 4 Dec 2018 16:52:32 +0000 (17:52 +0100)
This only happens after a certain wireframe threshold.

We sort triangles into 2 bins (start and end of the buffer) based on a
threshold and just draw the first bin if the wireframe slider is low enough.

This optimization is disabled for deformed meshes when playback is active.
This optimization is only implemented for meshes object for now.

This should help resolve (to some extent) T58188.

source/blender/draw/intern/DRW_render.h
source/blender/draw/intern/draw_cache.c
source/blender/draw/intern/draw_cache_impl_mesh.c
source/blender/draw/intern/draw_manager.c
source/blender/draw/modes/overlay_mode.c

index 1d11774d48f3809558bc8894a3b7f0480b5926e4..cdc6b28ccca257ca9538c621c68365050164fdd3 100644 (file)
@@ -556,6 +556,7 @@ bool DRW_state_is_depth(void);
 bool DRW_state_is_image_render(void);
 bool DRW_state_is_scene_render(void);
 bool DRW_state_is_opengl_render(void);
+bool DRW_state_is_playback(void);
 bool DRW_state_show_text(void);
 bool DRW_state_draw_support(void);
 bool DRW_state_draw_background(void);
index 51681f01849db90d65e558ab89bd43f562261cfe..2e13e1a343ef3a42d36707f90fdbc2c6b20e81db 100644 (file)
@@ -39,6 +39,7 @@
 #include "BLI_math.h"
 #include "BLI_listbase.h"
 
+#include "BKE_object.h"
 #include "BKE_object_deform.h"
 
 #include "GPU_batch.h"
@@ -47,6 +48,8 @@
 
 #include "MEM_guardedalloc.h"
 
+#include "DRW_render.h"
+
 #include "draw_cache.h"
 #include "draw_cache_impl.h"
 
@@ -3067,6 +3070,9 @@ void DRW_cache_mesh_face_wireframe_get(
 {
        BLI_assert(ob->type == OB_MESH);
 
+       const DRWContextState *draw_ctx = DRW_context_state_get();
+       reduce_len = reduce_len && !(DRW_state_is_playback() && BKE_object_is_deform_modified(draw_ctx->scene, ob));
+
        Mesh *me = ob->data;
        DRW_mesh_batch_cache_get_wireframes_face_texbuf(me, r_vert_tx, r_faceid_tx, r_tri_count, reduce_len);
 }
index 936df9bafdf568fc0b8713618aa87a8232373db7..5d7e588b9048e267fe4f44f5197f4e758b664d92 100644 (file)
@@ -2066,6 +2066,7 @@ typedef struct MeshBatchCache {
        GPUTexture *edges_face_overlay_tx;
        int edges_face_overlay_tri_count; /* Number of tri in edges_face_overlay(_adj)_tx */
        int edges_face_overlay_tri_count_low; /* Number of tri that are sure to produce edges. */
+       bool edges_face_reduce_len; /* Has the edges_face_overlay vertbuf has been sorted. */
 
        /* Maybe have shaded_triangles_data split into pos_nor and uv_tangent
         * to minimize data transfer for skinned mesh. */
@@ -4406,6 +4407,7 @@ static GPUVertBuf *mesh_batch_cache_create_edges_overlay_texture_buf(
 
        cache->edges_face_overlay_tri_count = vbo->vertex_alloc / 3;
        cache->edges_face_overlay_tri_count_low = vidx / 3;
+       cache->edges_face_reduce_len = reduce_len;
 
        BLI_edgehash_free(eh, MEM_freeN);
        return vbo;
@@ -5104,6 +5106,11 @@ void DRW_mesh_batch_cache_get_wireframes_face_texbuf(
 {
        MeshBatchCache *cache = mesh_batch_cache_get(me);
 
+       if (!cache->edges_face_reduce_len && reduce_len) {
+               GPU_VERTBUF_DISCARD_SAFE(cache->edges_face_overlay);
+               DRW_TEXTURE_FREE_SAFE(cache->edges_face_overlay_tx);
+       }
+
        if (cache->edges_face_overlay_tx == NULL || cache->pos_in_order_tx == NULL) {
                const int options = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI;
 
index 41acc9fe03c2761342ba39844d0b06d8b3916394..265d33c8023fb343498f7230e1d0b57c7830f198 100644 (file)
@@ -2419,6 +2419,16 @@ bool DRW_state_is_opengl_render(void)
        return DST.options.is_image_render && !DST.options.is_scene_render;
 }
 
+bool DRW_state_is_playback(void)
+{
+       if (DST.draw_ctx.evil_C != NULL) {
+               struct wmWindowManager *wm = CTX_wm_manager(DST.draw_ctx.evil_C);
+               return ED_screen_animation_playing(wm) != NULL;
+       }
+       return false;
+}
+
+
 /**
  * Should text draw in this mode?
  */
index 3f4168b00049e361f47be473487339f27410e269..43ec7ab26bb25ed15ffac36506663a9eb3b72b98 100644 (file)
@@ -289,9 +289,7 @@ static void overlay_cache_populate(void *vedata, Object *ob)
                        }
                        else {
                                /* Manually tweaked so the shader hidding matches. */
-                               const bool reduced_tri_len = (stl->g_data->wire_step_param[1] < 0.9988) &&
-                                                            !(DRW_state_is_select() || DRW_state_is_depth()) &&
-                                                            !BKE_object_is_deform_modified(draw_ctx->scene, ob);
+                               const bool reduced_tri_len = (stl->g_data->wire_step_param[1] < 0.9988) && !all_wires;
                                int tri_count;
                                GPUTexture *verts = NULL, *faceids;
                                DRW_cache_object_face_wireframe_get(ob, &verts, &faceids, &tri_count, reduced_tri_len);