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:
-rw-r--r--source/blender/draw/CMakeLists.txt3
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_uv.c79
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.h18
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader.c20
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_image_mask_frag.glsl14
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_image_vert.glsl (renamed from source/blender/draw/engines/overlay/shaders/edit_uv_stencil_image_vert.glsl)0
-rw-r--r--source/blender/draw/tests/shaders_test.cc1
-rw-r--r--source/blender/editors/space_image/space_image.c3
8 files changed, 129 insertions, 9 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index a6cc9fddd69..9b716eeeed3 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -379,7 +379,8 @@ data_to_c_simple(engines/overlay/shaders/edit_uv_verts_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/edit_uv_verts_frag.glsl SRC)
data_to_c_simple(engines/overlay/shaders/edit_uv_faces_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/edit_uv_face_dots_vert.glsl SRC)
-data_to_c_simple(engines/overlay/shaders/edit_uv_stencil_image_vert.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/edit_uv_image_vert.glsl SRC)
+data_to_c_simple(engines/overlay/shaders/edit_uv_image_mask_frag.glsl SRC)
data_to_c_simple(engines/overlay/shaders/edit_uv_stretching_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/edit_uv_tiled_image_borders_vert.glsl SRC)
data_to_c_simple(engines/overlay/shaders/extra_frag.glsl SRC)
diff --git a/source/blender/draw/engines/overlay/overlay_edit_uv.c b/source/blender/draw/engines/overlay/overlay_edit_uv.c
index 045a38ef374..edc817ac7c1 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_uv.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_uv.c
@@ -26,11 +26,14 @@
#include "BKE_editmesh.h"
#include "BKE_image.h"
+#include "BKE_mask.h"
#include "BKE_paint.h"
#include "DNA_brush_types.h"
#include "DNA_mesh_types.h"
+#include "DEG_depsgraph_query.h"
+
#include "ED_image.h"
#include "IMB_imbuf_types.h"
@@ -70,6 +73,27 @@ static OVERLAY_UVLineStyle edit_uv_line_style_from_space_image(const SpaceImage
}
}
+/* TODO(jbakker): the GPU texture should be cached with the mask. */
+static GPUTexture *edit_uv_mask_texture(
+ Mask *mask, const int width, const int height_, const float aspx, const float aspy)
+{
+ const int height = (float)height_ * (aspy / aspx);
+ MaskRasterHandle *handle;
+ float *buffer = MEM_mallocN(sizeof(float) * height * width, __func__);
+
+ /* Initialize rasterization handle. */
+ handle = BKE_maskrasterize_handle_new();
+ BKE_maskrasterize_handle_init(handle, mask, width, height, true, true, true);
+
+ BKE_maskrasterize_buffer(handle, width, height, buffer);
+
+ /* Free memory. */
+ BKE_maskrasterize_handle_free(handle);
+ GPUTexture *texture = GPU_texture_create_2d(mask->id.name, width, height, 1, GPU_R16F, buffer);
+ MEM_freeN(buffer);
+ return texture;
+}
+
/* -------------------------------------------------------------------- */
/** \name Internal API
* \{ */
@@ -93,6 +117,7 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
const bool has_edit_object = (draw_ctx->object_edit) != NULL;
const bool is_paint_mode = sima->mode == SI_MODE_PAINT;
const bool is_view_mode = sima->mode == SI_MODE_VIEW;
+ const bool is_mask_mode = sima->mode == SI_MODE_MASK;
const bool is_edit_mode = draw_ctx->object_mode == OB_MODE_EDIT;
const bool do_uv_overlay = is_image_type && is_uv_editor && has_edit_object;
const bool show_modified_uvs = sima->flag & SI_DRAWSHADOW;
@@ -118,6 +143,14 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
(is_view_mode && do_tex_paint_shadows &&
((draw_ctx->object_mode & (OB_MODE_TEXTURE_PAINT)) != 0)) ||
(do_uv_overlay && (show_modified_uvs)));
+
+ pd->edit_uv.do_mask_overlay = show_overlays && is_mask_mode && (sima->mask_info.mask != NULL) &&
+ ((sima->mask_info.draw_flag & MASK_DRAWFLAG_OVERLAY) != 0);
+ pd->edit_uv.mask_overlay_mode = sima->mask_info.overlay_mode;
+ pd->edit_uv.mask = sima->mask_info.mask ? (Mask *)DEG_get_evaluated_id(
+ draw_ctx->depsgraph, &sima->mask_info.mask->id) :
+ NULL;
+
pd->edit_uv.do_uv_stretching_overlay = show_overlays && do_uvstretching_overlay;
pd->edit_uv.uv_opacity = sima->uv_opacity;
pd->edit_uv.do_tiled_image_overlay = show_overlays && is_image_type && is_tiled_image;
@@ -132,7 +165,12 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
pd->edit_uv.total_area_ratio = 0.0f;
pd->edit_uv.total_area_ratio_inv = 0.0f;
- ED_space_image_get_uv_aspect(sima, &pd->edit_uv.aspect[0], &pd->edit_uv.aspect[1]);
+ /* During engine init phase the sima isn't locked and we are able to retrieve the needed data.
+ * During cache_init the image engine locks the sima and makes it imposible to retrieve the data.
+ */
+ ED_space_image_get_uv_aspect(sima, &pd->edit_uv.uv_aspect[0], &pd->edit_uv.uv_aspect[1]);
+ ED_space_image_get_size(sima, &pd->edit_uv.image_size[0], &pd->edit_uv.image_size[1]);
+ ED_space_image_get_aspect(sima, &pd->edit_uv.image_aspect[0], &pd->edit_uv.image_aspect[1]);
}
void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
@@ -225,7 +263,7 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
GPUShader *sh = OVERLAY_shader_edit_uv_stretching_angle_get();
pd->edit_uv_stretching_grp = DRW_shgroup_create(sh, psl->edit_uv_stretching_ps);
DRW_shgroup_uniform_block(pd->edit_uv_stretching_grp, "globalsBlock", G_draw.block_ubo);
- DRW_shgroup_uniform_vec2_copy(pd->edit_uv_stretching_grp, "aspect", pd->edit_uv.aspect);
+ DRW_shgroup_uniform_vec2_copy(pd->edit_uv_stretching_grp, "aspect", pd->edit_uv.uv_aspect);
}
else /* SI_UVDT_STRETCH_AREA */ {
GPUShader *sh = OVERLAY_shader_edit_uv_stretching_area_get();
@@ -334,6 +372,26 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
pd->edit_uv.stencil_ibuf = NULL;
pd->edit_uv.stencil_image = NULL;
}
+
+ if (pd->edit_uv.do_mask_overlay) {
+ const bool is_combined_overlay = pd->edit_uv.mask_overlay_mode == MASK_OVERLAY_COMBINED;
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS;
+ state |= is_combined_overlay ? DRW_STATE_BLEND_MUL : DRW_STATE_BLEND_ALPHA;
+ DRW_PASS_CREATE(psl->edit_uv_mask_ps, state);
+
+ GPUShader *sh = OVERLAY_shader_edit_uv_mask_image();
+ GPUBatch *geom = DRW_cache_quad_get();
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->edit_uv_mask_ps);
+ GPUTexture *mask_texture = edit_uv_mask_texture(pd->edit_uv.mask,
+ pd->edit_uv.image_size[0],
+ pd->edit_uv.image_size[1],
+ pd->edit_uv.image_aspect[1],
+ pd->edit_uv.image_aspect[1]);
+ pd->edit_uv.mask_texture = mask_texture;
+ DRW_shgroup_uniform_texture(grp, "imgTexture", mask_texture);
+ DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){1.0f, 1.0f, 1.0f, 1.0f});
+ DRW_shgroup_call_obmat(grp, geom, NULL);
+ }
}
void OVERLAY_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob)
@@ -436,6 +494,8 @@ static void OVERLAY_edit_uv_draw_finish(OVERLAY_Data *vedata)
pd->edit_uv.stencil_image = NULL;
pd->edit_uv.stencil_ibuf = NULL;
}
+
+ DRW_TEXTURE_FREE_SAFE(pd->edit_uv.mask_texture);
}
void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata)
@@ -447,6 +507,21 @@ void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata)
if (pd->edit_uv.do_tiled_image_border_overlay) {
DRW_draw_pass(psl->edit_uv_tiled_image_borders_ps);
}
+ if (pd->edit_uv.do_mask_overlay) {
+ /* Combined overlay renders in the default framebuffer and modifies the image in SRS.
+ * The alpha overlay renders in the overlay framebuffer. */
+ const bool is_combined_overlay = pd->edit_uv.mask_overlay_mode == MASK_OVERLAY_COMBINED;
+ GPUFrameBuffer *previous_framebuffer = NULL;
+ if (is_combined_overlay) {
+ DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
+ previous_framebuffer = GPU_framebuffer_active_get();
+ GPU_framebuffer_bind(dfbl->default_fb);
+ }
+ DRW_draw_pass(psl->edit_uv_mask_ps);
+ if (previous_framebuffer) {
+ GPU_framebuffer_bind(previous_framebuffer);
+ }
+ }
if (pd->edit_uv.do_uv_stretching_overlay) {
edit_uv_stretching_update_ratios(vedata);
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index 3355e1bdf16..3aee391c281 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -34,9 +34,9 @@ extern "C" {
# define USE_GEOM_SHADER_WORKAROUND 0
#endif
-/* Needed for eSpaceImage_UVDT_Stretch */
+/* Needed for eSpaceImage_UVDT_Stretch and eMaskOverlayMode */
+#include "DNA_mask_types.h"
#include "DNA_space_types.h"
-
/* Forward declarations */
struct ImBuf;
@@ -99,6 +99,7 @@ typedef struct OVERLAY_PassList {
DRWPass *edit_uv_stretching_ps;
DRWPass *edit_uv_tiled_image_borders_ps;
DRWPass *edit_uv_stencil_ps;
+ DRWPass *edit_uv_mask_ps;
DRWPass *extra_ps[2];
DRWPass *extra_blend_ps;
DRWPass *extra_centers_ps;
@@ -368,18 +369,23 @@ typedef struct OVERLAY_PrivateData {
bool do_tiled_image_overlay;
bool do_tiled_image_border_overlay;
bool do_stencil_overlay;
+ bool do_mask_overlay;
bool do_faces;
bool do_face_dots;
float uv_opacity;
+
+ int image_size[2];
+ float image_aspect[2];
+
/* edge drawing */
OVERLAY_UVLineStyle line_style;
float dash_length;
int do_smooth_wire;
/* stretching overlay */
- float aspect[2];
+ float uv_aspect[2];
eSpaceImage_UVDT_Stretch draw_type;
ListBase totals;
float total_area_ratio;
@@ -389,6 +395,11 @@ typedef struct OVERLAY_PrivateData {
struct Image *stencil_image;
struct ImBuf *stencil_ibuf;
void *stencil_lock;
+
+ /* mask overlay */
+ Mask *mask;
+ eMaskOverlayMode mask_overlay_mode;
+ GPUTexture *mask_texture;
} edit_uv;
struct {
bool transparent;
@@ -690,6 +701,7 @@ GPUShader *OVERLAY_shader_edit_uv_stretching_area_get(void);
GPUShader *OVERLAY_shader_edit_uv_stretching_angle_get(void);
GPUShader *OVERLAY_shader_edit_uv_tiled_image_borders_get(void);
GPUShader *OVERLAY_shader_edit_uv_stencil_image(void);
+GPUShader *OVERLAY_shader_edit_uv_mask_image(void);
GPUShader *OVERLAY_shader_extra(bool is_select);
GPUShader *OVERLAY_shader_extra_groundline(void);
GPUShader *OVERLAY_shader_extra_wire(bool use_object, bool is_select);
diff --git a/source/blender/draw/engines/overlay/overlay_shader.c b/source/blender/draw/engines/overlay/overlay_shader.c
index f3840679d80..88f4e28c039 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.c
@@ -78,7 +78,7 @@ extern char datatoc_edit_uv_edges_frag_glsl[];
extern char datatoc_edit_uv_faces_vert_glsl[];
extern char datatoc_edit_uv_face_dots_vert_glsl[];
extern char datatoc_edit_uv_stretching_vert_glsl[];
-extern char datatoc_edit_uv_stencil_image_vert_glsl[];
+extern char datatoc_edit_uv_image_vert_glsl[];
extern char datatoc_edit_uv_tiled_image_borders_vert_glsl[];
extern char datatoc_extra_frag_glsl[];
extern char datatoc_extra_vert_glsl[];
@@ -94,6 +94,7 @@ extern char datatoc_facing_vert_glsl[];
extern char datatoc_grid_frag_glsl[];
extern char datatoc_grid_vert_glsl[];
extern char datatoc_image_frag_glsl[];
+extern char datatoc_edit_uv_image_mask_frag_glsl[];
extern char datatoc_image_vert_glsl[];
extern char datatoc_motion_path_line_vert_glsl[];
extern char datatoc_motion_path_line_geom_glsl[];
@@ -185,6 +186,7 @@ typedef struct OVERLAY_Shaders {
GPUShader *edit_uv_stretching_area;
GPUShader *edit_uv_tiled_image_borders;
GPUShader *edit_uv_stencil_image;
+ GPUShader *edit_uv_mask_image;
GPUShader *extra;
GPUShader *extra_select;
GPUShader *extra_groundline;
@@ -1070,11 +1072,25 @@ GPUShader *OVERLAY_shader_edit_uv_stencil_image(void)
OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
if (!sh_data->edit_uv_stencil_image) {
sh_data->edit_uv_stencil_image = DRW_shader_create_with_shaderlib(
- datatoc_edit_uv_stencil_image_vert_glsl, NULL, datatoc_image_frag_glsl, e_data.lib, NULL);
+ datatoc_edit_uv_image_vert_glsl, NULL, datatoc_image_frag_glsl, e_data.lib, NULL);
}
return sh_data->edit_uv_stencil_image;
}
+GPUShader *OVERLAY_shader_edit_uv_mask_image(void)
+{
+ OVERLAY_Shaders *sh_data = &e_data.sh_data[0];
+ if (!sh_data->edit_uv_mask_image) {
+ sh_data->edit_uv_mask_image = DRW_shader_create_with_shaderlib(
+ datatoc_edit_uv_image_vert_glsl,
+ NULL,
+ datatoc_edit_uv_image_mask_frag_glsl,
+ e_data.lib,
+ NULL);
+ }
+ return sh_data->edit_uv_mask_image;
+}
+
GPUShader *OVERLAY_shader_image(void)
{
const DRWContextState *draw_ctx = DRW_context_state_get();
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_image_mask_frag.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_image_mask_frag.glsl
new file mode 100644
index 00000000000..0b579d6067c
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_image_mask_frag.glsl
@@ -0,0 +1,14 @@
+#pragma BLENDER_REQUIRE(common_colormanagement_lib.glsl)
+
+uniform sampler2D imgTexture;
+uniform vec4 color;
+
+in vec2 uvs;
+out vec4 fragColor;
+
+void main()
+{
+ vec2 uvs_clamped = clamp(uvs, 0.0, 1.0);
+ float mask_value = texture_read_as_linearrgb(imgTexture, true, uvs_clamped).r;
+ fragColor = vec4(color.rgb * mask_value, color.a);
+}
diff --git a/source/blender/draw/engines/overlay/shaders/edit_uv_stencil_image_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_image_vert.glsl
index d22cc795e66..d22cc795e66 100644
--- a/source/blender/draw/engines/overlay/shaders/edit_uv_stencil_image_vert.glsl
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_image_vert.glsl
diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc
index d365f76aabe..2c8b3d85a0a 100644
--- a/source/blender/draw/tests/shaders_test.cc
+++ b/source/blender/draw/tests/shaders_test.cc
@@ -241,6 +241,7 @@ TEST_F(DrawTest, overlay_glsl_shaders)
EXPECT_NE(OVERLAY_shader_edit_uv_stretching_angle_get(), nullptr);
EXPECT_NE(OVERLAY_shader_edit_uv_tiled_image_borders_get(), nullptr);
EXPECT_NE(OVERLAY_shader_edit_uv_stencil_image(), nullptr);
+ EXPECT_NE(OVERLAY_shader_edit_uv_mask_image(), nullptr);
EXPECT_NE(OVERLAY_shader_extra(false), nullptr);
EXPECT_NE(OVERLAY_shader_extra(true), nullptr);
EXPECT_NE(OVERLAY_shader_extra_groundline(), nullptr);
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 9a36c88f6d1..1981f04682d 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -705,7 +705,8 @@ static void image_main_region_draw(const bContext *C, ARegion *region)
ED_mask_draw_region(depsgraph,
mask,
region,
- sima->mask_info.draw_flag,
+ /* Mask overlay is drawn by image/overlay engine. */
+ sima->mask_info.draw_flag & ~MASK_DRAWFLAG_OVERLAY,
sima->mask_info.draw_type,
sima->mask_info.overlay_mode,
width,