Armature: Add ghosting support (old x-ray)

This commit is contained in:
Clément Foucault 2018-08-16 23:56:58 +02:00
parent 4711e0ee26
commit 77e1942e0e
2 changed files with 107 additions and 80 deletions

View File

@ -37,12 +37,12 @@ extern GlobalsUboStorage ts;
/* *********** LISTS *********** */
typedef struct EDIT_ARMATURE_PassList {
struct DRWPass *bone_solid;
struct DRWPass *bone_wire;
struct DRWPass *bone_outline;
struct DRWPass *bone_envelope;
struct DRWPass *bone_solid[2];
struct DRWPass *bone_wire[2];
struct DRWPass *bone_outline[2];
struct DRWPass *bone_envelope[2];
struct DRWPass *bone_axes;
struct DRWPass *relationship;
struct DRWPass *relationship[2];
} EDIT_ARMATURE_PassList;
typedef struct EDIT_ARMATURE_StorageList {
@ -77,43 +77,33 @@ static void EDIT_ARMATURE_cache_init(void *vedata)
}
stl->g_data->transparent_bones = (draw_ctx->v3d->overlay.arm_flag & V3D_OVERLAY_ARM_TRANSP_BONES) != 0;
{
for (int i = 0; i < 2; ++i) {
/* Solid bones */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK;
state |= (stl->g_data->transparent_bones) ? DRW_STATE_BLEND : DRW_STATE_WRITE_DEPTH;
psl->bone_solid = DRW_pass_create("Bone Solid Pass", state);
}
psl->bone_solid[i] = DRW_pass_create("Bone Solid Pass", state);
{
/* Bones Outline */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
psl->bone_outline = DRW_pass_create("Bone Outline Pass", state);
}
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
psl->bone_outline[i] = DRW_pass_create("Bone Outline Pass", state);
{
/* Wire bones */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND;
psl->bone_wire = DRW_pass_create("Bone Wire Pass", state);
}
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND;
psl->bone_wire[i] = DRW_pass_create("Bone Wire Pass", state);
{
/* distance outline around envelope bones */
DRWState state = DRW_STATE_ADDITIVE | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_FRONT;
psl->bone_envelope = DRW_pass_create("Bone Envelope Outline Pass", state);
state = DRW_STATE_ADDITIVE | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_FRONT;
psl->bone_envelope[i] = DRW_pass_create("Bone Envelope Outline Pass", state);
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);
}
{
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WIRE_SMOOTH | DRW_STATE_BLEND;
psl->bone_axes = DRW_pass_create("Bone Axes Pass", state);
}
{
/* Non Meshes Pass (Camera, empties, lamps ...) */
DRWState state =
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
DRW_STATE_BLEND | DRW_STATE_WIRE;
psl->relationship = DRW_pass_create("Bone Relationship Pass", state);
}
}
static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob)
@ -125,13 +115,15 @@ static void EDIT_ARMATURE_cache_populate(void *vedata, Object *ob)
EDIT_ARMATURE_PassList *psl = ((EDIT_ARMATURE_Data *)vedata)->psl;
EDIT_ARMATURE_StorageList *stl = ((EDIT_ARMATURE_Data *)vedata)->stl;
int ghost = (ob->dtx & OB_DRAWXRAY) ? 1 : 0;
DRWArmaturePasses passes = {
.bone_solid = psl->bone_solid,
.bone_outline = psl->bone_outline,
.bone_wire = psl->bone_wire,
.bone_envelope = psl->bone_envelope,
.bone_solid = psl->bone_solid[ghost],
.bone_outline = psl->bone_outline[ghost],
.bone_wire = psl->bone_wire[ghost],
.bone_envelope = psl->bone_envelope[ghost],
.bone_axes = psl->bone_axes,
.relationship_lines = psl->relationship,
.relationship_lines = psl->relationship[ghost],
};
DRW_shgroup_armature_edit(ob, passes, stl->g_data->transparent_bones);
}
@ -145,25 +137,43 @@ static void EDIT_ARMATURE_draw_scene(void *vedata)
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
DRW_draw_pass(psl->bone_envelope);
DRW_draw_pass(psl->bone_envelope[0]);
if (stl->g_data->transparent_bones) {
/* For performance reason, avoid blending on MS target. */
DRW_draw_pass(psl->bone_solid);
DRW_draw_pass(psl->bone_solid[0]);
}
MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl)
if (!stl->g_data->transparent_bones) {
DRW_draw_pass(psl->bone_solid);
DRW_draw_pass(psl->bone_solid[0]);
}
DRW_draw_pass(psl->bone_outline);
DRW_draw_pass(psl->bone_wire);
DRW_draw_pass(psl->relationship);
DRW_draw_pass(psl->bone_outline[0]);
DRW_draw_pass(psl->bone_wire[0]);
DRW_draw_pass(psl->relationship[0]);
MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl)
if (!DRW_pass_is_empty(psl->bone_envelope[1]) ||
!DRW_pass_is_empty(psl->bone_solid[1]) ||
!DRW_pass_is_empty(psl->bone_outline[1]) ||
!DRW_pass_is_empty(psl->bone_wire[1]) ||
!DRW_pass_is_empty(psl->relationship[1]))
{
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(dfbl->default_fb);
GPU_framebuffer_clear_depth(dfbl->default_fb, 1.0f);
}
DRW_draw_pass(psl->bone_envelope[1]);
DRW_draw_pass(psl->bone_solid[1]);
DRW_draw_pass(psl->bone_outline[1]);
DRW_draw_pass(psl->bone_wire[1]);
DRW_draw_pass(psl->relationship[1]);
}
/* Draw axes with linesmooth and outside of multisample buffer. */
DRW_draw_pass(psl->bone_axes);
}

View File

@ -47,12 +47,12 @@ extern GlobalsUboStorage ts;
* for POSE_PassList */
typedef struct POSE_PassList {
struct DRWPass *bone_solid;
struct DRWPass *bone_outline;
struct DRWPass *bone_wire;
struct DRWPass *bone_envelope;
struct DRWPass *bone_solid[2];
struct DRWPass *bone_outline[2];
struct DRWPass *bone_wire[2];
struct DRWPass *bone_envelope[2];
struct DRWPass *bone_axes;
struct DRWPass *relationship;
struct DRWPass *relationship[2];
struct DRWPass *bone_selection;
} POSE_PassList;
@ -118,28 +118,26 @@ static void POSE_cache_init(void *vedata)
POSE_PrivateData *ppd = stl->g_data;
ppd->transparent_bones = (draw_ctx->v3d->overlay.arm_flag & V3D_OVERLAY_ARM_TRANSP_BONES) != 0;
{
for (int i = 0; i < 2; ++i) {
/* Solid bones */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_BACK;
psl->bone_solid = DRW_pass_create("Bone Solid Pass", state);
}
psl->bone_solid[i] = DRW_pass_create("Bone Solid Pass", state);
{
/* Bones Outline */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
psl->bone_outline = DRW_pass_create("Bone Outline Pass", state);
}
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL;
psl->bone_outline[i] = DRW_pass_create("Bone Outline Pass", state);
{
/* Wire bones */
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND;
psl->bone_wire = DRW_pass_create("Bone Wire Pass", state);
}
state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND;
psl->bone_wire[i] = DRW_pass_create("Bone Wire Pass", state);
{
/* distance outline around envelope bones */
DRWState state = DRW_STATE_ADDITIVE | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_FRONT;
psl->bone_envelope = DRW_pass_create("Bone Envelope Outline Pass", state);
state = DRW_STATE_ADDITIVE | DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_CULL_FRONT;
psl->bone_envelope[i] = DRW_pass_create("Bone Envelope Outline Pass", state);
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);
}
{
@ -147,14 +145,6 @@ static void POSE_cache_init(void *vedata)
psl->bone_axes = DRW_pass_create("Bone Axes Pass", state);
}
{
/* Non Meshes Pass (Camera, empties, lamps ...) */
DRWState state =
DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS_EQUAL |
DRW_STATE_BLEND | DRW_STATE_WIRE;
psl->relationship = DRW_pass_create("Bone Relationship Pass", state);
}
{
if (POSE_is_bone_selection_overlay_active()) {
copy_v4_fl4(ppd->blend_color, 0.0f, 0.0f, 0.0f, v3d->overlay.bone_select_alpha);
@ -208,13 +198,15 @@ static void POSE_cache_populate(void *vedata, Object *ob)
return;
}
if (DRW_pose_mode_armature(ob, draw_ctx->obact)) {
int ghost = (ob->dtx & OB_DRAWXRAY) ? 1 : 0;
DRWArmaturePasses passes = {
.bone_solid = psl->bone_solid,
.bone_outline = psl->bone_outline,
.bone_wire = psl->bone_wire,
.bone_envelope = psl->bone_envelope,
.bone_solid = psl->bone_solid[ghost],
.bone_outline = psl->bone_outline[ghost],
.bone_wire = psl->bone_wire[ghost],
.bone_envelope = psl->bone_envelope[ghost],
.bone_axes = psl->bone_axes,
.relationship_lines = psl->relationship,
.relationship_lines = psl->relationship[ghost],
};
DRW_shgroup_armature_pose(ob, passes, ppd->transparent_bones);
}
@ -270,8 +262,10 @@ static void POSE_draw_scene(void *vedata)
const bool bone_selection_overlay = POSE_is_bone_selection_overlay_active();
if (DRW_state_is_select()) {
DRW_draw_pass(psl->bone_solid);
DRW_draw_pass(psl->bone_wire);
DRW_draw_pass(psl->bone_solid[0]);
DRW_draw_pass(psl->bone_wire[0]);
DRW_draw_pass(psl->bone_solid[1]);
DRW_draw_pass(psl->bone_wire[1]);
return;
}
@ -283,26 +277,49 @@ static void POSE_draw_scene(void *vedata)
GPU_framebuffer_bind(dfbl->default_fb);
}
DRW_draw_pass(psl->bone_envelope);
DRW_draw_pass(psl->bone_envelope[0]);
if (transparent_bones) {
DRW_pass_state_add(psl->bone_solid, DRW_STATE_BLEND);
DRW_pass_state_remove(psl->bone_solid, DRW_STATE_WRITE_DEPTH);
DRW_draw_pass(psl->bone_solid);
DRW_pass_state_add(psl->bone_solid[0], DRW_STATE_BLEND);
DRW_pass_state_remove(psl->bone_solid[0], DRW_STATE_WRITE_DEPTH);
DRW_draw_pass(psl->bone_solid[0]);
}
MULTISAMPLE_SYNC_ENABLE(dfbl, dtxl)
if (!transparent_bones) {
DRW_draw_pass(psl->bone_solid);
DRW_draw_pass(psl->bone_solid[0]);
}
DRW_draw_pass(psl->bone_outline);
DRW_draw_pass(psl->bone_wire);
DRW_draw_pass(psl->relationship);
DRW_draw_pass(psl->bone_outline[0]);
DRW_draw_pass(psl->bone_wire[0]);
DRW_draw_pass(psl->relationship[0]);
MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl)
if (!DRW_pass_is_empty(psl->bone_envelope[1]) ||
!DRW_pass_is_empty(psl->bone_solid[1]) ||
!DRW_pass_is_empty(psl->bone_outline[1]) ||
!DRW_pass_is_empty(psl->bone_wire[1]) ||
!DRW_pass_is_empty(psl->relationship[1]))
{
if (DRW_state_is_fbo()) {
GPU_framebuffer_bind(dfbl->default_fb);
GPU_framebuffer_clear_depth(dfbl->default_fb, 1.0f);
}
if (transparent_bones) {
DRW_pass_state_add(psl->bone_solid[1], DRW_STATE_BLEND);
DRW_pass_state_remove(psl->bone_solid[1], DRW_STATE_WRITE_DEPTH);
}
DRW_draw_pass(psl->bone_envelope[1]);
DRW_draw_pass(psl->bone_solid[1]);
DRW_draw_pass(psl->bone_outline[1]);
DRW_draw_pass(psl->bone_wire[1]);
DRW_draw_pass(psl->relationship[1]);
}
/* Draw axes with linesmooth and outside of multisample buffer. */
DRW_draw_pass(psl->bone_axes);
}