diff options
-rw-r--r-- | source/blender/draw/intern/draw_armature.c | 37 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.h | 1 | ||||
-rw-r--r-- | source/blender/draw/modes/edit_armature_mode.c | 1 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 12 | ||||
-rw-r--r-- | source/blender/draw/modes/pose_mode.c | 16 |
5 files changed, 57 insertions, 10 deletions
diff --git a/source/blender/draw/intern/draw_armature.c b/source/blender/draw/intern/draw_armature.c index 7d1f0568e63..801063aeebd 100644 --- a/source/blender/draw/intern/draw_armature.c +++ b/source/blender/draw/intern/draw_armature.c @@ -345,7 +345,6 @@ static void drw_shgroup_bone_custom_solid(const float (*bone_mat)[4], const eGPUShaderConfig sh_cfg, Object *custom) { - /* grr, not re-using instances! */ struct GPUBatch *surf = DRW_cache_object_surface_get(custom); struct GPUBatch *edges = DRW_cache_object_edge_detection_get(custom, NULL); struct GPUBatch *ledges = DRW_cache_object_loose_edges_get(custom); @@ -358,23 +357,43 @@ static void drw_shgroup_bone_custom_solid(const float (*bone_mat)[4], mul_m4_m4m4(final_bonemat, g_data.ob->obmat, bone_mat); } + BLI_assert(g_data.passes.custom_shapes != NULL); + if (surf && g_data.passes.bone_solid != NULL) { - DRWShadingGroup *shgrp_geom_solid = shgroup_instance_bone_shape_solid( - g_data.passes.bone_solid, surf, g_data.transparent, sh_cfg); + DRWShadingGroup *shgrp_geom_solid = BLI_ghash_lookup(g_data.passes.custom_shapes, surf); + + if (shgrp_geom_solid == NULL) { + /* NOTE! g_data.transparent require a separate shading group if the + * object is transparent. This is done by passing a different ghash + * for transparent armature in pose mode. */ + shgrp_geom_solid = shgroup_instance_bone_shape_solid( + g_data.passes.bone_solid, surf, g_data.transparent, sh_cfg); + BLI_ghash_insert(g_data.passes.custom_shapes, surf, shgrp_geom_solid); + } DRW_shgroup_call_dynamic_add(shgrp_geom_solid, final_bonemat, bone_color, hint_color); } if (edges && outline_color[3] > 0.0f) { - DRWShadingGroup *shgrp_geom_wire = shgroup_instance_bone_shape_outline( - g_data.passes.bone_outline, edges, sh_cfg); + DRWShadingGroup *shgrp_geom_wire = BLI_ghash_lookup(g_data.passes.custom_shapes, edges); + + if (shgrp_geom_wire == NULL) { + shgrp_geom_wire = shgroup_instance_bone_shape_outline( + g_data.passes.bone_outline, edges, sh_cfg); + + BLI_ghash_insert(g_data.passes.custom_shapes, edges, shgrp_geom_wire); + } DRW_shgroup_call_dynamic_add(shgrp_geom_wire, final_bonemat, outline_color); } if (ledges) { - DRWShadingGroup *shgrp_geom_ledges = shgroup_instance_wire(g_data.passes.bone_wire, ledges); - float final_color[4]; - copy_v3_v3(final_color, outline_color); - final_color[3] = 1.0f; /* hack */ + DRWShadingGroup *shgrp_geom_ledges = BLI_ghash_lookup(g_data.passes.custom_shapes, ledges); + + if (shgrp_geom_ledges == NULL) { + shgrp_geom_ledges = shgroup_instance_wire(g_data.passes.bone_wire, ledges); + + BLI_ghash_insert(g_data.passes.custom_shapes, ledges, shgrp_geom_ledges); + } + float final_color[4] = {outline_color[0], outline_color[1], outline_color[2], 1.0f}; DRW_shgroup_call_dynamic_add(shgrp_geom_ledges, final_bonemat, final_color); } } diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index db8f8d46e85..489bc7459df 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -216,6 +216,7 @@ typedef struct DRWArmaturePasses { struct DRWPass *bone_envelope; struct DRWPass *bone_axes; struct DRWPass *relationship_lines; + struct GHash *custom_shapes; } DRWArmaturePasses; void DRW_shgroup_armature_object(struct Object *ob, diff --git a/source/blender/draw/modes/edit_armature_mode.c b/source/blender/draw/modes/edit_armature_mode.c index 12bf4982ffb..d1ef0d0e104 100644 --- a/source/blender/draw/modes/edit_armature_mode.c +++ b/source/blender/draw/modes/edit_armature_mode.c @@ -126,6 +126,7 @@ static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob) .bone_envelope = psl->bone_envelope[ghost], .bone_axes = psl->bone_axes, .relationship_lines = psl->relationship[ghost], + .custom_shapes = NULL, /* Not needed in edit mode. */ }; DRW_shgroup_armature_edit(ob, passes, transp); } diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 7d42f59fea0..f7694f4a6f6 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -53,6 +53,8 @@ #include "BKE_particle.h" #include "BKE_tracking.h" +#include "BLI_ghash.h" + #include "ED_view3d.h" #include "GPU_batch.h" @@ -273,6 +275,8 @@ typedef struct OBJECT_PrivateData { OBJECT_ShadingGroupList sgl; OBJECT_ShadingGroupList sgl_ghost; + GHash *custom_shapes; + /* Outlines */ DRWShadingGroup *outlines_active; DRWShadingGroup *outlines_select; @@ -1040,6 +1044,8 @@ static void OBJECT_cache_init(void *vedata) g_data->xray_enabled_and_not_wire = g_data->xray_enabled && draw_ctx->v3d->shading.type > OB_WIRE; + g_data->custom_shapes = BLI_ghash_ptr_new(__func__); + { DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_WIRE; @@ -3288,6 +3294,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) .bone_envelope = sgl->bone_envelope, .bone_axes = sgl->bone_axes, .relationship_lines = NULL, /* Don't draw relationship lines */ + .custom_shapes = stl->g_data->custom_shapes, }; DRW_shgroup_armature_object(ob, view_layer, passes, is_wire); } @@ -3395,6 +3402,11 @@ static void OBJECT_cache_finish(void *vedata) DRW_pass_sort_shgroup_z(stl->g_data->sgl.image_empties); DRW_pass_sort_shgroup_z(stl->g_data->sgl_ghost.image_empties); + + if (stl->g_data->custom_shapes) { + /* TODO(fclem): Do not free it for each frame but reuse it. Avoiding alloc cost. */ + BLI_ghash_free(stl->g_data->custom_shapes, NULL, NULL); + } } static void OBJECT_draw_scene(void *vedata) diff --git a/source/blender/draw/modes/pose_mode.c b/source/blender/draw/modes/pose_mode.c index 5e3353414f5..a37901a1fa9 100644 --- a/source/blender/draw/modes/pose_mode.c +++ b/source/blender/draw/modes/pose_mode.c @@ -72,6 +72,7 @@ typedef struct POSE_Data { typedef struct POSE_PrivateData { DRWShadingGroup *bone_selection_shgrp; DRWShadingGroup *bone_selection_invert_shgrp; + GHash *custom_shapes[2]; float blend_color[4]; float blend_color_invert[4]; bool transparent_bones; @@ -139,6 +140,8 @@ static void POSE_cache_init(void *vedata) state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_WIRE; psl->relationship[i] = DRW_pass_create("Bone Relationship Pass", state); + + ppd->custom_shapes[i] = BLI_ghash_ptr_new(__func__); } { @@ -213,6 +216,7 @@ static void POSE_cache_populate(void *vedata, Object *ob) .bone_envelope = psl->bone_envelope[ghost], .bone_axes = psl->bone_axes, .relationship_lines = psl->relationship[ghost], + .custom_shapes = ppd->custom_shapes[transp], }; DRW_shgroup_armature_pose(ob, passes, transp); } @@ -231,6 +235,16 @@ static void POSE_cache_populate(void *vedata, Object *ob) } } +static void POSE_cache_finish(void *vedata) +{ + POSE_PrivateData *ppd = ((POSE_Data *)vedata)->stl->g_data; + + /* TODO(fclem): Do not free it for each frame but reuse it. Avoiding alloc cost. */ + for (int i = 0; i < 2; i++) { + BLI_ghash_free(ppd->custom_shapes[i], NULL, NULL); + } +} + /** * Return true if armature should be handled by the pose mode engine. */ @@ -323,7 +337,7 @@ DrawEngineType draw_engine_pose_type = { &POSE_engine_free, &POSE_cache_init, &POSE_cache_populate, - NULL, + &POSE_cache_finish, NULL, &POSE_draw_scene, NULL, |