diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2019-03-20 18:33:17 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2019-03-20 18:33:49 +0300 |
commit | c5fc861172879102034129ecbe653e91eeff5caf (patch) | |
tree | 8619b3e2b97f48eeaac874b28c9db999fedf5c76 /source | |
parent | 3508ffc34c1f742e6a798814b80075ccbe1baa22 (diff) |
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.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 29 | ||||
-rw-r--r-- | source/blender/draw/modes/shaders/object_empty_image_frag.glsl | 15 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_types.h | 8 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_object.c | 5 |
4 files changed, 42 insertions, 15 deletions
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 4fad882a7b5..5cacfd0e941 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -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,38 +944,40 @@ 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); + { + DRWShadingGroup *grp = DRW_shgroup_create(sh_data->object_empty_image_wire, sgl->non_meshes); /* 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); + DRW_shgroup_uniform_vec3(grp, "color", 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); + DRW_shgroup_call_add(grp, DRW_cache_image_plane_wire_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 */ + 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_vec3(grp, "color", color, 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_wire_get(), ob->obmat); + DRW_shgroup_call_add(grp, DRW_cache_image_plane_get(), ob->obmat); } } diff --git a/source/blender/draw/modes/shaders/object_empty_image_frag.glsl b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl index e47b28d80c6..c20d70e3b06 100644 --- a/source/blender/draw/modes/shaders/object_empty_image_frag.glsl +++ b/source/blender/draw/modes/shaders/object_empty_image_frag.glsl @@ -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) { diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 136acb9dc1c..e97ae722457 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -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 diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c index f320ce925ff..ec0e9e6f7d7 100644 --- a/source/blender/makesrna/intern/rna_object.c +++ b/source/blender/makesrna/intern/rna_object.c @@ -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", ""}, |