Image Empties: More visibility settings
Support for showing images in background/foreground and only in perspective/orthographic view. Internally the depth of the image is modified in the fragment shader by setting `gl_FragDepth` explicitly. The UI still needs some work to improve usability, see D3863 for details. Currently there is one duplicated function, not sure how to best deduplicate it yet. (`is_image_empty_visible`) Reviewer: fclem, brecht, campbellbarton Differential Revision: https://developer.blender.org/D3863
This commit is contained in:
parent
0727abf1bc
commit
a3802f66e2
|
@ -56,6 +56,10 @@ class DATA_PT_empty(DataButtonsPanel, Panel):
|
|||
layout.separator()
|
||||
|
||||
layout.prop(ob, "empty_display_size", text="Size")
|
||||
layout.prop(ob, "empty_image_depth", text="Depth", expand=True)
|
||||
|
||||
layout.prop(ob, "show_empty_image_orthographic", text="Display Orthographic")
|
||||
layout.prop(ob, "show_empty_image_perspective", text="Display Perspective")
|
||||
|
||||
|
||||
classes = (
|
||||
|
|
|
@ -832,6 +832,10 @@ void BKE_object_init(Object *ob)
|
|||
ob->dt = OB_TEXTURE;
|
||||
ob->empty_drawtype = OB_PLAINAXES;
|
||||
ob->empty_drawsize = 1.0;
|
||||
ob->empty_image_depth = OB_EMPTY_IMAGE_DEPTH_DEFAULT;
|
||||
ob->empty_image_visibility_flag = (
|
||||
OB_EMPTY_IMAGE_VISIBLE_PERSPECTIVE
|
||||
| OB_EMPTY_IMAGE_VISIBLE_ORTHOGRAPHIC);
|
||||
if (ob->type == OB_EMPTY) {
|
||||
copy_v2_fl(ob->ima_ofs, -0.5f);
|
||||
}
|
||||
|
|
|
@ -2220,5 +2220,10 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
|
||||
ob->empty_image_visibility_flag = (
|
||||
OB_EMPTY_IMAGE_VISIBLE_PERSPECTIVE
|
||||
| OB_EMPTY_IMAGE_VISIBLE_ORTHOGRAPHIC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -419,14 +419,23 @@ static void OBJECT_engine_init(void *vedata)
|
|||
e_data.outline_fade_sh = DRW_shader_create_fullscreen(datatoc_object_outline_expand_frag_glsl, NULL);
|
||||
|
||||
/* Empty images */
|
||||
# define EMPTY_IMAGE_SHADER_DEFINES \
|
||||
"#define DEPTH_UNCHANGED " STRINGIFY(OB_EMPTY_IMAGE_DEPTH_DEFAULT) "\n" \
|
||||
"#define DEPTH_FRONT " STRINGIFY(OB_EMPTY_IMAGE_DEPTH_FRONT) "\n" \
|
||||
"#define DEPTH_BACK " STRINGIFY(OB_EMPTY_IMAGE_DEPTH_BACK) "\n"
|
||||
|
||||
e_data.object_empty_image_sh = DRW_shader_create(
|
||||
datatoc_object_empty_image_vert_glsl, NULL,
|
||||
datatoc_object_empty_image_frag_glsl, NULL);
|
||||
datatoc_object_empty_image_vert_glsl, NULL,
|
||||
datatoc_object_empty_image_frag_glsl,
|
||||
EMPTY_IMAGE_SHADER_DEFINES);
|
||||
|
||||
e_data.object_empty_image_wire_sh = DRW_shader_create(
|
||||
datatoc_object_empty_image_vert_glsl, NULL,
|
||||
datatoc_object_empty_image_frag_glsl,
|
||||
"#define USE_WIRE\n");
|
||||
datatoc_object_empty_image_vert_glsl, NULL,
|
||||
datatoc_object_empty_image_frag_glsl,
|
||||
EMPTY_IMAGE_SHADER_DEFINES
|
||||
"#define USE_WIRE\n");
|
||||
|
||||
# undef EMPTY_IMAGE_SHADER_DEFINES
|
||||
|
||||
/* Grid */
|
||||
e_data.grid_sh = DRW_shader_create_with_lib(
|
||||
|
@ -847,6 +856,17 @@ static void image_calc_aspect(Image *ima, ImageUser *iuser, float r_image_aspect
|
|||
}
|
||||
}
|
||||
|
||||
static bool is_image_empty_visible(Object *ob, RegionView3D *rv3d)
|
||||
{
|
||||
int visibility_flag = ob->empty_image_visibility_flag;
|
||||
if (rv3d->is_persp) {
|
||||
return visibility_flag & OB_EMPTY_IMAGE_VISIBLE_PERSPECTIVE;
|
||||
}
|
||||
else {
|
||||
return visibility_flag & OB_EMPTY_IMAGE_VISIBLE_ORTHOGRAPHIC;
|
||||
}
|
||||
}
|
||||
|
||||
/* per-image shading groups for image-type empty objects */
|
||||
struct EmptyImageShadingGroupData {
|
||||
DRWShadingGroup *shgrp_image;
|
||||
|
@ -855,10 +875,12 @@ struct EmptyImageShadingGroupData {
|
|||
};
|
||||
|
||||
static void DRW_shgroup_empty_image(
|
||||
OBJECT_ShadingGroupList *sgl, Object *ob, const float color[3])
|
||||
OBJECT_ShadingGroupList *sgl, Object *ob, const float color[3], RegionView3D *rv3d)
|
||||
{
|
||||
/* TODO: 'StereoViews', see draw_empty_image. */
|
||||
|
||||
if (!is_image_empty_visible(ob, rv3d)) return;
|
||||
|
||||
if (sgl->image_plane_map == NULL) {
|
||||
sgl->image_plane_map = BLI_ghash_ptr_new(__func__);
|
||||
}
|
||||
|
@ -891,6 +913,7 @@ static void DRW_shgroup_empty_image(
|
|||
e_data.object_empty_image_sh, sgl->non_meshes, geom, e_data.empty_image_format);
|
||||
DRW_shgroup_uniform_texture(grp, "image", tex);
|
||||
DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1);
|
||||
DRW_shgroup_uniform_int_copy(grp, "depthMode", ob->empty_image_depth);
|
||||
|
||||
empty_image_data->shgrp_image = grp;
|
||||
}
|
||||
|
@ -910,6 +933,7 @@ static void DRW_shgroup_empty_image(
|
|||
DRWShadingGroup *grp = DRW_shgroup_instance_create(
|
||||
e_data.object_empty_image_wire_sh, sgl->non_meshes, geom, e_data.empty_image_wire_format);
|
||||
DRW_shgroup_uniform_vec2(grp, "aspect", empty_image_data->image_aspect, 1);
|
||||
DRW_shgroup_uniform_int_copy(grp, "depthMode", ob->empty_image_depth);
|
||||
|
||||
empty_image_data->shgrp_wire = grp;
|
||||
}
|
||||
|
@ -1853,7 +1877,7 @@ static void DRW_shgroup_empty_ex(
|
|||
}
|
||||
}
|
||||
|
||||
static void DRW_shgroup_empty(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLayer *view_layer)
|
||||
static void DRW_shgroup_empty(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLayer *view_layer, RegionView3D *rv3d)
|
||||
{
|
||||
float *color;
|
||||
DRW_object_wire_theme_get(ob, view_layer, &color);
|
||||
|
@ -1869,7 +1893,7 @@ static void DRW_shgroup_empty(OBJECT_ShadingGroupList *sgl, Object *ob, ViewLaye
|
|||
DRW_shgroup_empty_ex(sgl, ob->obmat, &ob->empty_drawsize, ob->empty_drawtype, color);
|
||||
break;
|
||||
case OB_EMPTY_IMAGE:
|
||||
DRW_shgroup_empty_image(sgl, ob, color);
|
||||
DRW_shgroup_empty_image(sgl, ob, color, rv3d);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2756,7 +2780,7 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
|
|||
if (hide_object_extra) {
|
||||
break;
|
||||
}
|
||||
DRW_shgroup_empty(sgl, ob, view_layer);
|
||||
DRW_shgroup_empty(sgl, ob, view_layer, rv3d);
|
||||
break;
|
||||
case OB_GPENCIL:
|
||||
if (hide_object_extra) {
|
||||
|
|
|
@ -11,6 +11,8 @@ out vec4 fragColor;
|
|||
uniform sampler2D image;
|
||||
#endif
|
||||
|
||||
uniform int depthMode;
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef USE_WIRE
|
||||
|
@ -18,4 +20,14 @@ void main()
|
|||
#else
|
||||
fragColor = finalColor * texture(image, texCoord_interp);
|
||||
#endif
|
||||
|
||||
if (depthMode == DEPTH_BACK) {
|
||||
gl_FragDepth = 0.999999;
|
||||
}
|
||||
else if (depthMode == DEPTH_FRONT) {
|
||||
gl_FragDepth = 0.000001;
|
||||
}
|
||||
else if (depthMode == DEPTH_UNCHANGED) {
|
||||
gl_FragDepth = gl_FragCoord.z;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -107,9 +107,21 @@ static void gizmo_empty_image_prop_matrix_set(
|
|||
ob->ima_ofs[1] = (matrix[3][1] - (0.5f * dims[1])) / dims[1];
|
||||
}
|
||||
|
||||
static bool is_image_empty_visible(Object *ob, RegionView3D *rv3d)
|
||||
{
|
||||
int visibility_flag = ob->empty_image_visibility_flag;
|
||||
if (rv3d->is_persp) {
|
||||
return visibility_flag & OB_EMPTY_IMAGE_VISIBLE_PERSPECTIVE;
|
||||
}
|
||||
else {
|
||||
return visibility_flag & OB_EMPTY_IMAGE_VISIBLE_ORTHOGRAPHIC;
|
||||
}
|
||||
}
|
||||
|
||||
static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmGizmoGroupType *UNUSED(gzgt))
|
||||
{
|
||||
View3D *v3d = CTX_wm_view3d(C);
|
||||
RegionView3D *rv3d = CTX_wm_region_view3d(C);
|
||||
|
||||
if ((v3d->flag2 & V3D_RENDER_OVERRIDE) ||
|
||||
(v3d->gizmo_flag & (V3D_GIZMO_HIDE | V3D_GIZMO_HIDE_CONTEXT)))
|
||||
|
@ -120,7 +132,9 @@ static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmGizmoGroupType *UN
|
|||
Object *ob = CTX_data_active_object(C);
|
||||
|
||||
if (ob && ob->type == OB_EMPTY) {
|
||||
return (ob->empty_drawtype == OB_EMPTY_IMAGE);
|
||||
if (ob->empty_drawtype == OB_EMPTY_IMAGE){
|
||||
return is_image_empty_visible(ob, rv3d);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -296,6 +296,9 @@ typedef struct Object {
|
|||
|
||||
float ima_ofs[2]; /* offset for image empties */
|
||||
ImageUser *iuser; /* must be non-null when object is an empty image */
|
||||
char empty_image_visibility_flag;
|
||||
char empty_image_depth;
|
||||
char pad11[6];
|
||||
|
||||
ListBase lodlevels; /* contains data for levels of detail */
|
||||
LodLevel *currentlod;
|
||||
|
@ -596,6 +599,17 @@ enum {
|
|||
OB_DUPLI_FLAG_RENDER = 1 << 1,
|
||||
};
|
||||
|
||||
/* ob->empty_image_depth */
|
||||
#define OB_EMPTY_IMAGE_DEPTH_DEFAULT 0
|
||||
#define OB_EMPTY_IMAGE_DEPTH_FRONT 1
|
||||
#define OB_EMPTY_IMAGE_DEPTH_BACK 2
|
||||
|
||||
/* ob->empty_image_visibility_flag */
|
||||
enum {
|
||||
OB_EMPTY_IMAGE_VISIBLE_PERSPECTIVE = 1 << 0,
|
||||
OB_EMPTY_IMAGE_VISIBLE_ORTHOGRAPHIC = 1 << 1,
|
||||
};
|
||||
|
||||
#define MAX_DUPLI_RECUR 8
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -110,6 +110,13 @@ const EnumPropertyItem rna_enum_object_empty_drawtype_items[] = {
|
|||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_object_empty_image_depth_items[] = {
|
||||
{OB_EMPTY_IMAGE_DEPTH_DEFAULT, "DEFAULT", 0, "Default", ""},
|
||||
{OB_EMPTY_IMAGE_DEPTH_FRONT, "FRONT", 0, "Front", ""},
|
||||
{OB_EMPTY_IMAGE_DEPTH_BACK, "BACK", 0, "Back", ""},
|
||||
{0, NULL, 0, NULL, NULL}
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_object_gpencil_type_items[] = {
|
||||
{GP_EMPTY, "EMPTY", ICON_GP_EMPTY, "Blank", "Create an empty grease pencil object"},
|
||||
{GP_STROKE, "STROKE", ICON_GP_STROKE, "Stroke", "Create a simple stroke with basic colors"},
|
||||
|
@ -2488,6 +2495,21 @@ static void rna_def_object(BlenderRNA *brna)
|
|||
"Parameters defining which layer, pass and frame of the image is displayed");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "empty_image_depth", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_object_empty_image_depth_items);
|
||||
RNA_def_property_ui_text(prop, "Empty Image Depth", "Determine which other objects will occlude the image");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_empty_image_perspective", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "empty_image_visibility_flag", OB_EMPTY_IMAGE_VISIBLE_PERSPECTIVE);
|
||||
RNA_def_property_ui_text(prop, "Display in Perspective Mode", "Display image in perspective mode");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
|
||||
|
||||
prop = RNA_def_property(srna, "show_empty_image_orthographic", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "empty_image_visibility_flag", OB_EMPTY_IMAGE_VISIBLE_ORTHOGRAPHIC);
|
||||
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);
|
||||
|
||||
/* render */
|
||||
prop = RNA_def_property(srna, "pass_index", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "index");
|
||||
|
|
Loading…
Reference in New Issue