diff options
author | Jeroen Bakker <j.bakker@atmind.nl> | 2018-06-13 17:47:10 +0300 |
---|---|---|
committer | Jeroen Bakker <j.bakker@atmind.nl> | 2018-06-13 17:47:38 +0300 |
commit | 2e23385c35727a78417d0ea5f1aec47320268436 (patch) | |
tree | 060d5b2a48f45e486ca67f0fee773a28d0826e92 | |
parent | 645c91882530de08eb210e59074ba64935ef3090 (diff) |
T55456: EditDrawMode
reorganized shader compilation
-rw-r--r-- | source/blender/draw/modes/edit_mesh_mode.c | 264 |
1 files changed, 97 insertions, 167 deletions
diff --git a/source/blender/draw/modes/edit_mesh_mode.c b/source/blender/draw/modes/edit_mesh_mode.c index 1a271fadd6b..5be98b12bb7 100644 --- a/source/blender/draw/modes/edit_mesh_mode.c +++ b/source/blender/draw/modes/edit_mesh_mode.c @@ -39,6 +39,9 @@ #include "BKE_object.h" +#include "BLI_dynstr.h" + + extern struct GPUUniformBuffer *globals_ubo; /* draw_common.c */ extern struct GlobalsUboStorage ts; /* draw_common.c */ @@ -87,26 +90,15 @@ typedef struct EDIT_MESH_Data { } EDIT_MESH_Data; /* *********** STATIC *********** */ +#define MAX_SHADERS 16 static struct { /* weight/vert-color */ GPUShader *vcolor_face_shader; /* Geometry */ - GPUShader *overlay_tri_sh; - GPUShader *overlay_tri_fast_sh; - GPUShader *overlay_tri_vcol_sh; - GPUShader *overlay_tri_vcol_fast_sh; - GPUShader *overlay_tri_edgesel_sh; - GPUShader *overlay_tri_edgesel_fast_sh; - GPUShader *overlay_tri_vcol_edgesel_sh; - GPUShader *overlay_tri_vcol_edgesel_fast_sh; - - /* Loose Edges */ - GPUShader *overlay_loose_edge_sh; - GPUShader *overlay_loose_edge_vcol_sh; - GPUShader *overlay_loose_edge_edgesel_sh; - GPUShader *overlay_loose_edge_vcol_edgesel_sh; + GPUShader *overlay_tri_sh_cache[MAX_SHADERS]; + GPUShader *overlay_loose_edge_sh_cache[MAX_SHADERS]; GPUShader *overlay_vert_sh; GPUShader *overlay_facedot_sh; @@ -144,6 +136,89 @@ typedef struct EDIT_MESH_PrivateData { } EDIT_MESH_PrivateData; /* Transient data */ /* *********** FUNCTIONS *********** */ +static int EDIT_MESH_sh_index(ToolSettings *tsettings, RegionView3D *rv3d, bool supports_fast_mode) +{ + int result = tsettings->selectmode << 1; + if (supports_fast_mode) + { + SET_FLAG_FROM_TEST(result, (rv3d->rflag & RV3D_NAVIGATING), 1 << 0); + } + return result; +} + +static char *EDIT_MESH_sh_defines(ToolSettings *tsettings, RegionView3D *rv3d, bool anti_alias) +{ + const int selectmode = tsettings->selectmode; + const int fast_mode = rv3d->rflag & RV3D_NAVIGATING; + + char *str = NULL; + DynStr *ds = BLI_dynstr_new(); + + if (selectmode & SCE_SELECT_VERTEX) + { + BLI_dynstr_appendf(ds, "#define VERTEX_SELECTION\n"); + } + + if (selectmode & SCE_SELECT_EDGE) + { + BLI_dynstr_appendf(ds, "#define EDGE_SELECTION\n"); + } + + if (selectmode & SCE_SELECT_FACE) + { + BLI_dynstr_appendf(ds, "#define FACE_SELECTION\n"); + } + + if (!fast_mode) + { + BLI_dynstr_appendf(ds, "#define EDGE_FIX\n"); + } + + if (anti_alias) + { + BLI_dynstr_appendf(ds, "#define ANTI_ALIASING\n"); + } + BLI_dynstr_appendf(ds, "#define VERTEX_FACING\n"); + + str = BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + return str; +} + +static GPUShader *EDIT_MESH_ensure_shader(ToolSettings *tsettings, RegionView3D *rv3d, bool fast_mode, bool looseedge) +{ + const int index = EDIT_MESH_sh_index(tsettings, rv3d, fast_mode); + if (looseedge) + { + if (!e_data.overlay_loose_edge_sh_cache[index]) + { + char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true); + e_data.overlay_loose_edge_sh_cache[index] = DRW_shader_create_with_lib( + datatoc_edit_mesh_overlay_vert_glsl, + datatoc_edit_mesh_overlay_geom_edge_glsl, + datatoc_edit_mesh_overlay_frag_glsl, + datatoc_common_globals_lib_glsl, + defines); + MEM_freeN(defines); + } + return e_data.overlay_loose_edge_sh_cache[index]; + } + else { + if (!e_data.overlay_tri_sh_cache[index]) + { + char *defines = EDIT_MESH_sh_defines(tsettings, rv3d, true); + e_data.overlay_tri_sh_cache[index] = DRW_shader_create_with_lib( + datatoc_edit_mesh_overlay_vert_glsl, + datatoc_edit_mesh_overlay_geom_tri_glsl, + datatoc_edit_mesh_overlay_frag_glsl, + datatoc_common_globals_lib_glsl, + defines); + + MEM_freeN(defines); + } + return e_data.overlay_tri_sh_cache[index]; + } +} static void EDIT_MESH_engine_init(void *vedata) { @@ -166,130 +241,6 @@ static void EDIT_MESH_engine_init(void *vedata) e_data.vcolor_face_shader = GPU_shader_get_builtin_shader(GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR_ALPHA); } - if (!e_data.overlay_tri_sh) { - e_data.overlay_tri_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_tri_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define EDGE_FIX\n" - "#define ANTI_ALIASING\n" - "#define VERTEX_FACING"); - } - if (!e_data.overlay_tri_fast_sh) { - e_data.overlay_tri_fast_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_tri_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define ANTI_ALIASING\n" - "#define VERTEX_FACING\n"); - } - if (!e_data.overlay_tri_vcol_sh) { - e_data.overlay_tri_vcol_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_tri_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define EDGE_FIX\n" - "#define VERTEX_SELECTION\n" - "#define ANTI_ALIASING\n" - "#define VERTEX_FACING\n"); - } - if (!e_data.overlay_tri_vcol_fast_sh) { - e_data.overlay_tri_vcol_fast_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_tri_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define VERTEX_SELECTION\n" - "#define ANTI_ALIASING\n" - "#define VERTEX_FACING\n"); - } - - if (!e_data.overlay_tri_edgesel_sh) { - e_data.overlay_tri_edgesel_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_tri_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define EDGE_FIX\n" - "#define EDGE_SELECTION\n" - "#define ANTI_ALIASING\n" - "#define VERTEX_FACING"); - } - if (!e_data.overlay_tri_edgesel_fast_sh) { - e_data.overlay_tri_edgesel_fast_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_tri_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define ANTI_ALIASING\n" - "#define EDGE_SELECTION\n" - "#define VERTEX_FACING\n"); - } - if (!e_data.overlay_tri_vcol_edgesel_sh) { - e_data.overlay_tri_vcol_edgesel_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_tri_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define EDGE_FIX\n" - "#define VERTEX_SELECTION\n" - "#define EDGE_SELECTION\n" - "#define ANTI_ALIASING\n" - "#define VERTEX_FACING\n"); - } - if (!e_data.overlay_tri_vcol_edgesel_fast_sh) { - e_data.overlay_tri_vcol_edgesel_fast_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_tri_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define VERTEX_SELECTION\n" - "#define EDGE_SELECTION\n" - "#define ANTI_ALIASING\n" - "#define VERTEX_FACING\n"); - } - - if (!e_data.overlay_loose_edge_sh) { - e_data.overlay_loose_edge_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_edge_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define ANTI_ALIASING\n" - "#define VERTEX_FACING\n"); - } - if (!e_data.overlay_loose_edge_vcol_sh) { - e_data.overlay_loose_edge_vcol_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_edge_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define VERTEX_SELECTION\n" - "#define VERTEX_FACING\n"); - } - if (!e_data.overlay_loose_edge_edgesel_sh) { - e_data.overlay_loose_edge_edgesel_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_edge_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define ANTI_ALIASING\n" - "#define EDGE_SELECTION\n" - "#define VERTEX_FACING\n"); - } - if (!e_data.overlay_loose_edge_vcol_edgesel_sh) { - e_data.overlay_loose_edge_vcol_edgesel_sh = DRW_shader_create_with_lib( - datatoc_edit_mesh_overlay_vert_glsl, - datatoc_edit_mesh_overlay_geom_edge_glsl, - datatoc_edit_mesh_overlay_frag_glsl, - datatoc_common_globals_lib_glsl, - "#define VERTEX_SELECTION\n" - "#define EDGE_SELECTION\n" - "#define VERTEX_FACING\n"); - } if (!e_data.overlay_vert_sh) { e_data.overlay_vert_sh = DRW_shader_create_with_lib( datatoc_edit_mesh_overlay_loosevert_vert_glsl, NULL, @@ -348,24 +299,9 @@ static DRWPass *edit_mesh_create_overlay_pass( RegionView3D *rv3d = draw_ctx->rv3d; Scene *scene = draw_ctx->scene; ToolSettings *tsettings = scene->toolsettings; - const bool in_edge_mode = (tsettings->selectmode & SCE_SELECT_EDGE) > 0; - - if ((tsettings->selectmode & SCE_SELECT_VERTEX) != 0) { - ledge_sh = in_edge_mode? e_data.overlay_loose_edge_vcol_edgesel_sh: e_data.overlay_loose_edge_vcol_sh; - if ((rv3d->rflag & RV3D_NAVIGATING) != 0) - tri_sh = in_edge_mode? e_data.overlay_tri_vcol_edgesel_fast_sh: e_data.overlay_tri_vcol_fast_sh; - else - tri_sh = in_edge_mode? e_data.overlay_tri_vcol_edgesel_sh: e_data.overlay_tri_vcol_sh; - } - else { - ledge_sh = in_edge_mode? e_data.overlay_loose_edge_edgesel_sh: e_data.overlay_loose_edge_sh; - - if ((rv3d->rflag & RV3D_NAVIGATING) != 0) - tri_sh = in_edge_mode? e_data.overlay_tri_edgesel_fast_sh: e_data.overlay_tri_fast_sh; - else - tri_sh = in_edge_mode? e_data.overlay_tri_edgesel_sh: e_data.overlay_tri_sh; - } + ledge_sh = EDIT_MESH_ensure_shader(tsettings, rv3d, false, true); + tri_sh = EDIT_MESH_ensure_shader(tsettings, rv3d, true, false); DRWPass *pass = DRW_pass_create( "Edit Mesh Face Overlay Pass", @@ -635,18 +571,6 @@ static void EDIT_MESH_draw_scene(void *vedata) static void EDIT_MESH_engine_free(void) { - DRW_SHADER_FREE_SAFE(e_data.overlay_tri_sh); - DRW_SHADER_FREE_SAFE(e_data.overlay_tri_fast_sh); - DRW_SHADER_FREE_SAFE(e_data.overlay_tri_vcol_sh); - DRW_SHADER_FREE_SAFE(e_data.overlay_tri_vcol_fast_sh); - DRW_SHADER_FREE_SAFE(e_data.overlay_tri_edgesel_sh); - DRW_SHADER_FREE_SAFE(e_data.overlay_tri_edgesel_fast_sh); - DRW_SHADER_FREE_SAFE(e_data.overlay_tri_vcol_edgesel_sh); - DRW_SHADER_FREE_SAFE(e_data.overlay_tri_vcol_edgesel_fast_sh); - DRW_SHADER_FREE_SAFE(e_data.overlay_loose_edge_sh); - DRW_SHADER_FREE_SAFE(e_data.overlay_loose_edge_vcol_sh); - DRW_SHADER_FREE_SAFE(e_data.overlay_loose_edge_edgesel_sh); - DRW_SHADER_FREE_SAFE(e_data.overlay_loose_edge_vcol_edgesel_sh); DRW_SHADER_FREE_SAFE(e_data.overlay_vert_sh); DRW_SHADER_FREE_SAFE(e_data.overlay_facedot_sh); DRW_SHADER_FREE_SAFE(e_data.overlay_mix_sh); @@ -654,6 +578,12 @@ static void EDIT_MESH_engine_free(void) DRW_SHADER_FREE_SAFE(e_data.normals_loop_sh); DRW_SHADER_FREE_SAFE(e_data.normals_face_sh); DRW_SHADER_FREE_SAFE(e_data.normals_sh); + + for (int i = 0; i < MAX_SHADERS; i++) + { + DRW_SHADER_FREE_SAFE(e_data.overlay_tri_sh_cache[i]); + DRW_SHADER_FREE_SAFE(e_data.overlay_loose_edge_sh_cache[i]); + } } static const DrawEngineDataSize EDIT_MESH_data_size = DRW_VIEWPORT_DATA_SIZE(EDIT_MESH_Data); |