Fix T58550 Dragged in images dont overlap properly

This patch adds a new "Use Alpha" option on image empties to avoid ordering
issue of reference images.

If ordering is not important, "Use Alpha" can be enabled to provide
transparency and alpha blending support.
This commit is contained in:
Clément Foucault 2019-03-20 16:33:17 +01:00
parent 3508ffc34c
commit c5fc861172
Notes: blender-bot 2023-02-14 04:46:16 +01:00
Referenced by issue #59307, Wrong display of mesh in front of images, on macOS
Referenced by issue #58550, Dragged in images dont overlap properly
5 changed files with 54 additions and 22 deletions

View File

@ -48,7 +48,12 @@ class DATA_PT_empty(DataButtonsPanel, Panel):
layout.row(align=True).row(align=True)
layout.prop(ob, "color", text="Transparency", index=3, slider=True)
layout.prop(ob, "empty_image_use_alpha")
col = layout.column()
col.active = ob.empty_image_use_transparency
col.prop(ob, "color", text="Transparency", index=3, slider=True)
col = layout.column(align=True)
col.prop(ob, "empty_image_offset", text="Offset X", index=0)
col.prop(ob, "empty_image_offset", text="Y", index=1)

View File

@ -927,6 +927,7 @@ static void DRW_shgroup_empty_image(
/* Calling 'BKE_image_get_size' may free the texture. Get the size from 'tex' instead, see: T59347 */
int size[2] = {0};
const bool use_alpha_blend = (ob->empty_image_flag & OB_EMPTY_IMAGE_USE_ALPHA_BLEND) != 0;
GPUTexture *tex = NULL;
if (ob->data != NULL) {
@ -943,25 +944,6 @@ static void DRW_shgroup_empty_image(
float image_aspect[2];
image_calc_aspect(ob->data, size, image_aspect);
/* OPTI(fclem) We need sorting only for transparent images. If an image as no alpha channel and
* ob->col[3] == 1.0f, we could remove it from the sorting pass. */
if (tex && (ob->color[3] > 0.0f) && BKE_object_empty_image_data_is_visible_in_view3d(ob, rv3d)) {
DRWShadingGroup *grp = DRW_shgroup_create(sh_data->object_empty_image, sgl->image_empties);
DRW_shgroup_uniform_texture(grp, "image", tex);
/* TODO(fclem) implement DRW_shgroup_uniform_vec2_copy */
DRW_shgroup_uniform_float_copy(grp, "aspectX", image_aspect[0]);
DRW_shgroup_uniform_float_copy(grp, "aspectY", image_aspect[1]);
DRW_shgroup_uniform_int_copy(grp, "depthMode", ob->empty_image_depth);
DRW_shgroup_uniform_float(grp, "size", &ob->empty_drawsize, 1);
DRW_shgroup_uniform_vec2(grp, "offset", ob->ima_ofs, 1);
DRW_shgroup_uniform_vec4(grp, "objectColor", ob->color, 1);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
DRW_shgroup_call_add(grp, DRW_cache_image_plane_get(), ob->obmat);
}
{
DRWShadingGroup *grp = DRW_shgroup_create(sh_data->object_empty_image_wire, sgl->non_meshes);
/* TODO(fclem) implement DRW_shgroup_uniform_vec2_copy */
@ -976,6 +958,27 @@ static void DRW_shgroup_empty_image(
}
DRW_shgroup_call_add(grp, DRW_cache_image_plane_wire_get(), ob->obmat);
}
if (!BKE_object_empty_image_data_is_visible_in_view3d(ob, rv3d)) {
return;
}
if (tex && ((ob->color[3] > 0.0f) || !use_alpha_blend)) {
DRWShadingGroup *grp = DRW_shgroup_create(sh_data->object_empty_image,
(use_alpha_blend) ? sgl->image_empties : sgl->non_meshes);
DRW_shgroup_uniform_float_copy(grp, "aspectX", image_aspect[0]);
DRW_shgroup_uniform_float_copy(grp, "aspectY", image_aspect[1]);
DRW_shgroup_uniform_int_copy(grp, "depthMode", ob->empty_image_depth);
DRW_shgroup_uniform_float(grp, "size", &ob->empty_drawsize, 1);
DRW_shgroup_uniform_vec2(grp, "offset", ob->ima_ofs, 1);
DRW_shgroup_uniform_texture(grp, "image", tex);
DRW_shgroup_uniform_vec4(grp, "objectColor", ob->color, 1);
DRW_shgroup_uniform_bool_copy(grp, "useAlphaTest", !use_alpha_blend);
if (sh_cfg == GPU_SHADER_CFG_CLIPPED) {
DRW_shgroup_world_clip_planes_from_rv3d(grp, DRW_context_state_get()->rv3d);
}
DRW_shgroup_call_add(grp, DRW_cache_image_plane_get(), ob->obmat);
}
}
static void OBJECT_cache_init(void *vedata)

View File

@ -12,13 +12,26 @@ uniform sampler2D image;
#endif
uniform int depthMode;
uniform bool useAlphaTest;
void main()
{
#ifdef USE_WIRE
fragColor = finalColor;
#else
fragColor = finalColor * texture(image, texCoord_interp);
vec4 tex_col = texture(image, texCoord_interp);
fragColor = finalColor * tex_col;
if (useAlphaTest) {
/* Arbitrary discard anything below 5% opacity.
* Note that this could be exposed to the User. */
if (tex_col.a < 0.05) {
discard;
}
else {
fragColor.a = 1.0;
}
}
#endif
if (depthMode == DEPTH_BACK) {

View File

@ -372,7 +372,8 @@ typedef struct Object {
ImageUser *iuser;
char empty_image_visibility_flag;
char empty_image_depth;
char _pad8[2];
char empty_image_flag;
char _pad8[1];
int select_id;
@ -670,6 +671,11 @@ enum {
OB_EMPTY_IMAGE_HIDE_FRONT = 1 << 3,
};
/** #Object.empty_image_flag */
enum {
OB_EMPTY_IMAGE_USE_ALPHA_BLEND = 1 << 0,
};
#define MAX_DUPLI_RECUR 8
#ifdef __cplusplus

View File

@ -2505,6 +2505,11 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Display in Orthographic Mode", "Display image in orthographic mode");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
prop = RNA_def_property(srna, "empty_image_use_alpha", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "empty_image_flag", OB_EMPTY_IMAGE_USE_ALPHA_BLEND);
RNA_def_property_ui_text(prop, "Use Alpha", "Use alpha blending instead of alpha test (can produce sorting artifacts)");
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
static EnumPropertyItem prop_empty_image_side_items[] = {
{0, "DOUBLE_SIDED", 0, "Both", ""},
{OB_EMPTY_IMAGE_HIDE_BACK, "FRONT", 0, "Front", ""},