Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2018-11-22 20:22:34 +0300
committerClément Foucault <foucault.clem@gmail.com>2018-11-22 20:31:03 +0300
commitf30271e3d41d3a2bb2be2ce15ff614a4d1a33f0a (patch)
tree4bccf9928c78250cfb8ea08c8e43bd487845f5fb /source/blender
parente16ef56a0dd02f882adaca1f7ea52cc2b02469f8 (diff)
Image Empties: Potential Fix for T57696
So far this makes a new pass for image empties that does not write to the depth buffer. Todo: - Sort empties using `DRW_pass_sort_shgroup_z`. - Calculate correct bounding boxes. - fix bounding box memory leak. Reviewers: fclem Differential Revision: https://developer.blender.org/D3922
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/draw/modes/object_mode.c143
-rw-r--r--source/blender/draw/modes/shaders/object_empty_image_vert.glsl28
2 files changed, 59 insertions, 112 deletions
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 824068a9800..88e30d65977 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -106,6 +106,7 @@ extern char datatoc_gpu_shader_uniform_color_frag_glsl[];
/* *********** LISTS *********** */
typedef struct OBJECT_PassList {
struct DRWPass *non_meshes[2];
+ struct DRWPass *image_empties[2];
struct DRWPass *spot_shapes[2];
struct DRWPass *ob_center;
struct DRWPass *outlines;
@@ -147,6 +148,7 @@ typedef struct OBJECT_Data {
typedef struct OBJECT_ShadingGroupList {
/* Reference only */
struct DRWPass *non_meshes;
+ struct DRWPass *image_empties;
struct DRWPass *spot_shapes;
struct DRWPass *bone_solid;
struct DRWPass *bone_outline;
@@ -167,8 +169,6 @@ typedef struct OBJECT_ShadingGroupList {
DRWShadingGroup *single_arrow;
DRWShadingGroup *single_arrow_line;
DRWShadingGroup *empty_axes;
- /* GPUTexture -> EmptyImageShadingGroupData */
- GHash *image_plane_map;
/* Force Field */
DRWShadingGroup *field_wind;
@@ -856,95 +856,48 @@ static void image_calc_aspect(Image *ima, ImageUser *iuser, float r_image_aspect
}
}
-/* per-image shading groups for image-type empty objects */
-struct EmptyImageShadingGroupData {
- DRWShadingGroup *shgrp_image;
- DRWShadingGroup *shgrp_wire;
- float image_aspect[2];
-};
-
static void DRW_shgroup_empty_image(
OBJECT_ShadingGroupList *sgl, Object *ob, const float color[3], RegionView3D *rv3d)
{
/* TODO: 'StereoViews', see draw_empty_image. */
- if (!BKE_image_empty_visible_in_view3d(ob, rv3d)) return;
-
- if (sgl->image_plane_map == NULL) {
- sgl->image_plane_map = BLI_ghash_ptr_new(__func__);
- }
-
- struct EmptyImageShadingGroupData *empty_image_data;
+ if (!BKE_image_empty_visible_in_view3d(ob, rv3d))
+ return;
GPUTexture *tex = ob->data ?
- GPU_texture_from_blender(ob->data, ob->iuser, GL_TEXTURE_2D, false, 0.0f) : NULL;
- void **val_p;
-
- /* Create on demand, 'tex' may be NULL. */
- if (BLI_ghash_ensure_p(sgl->image_plane_map, tex, &val_p)) {
- empty_image_data = *val_p;
- }
- else {
- empty_image_data = MEM_mallocN(sizeof(*empty_image_data), __func__);
-
- image_calc_aspect(ob->data, ob->iuser, empty_image_data->image_aspect);
-
- if (tex) {
- DRW_shgroup_instance_format(e_data.empty_image_format, {
- {"objectColor", DRW_ATTRIB_FLOAT, 4},
- {"size", DRW_ATTRIB_FLOAT, 1},
- {"offset", DRW_ATTRIB_FLOAT, 2},
- {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16},
- });
-
- struct GPUBatch *geom = DRW_cache_image_plane_get();
- DRWShadingGroup *grp = DRW_shgroup_instance_create(
- 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;
- }
- else {
- empty_image_data->shgrp_image = NULL;
- }
-
- {
- DRW_shgroup_instance_format(e_data.empty_image_wire_format, {
- {"color", DRW_ATTRIB_FLOAT, 4},
- {"size", DRW_ATTRIB_FLOAT, 1},
- {"offset", DRW_ATTRIB_FLOAT, 2},
- {"InstanceModelMatrix", DRW_ATTRIB_FLOAT, 16}
- });
+ GPU_texture_from_blender(ob->data, ob->iuser, GL_TEXTURE_2D, false, 0.0f) :
+ NULL;
- struct GPUBatch *geom = DRW_cache_image_plane_wire_get();
- 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);
+ float image_aspect[2];
+ image_calc_aspect(ob->data, ob->iuser, image_aspect);
- empty_image_data->shgrp_wire = grp;
- }
+ /* 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. */
- *val_p = empty_image_data;
+ if (tex && (ob->col[3] > 0.0f)) {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.object_empty_image_sh, 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->col, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_image_plane_get(), ob->obmat);
}
- if (empty_image_data->shgrp_image != NULL) {
- DRW_shgroup_call_dynamic_add(
- empty_image_data->shgrp_image,
- ob->col,
- &ob->empty_drawsize,
- ob->ima_ofs,
- ob->obmat);
- }
-
- DRW_shgroup_call_dynamic_add(
- empty_image_data->shgrp_wire,
- color,
- &ob->empty_drawsize,
- ob->ima_ofs,
- ob->obmat);
+ {
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.object_empty_image_wire_sh, 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, "color", color, 1);
+ DRW_shgroup_call_add(grp, DRW_cache_image_plane_wire_get(), ob->obmat);
+ }
}
static void OBJECT_cache_init(void *vedata)
@@ -1130,6 +1083,10 @@ static void OBJECT_cache_init(void *vedata)
DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_POINT | DRW_STATE_WIRE;
sgl->non_meshes = psl->non_meshes[i] = DRW_pass_create("Non Meshes Pass", state);
+ state = DRW_STATE_WRITE_COLOR |
+ DRW_STATE_DEPTH_LESS_EQUAL | DRW_STATE_BLEND | DRW_STATE_WIRE;
+ sgl->image_empties = psl->image_empties[i] = DRW_pass_create("Image Empties", state);
+
/* Empties */
geom = DRW_cache_plain_axes_get();
sgl->plain_axes = shgroup_instance(sgl->non_meshes, geom);
@@ -1167,9 +1124,6 @@ static void OBJECT_cache_init(void *vedata)
geom = DRW_cache_bone_arrows_get();
sgl->empty_axes = shgroup_instance_empty_axes(sgl->non_meshes, geom);
- /* initialize on first use */
- sgl->image_plane_map = NULL;
-
/* Force Field */
geom = DRW_cache_field_wind_get();
sgl->field_wind = shgroup_instance_scaled(sgl->non_meshes, geom);
@@ -2875,9 +2829,16 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
}
}
-static void OBJECT_draw_scene(void *vedata)
+static void OBJECT_cache_finish(void *vedata)
{
+ OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
+
+ DRW_pass_sort_shgroup_z(stl->g_data->sgl.image_empties);
+ DRW_pass_sort_shgroup_z(stl->g_data->sgl_ghost.image_empties);
+}
+static void OBJECT_draw_scene(void *vedata)
+{
OBJECT_PassList *psl = ((OBJECT_Data *)vedata)->psl;
OBJECT_StorageList *stl = ((OBJECT_Data *)vedata)->stl;
OBJECT_FramebufferList *fbl = ((OBJECT_Data *)vedata)->fbl;
@@ -2909,6 +2870,7 @@ static void OBJECT_draw_scene(void *vedata)
DRW_draw_pass(stl->g_data->sgl.bone_outline);
DRW_draw_pass(stl->g_data->sgl.non_meshes);
DRW_draw_pass(psl->particle);
+ DRW_draw_pass(stl->g_data->sgl.image_empties);
DRW_draw_pass(stl->g_data->sgl.bone_axes);
MULTISAMPLE_SYNC_DISABLE(dfbl, dtxl)
@@ -2963,12 +2925,6 @@ static void OBJECT_draw_scene(void *vedata)
}
}
- /* This has to be freed only after drawing empties! */
- if (stl->g_data->sgl.image_plane_map) {
- BLI_ghash_free(stl->g_data->sgl.image_plane_map, NULL, MEM_freeN);
- stl->g_data->sgl.image_plane_map = NULL;
- }
-
volumes_free_smoke_textures();
batch_camera_path_free(&stl->g_data->sgl.camera_path);
@@ -2976,6 +2932,7 @@ static void OBJECT_draw_scene(void *vedata)
!DRW_pass_is_empty(stl->g_data->sgl_ghost.bone_wire) ||
!DRW_pass_is_empty(stl->g_data->sgl_ghost.bone_outline) ||
!DRW_pass_is_empty(stl->g_data->sgl_ghost.non_meshes) ||
+ !DRW_pass_is_empty(stl->g_data->sgl_ghost.image_empties) ||
!DRW_pass_is_empty(stl->g_data->sgl_ghost.bone_axes))
{
if (DRW_state_is_fbo()) {
@@ -3005,6 +2962,7 @@ static void OBJECT_draw_scene(void *vedata)
DRW_draw_pass(stl->g_data->sgl_ghost.bone_wire);
DRW_draw_pass(stl->g_data->sgl_ghost.bone_outline);
DRW_draw_pass(stl->g_data->sgl_ghost.non_meshes);
+ DRW_draw_pass(stl->g_data->sgl_ghost.image_empties);
DRW_draw_pass(stl->g_data->sgl_ghost.bone_axes);
if (DRW_state_is_select()) {
@@ -3013,11 +2971,6 @@ static void OBJECT_draw_scene(void *vedata)
}
batch_camera_path_free(&stl->g_data->sgl_ghost.camera_path);
- /* This has to be freed only after drawing empties! */
- if (stl->g_data->sgl_ghost.image_plane_map) {
- BLI_ghash_free(stl->g_data->sgl_ghost.image_plane_map, NULL, MEM_freeN);
- stl->g_data->sgl_ghost.image_plane_map = NULL;
- }
DRW_draw_pass(psl->ob_center);
}
@@ -3032,7 +2985,7 @@ DrawEngineType draw_engine_object_type = {
&OBJECT_engine_free,
&OBJECT_cache_init,
&OBJECT_cache_populate,
- NULL,
+ &OBJECT_cache_finish,
NULL,
&OBJECT_draw_scene,
NULL,
diff --git a/source/blender/draw/modes/shaders/object_empty_image_vert.glsl b/source/blender/draw/modes/shaders/object_empty_image_vert.glsl
index c1a957f0640..3469e37358e 100644
--- a/source/blender/draw/modes/shaders/object_empty_image_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_empty_image_vert.glsl
@@ -1,21 +1,16 @@
-
-uniform mat4 ViewProjectionMatrix;
-uniform vec2 aspect;
-
-/* ---- Instantiated Attribs ---- */
-in vec2 texCoord;
-in vec2 pos;
-/* ---- Per instance Attribs ---- */
-in mat4 InstanceModelMatrix;
-
+uniform mat4 ModelViewProjectionMatrix;
+uniform float aspectX;
+uniform float aspectY;
+uniform float size;
+uniform vec2 offset;
#ifdef USE_WIRE
-in vec3 color;
+uniform vec3 color;
#else
-in vec4 objectColor;
+uniform vec4 objectColor;
#endif
-in float size;
-in vec2 offset;
+in vec2 texCoord;
+in vec2 pos;
flat out vec4 finalColor;
@@ -25,9 +20,8 @@ out vec2 texCoord_interp;
void main()
{
- gl_Position = ViewProjectionMatrix * InstanceModelMatrix * vec4(
- (pos[0] + offset[0]) * (size * aspect[0]),
- (pos[1] + offset[1]) * (size * aspect[1]),
+ gl_Position = ModelViewProjectionMatrix * vec4(
+ (pos + offset) * (size * vec2(aspectX, aspectY)),
0.0, 1.0);
#ifdef USE_WIRE
finalColor = vec4(color, 1.0);