Wireframe: Optimization: Only draw triangles that have edges

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.
This commit is contained in:
Clément Foucault 2018-12-04 15:39:30 +01:00
parent f1975a4639
commit 6f198f7851
5 changed files with 25 additions and 3 deletions

View 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);

View 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);
}

View 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;

View 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?
*/

View 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);