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:
authorJeroen Bakker <jeroen@blender.org>2020-10-26 17:54:00 +0300
committerJeroen Bakker <jeroen@blender.org>2020-11-17 15:10:39 +0300
commit1e1c39fc89395c5e5a68a7a21500195cd8dc6fd5 (patch)
treea9b6d8e5cceb6a5bffb7d000499449be51fabed2 /source/blender/draw
parent8b6ce77f163cf0822af8a107a213e984ba4b3e97 (diff)
Fix T82064: Add Image Clone tool to overlay engine
The clone tool in the image editor can show a second texture on top of the image. This wasn't ported and now results into alpha and depth issues. This fix adds the clone tool drawing to the overlay engine. Reviewed By: Clément Foucault Differential Revision: https://developer.blender.org/D9352
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/CMakeLists.txt1
-rw-r--r--source/blender/draw/engines/overlay/overlay_edit_uv.c80
-rw-r--r--source/blender/draw/engines/overlay/overlay_private.h10
-rw-r--r--source/blender/draw/engines/overlay/overlay_shader.c13
-rw-r--r--source/blender/draw/engines/overlay/shaders/edit_uv_stencil_image_vert.glsl14
-rw-r--r--source/blender/draw/engines/overlay/shaders/image_frag.glsl1
-rw-r--r--source/blender/draw/tests/shaders_test.cc1
7 files changed, 111 insertions, 9 deletions
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 4e72e89ae99..5436f78918c 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -373,6 +373,7 @@ 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_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 18400799d3c..e21b6b30d22 100644
--- a/source/blender/draw/engines/overlay/overlay_edit_uv.c
+++ b/source/blender/draw/engines/overlay/overlay_edit_uv.c
@@ -26,11 +26,15 @@
#include "BKE_editmesh.h"
#include "BKE_image.h"
+#include "BKE_paint.h"
+#include "DNA_brush_types.h"
#include "DNA_mesh_types.h"
#include "ED_image.h"
+#include "IMB_imbuf_types.h"
+
#include "GPU_batch.h"
#include "UI_interface.h"
@@ -77,7 +81,8 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
const DRWContextState *draw_ctx = DRW_context_state_get();
SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
const Scene *scene = draw_ctx->scene;
- const ToolSettings *ts = scene->toolsettings;
+ ToolSettings *ts = scene->toolsettings;
+ const Brush *brush = BKE_paint_brush(&ts->imapaint.paint);
const bool show_overlays = !pd->hide_overlays;
Image *image = sima->image;
@@ -99,6 +104,9 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
const bool do_uvstretching_overlay = is_image_type && is_uv_editor && is_edit_mode &&
((sima->flag & SI_DRAW_STRETCH) != 0);
const bool do_tex_paint_shadows = (sima->flag & SI_NO_DRAW_TEXPAINT) == 0;
+ const bool do_stencil_overlay = is_paint_mode && is_image_type && brush &&
+ (brush->imagepaint_tool == PAINT_TOOL_CLONE) &&
+ brush->clone.image;
pd->edit_uv.do_faces = show_overlays && do_faces && !do_uvstretching_overlay;
pd->edit_uv.do_face_dots = show_overlays && do_faces && do_face_dots;
@@ -117,6 +125,7 @@ void OVERLAY_edit_uv_init(OVERLAY_Data *vedata)
pd->edit_uv.dash_length = 4.0f * UI_DPI_FAC;
pd->edit_uv.line_style = edit_uv_line_style_from_space_image(sima);
pd->edit_uv.do_smooth_wire = ((U.gpu_flag & USER_GPU_FLAG_OVERLAY_SMOOTH_WIRE) > 0);
+ pd->edit_uv.do_stencil_overlay = show_overlays && do_stencil_overlay;
pd->edit_uv.draw_type = sima->dt_uvstretch;
BLI_listbase_clear(&pd->edit_uv.totals);
@@ -132,6 +141,12 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
OVERLAY_PassList *psl = vedata->psl;
OVERLAY_PrivateData *pd = stl->pd;
+ const DRWContextState *draw_ctx = DRW_context_state_get();
+ SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
+ Image *image = sima->image;
+ const Scene *scene = draw_ctx->scene;
+ ToolSettings *ts = scene->toolsettings;
+
if (pd->edit_uv.do_uv_overlay || pd->edit_uv.do_uv_shadow_overlay) {
/* uv edges */
{
@@ -224,9 +239,6 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
}
if (pd->edit_uv.do_tiled_image_border_overlay) {
- const DRWContextState *draw_ctx = DRW_context_state_get();
- SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
- Image *image = sima->image;
GPUBatch *geom = DRW_cache_quad_wires_get();
float obmat[4][4];
unit_m4(obmat);
@@ -265,10 +277,6 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
}
if (pd->edit_uv.do_tiled_image_overlay) {
- const DRWContextState *draw_ctx = DRW_context_state_get();
- SpaceImage *sima = (SpaceImage *)draw_ctx->space_data;
- Image *image = sima->image;
-
struct DRWTextStore *dt = DRW_text_cache_ensure();
uchar color[4];
/* Color Management: Exception here as texts are drawn in sRGB space directly. */
@@ -288,6 +296,42 @@ void OVERLAY_edit_uv_cache_init(OVERLAY_Data *vedata)
color);
}
}
+
+ if (pd->edit_uv.do_stencil_overlay) {
+ const Brush *brush = BKE_paint_brush(&ts->imapaint.paint);
+
+ DRW_PASS_CREATE(psl->edit_uv_stencil_ps,
+ DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_ALWAYS | DRW_STATE_BLEND_ALPHA_PREMUL);
+ GPUShader *sh = OVERLAY_shader_edit_uv_stencil_image();
+ GPUBatch *geom = DRW_cache_quad_get();
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, psl->edit_uv_stencil_ps);
+ Image *stencil_image = brush->clone.image;
+ ImBuf *stencil_ibuf = BKE_image_acquire_ibuf(stencil_image, NULL, &pd->edit_uv.stencil_lock);
+ pd->edit_uv.stencil_ibuf = stencil_ibuf;
+ pd->edit_uv.stencil_image = stencil_image;
+ GPUTexture *stencil_texture = BKE_image_get_gpu_texture(stencil_image, NULL, stencil_ibuf);
+ DRW_shgroup_uniform_texture(grp, "imgTexture", stencil_texture);
+ DRW_shgroup_uniform_bool_copy(grp, "imgPremultiplied", true);
+ DRW_shgroup_uniform_bool_copy(grp, "imgAlphaBlend", true);
+ DRW_shgroup_uniform_vec4_copy(grp, "color", (float[4]){1.0f, 1.0f, 1.0f, brush->clone.alpha});
+
+ float size_image[2];
+ BKE_image_get_size_fl(image, NULL, size_image);
+ float size_stencil_image[2] = {stencil_ibuf->x, stencil_ibuf->y};
+
+ float obmat[4][4];
+ unit_m4(obmat);
+ obmat[3][1] = brush->clone.offset[1];
+ obmat[3][0] = brush->clone.offset[0];
+ obmat[0][0] = size_stencil_image[0] / size_image[0];
+ obmat[1][1] = size_stencil_image[1] / size_image[1];
+
+ DRW_shgroup_call_obmat(grp, geom, obmat);
+ }
+ else {
+ pd->edit_uv.stencil_ibuf = NULL;
+ pd->edit_uv.stencil_image = NULL;
+ }
}
void OVERLAY_edit_uv_cache_populate(OVERLAY_Data *vedata, Object *ob)
@@ -379,6 +423,19 @@ static void edit_uv_stretching_update_ratios(OVERLAY_Data *vedata)
BLI_freelistN(&pd->edit_uv.totals);
}
+static void OVERLAY_edit_uv_draw_finish(OVERLAY_Data *vedata)
+{
+ OVERLAY_StorageList *stl = vedata->stl;
+ OVERLAY_PrivateData *pd = stl->pd;
+
+ if (pd->edit_uv.stencil_ibuf) {
+ BKE_image_release_ibuf(
+ pd->edit_uv.stencil_image, pd->edit_uv.stencil_ibuf, pd->edit_uv.stencil_lock);
+ pd->edit_uv.stencil_image = NULL;
+ pd->edit_uv.stencil_ibuf = NULL;
+ }
+}
+
void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata)
{
OVERLAY_PassList *psl = vedata->psl;
@@ -393,6 +450,7 @@ void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata)
edit_uv_stretching_update_ratios(vedata);
DRW_draw_pass(psl->edit_uv_stretching_ps);
}
+
if (pd->edit_uv.do_uv_overlay) {
if (pd->edit_uv.do_faces) {
DRW_draw_pass(psl->edit_uv_faces_ps);
@@ -404,6 +462,10 @@ void OVERLAY_edit_uv_draw(OVERLAY_Data *vedata)
else if (pd->edit_uv.do_uv_shadow_overlay) {
DRW_draw_pass(psl->edit_uv_edges_ps);
}
+ if (pd->edit_uv.do_stencil_overlay) {
+ DRW_draw_pass(psl->edit_uv_stencil_ps);
+ }
+ OVERLAY_edit_uv_draw_finish(vedata);
}
-/* \{ */
+/* \} */
diff --git a/source/blender/draw/engines/overlay/overlay_private.h b/source/blender/draw/engines/overlay/overlay_private.h
index d5ba0a5423f..7e6809cb4b1 100644
--- a/source/blender/draw/engines/overlay/overlay_private.h
+++ b/source/blender/draw/engines/overlay/overlay_private.h
@@ -37,6 +37,9 @@ extern "C" {
/* Needed for eSpaceImage_UVDT_Stretch */
#include "DNA_space_types.h"
+/* Forward declarations */
+struct ImBuf;
+
typedef struct OVERLAY_FramebufferList {
struct GPUFrameBuffer *overlay_default_fb;
struct GPUFrameBuffer *overlay_line_fb;
@@ -94,6 +97,7 @@ typedef struct OVERLAY_PassList {
DRWPass *edit_uv_faces_ps;
DRWPass *edit_uv_stretching_ps;
DRWPass *edit_uv_tiled_image_borders_ps;
+ DRWPass *edit_uv_stencil_ps;
DRWPass *extra_ps[2];
DRWPass *extra_blend_ps;
DRWPass *extra_centers_ps;
@@ -359,6 +363,7 @@ typedef struct OVERLAY_PrivateData {
bool do_uv_stretching_overlay;
bool do_tiled_image_overlay;
bool do_tiled_image_border_overlay;
+ bool do_stencil_overlay;
bool do_faces;
bool do_face_dots;
@@ -376,6 +381,10 @@ typedef struct OVERLAY_PrivateData {
float total_area_ratio;
float total_area_ratio_inv;
+ /* stencil overlay */
+ struct Image *stencil_image;
+ struct ImBuf *stencil_ibuf;
+ void * stencil_lock;
} edit_uv;
struct {
bool transparent;
@@ -676,6 +685,7 @@ GPUShader *OVERLAY_shader_edit_uv_verts_get(void);
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_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 5c1b7c786f4..f3840679d80 100644
--- a/source/blender/draw/engines/overlay/overlay_shader.c
+++ b/source/blender/draw/engines/overlay/overlay_shader.c
@@ -78,6 +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_tiled_image_borders_vert_glsl[];
extern char datatoc_extra_frag_glsl[];
extern char datatoc_extra_vert_glsl[];
@@ -183,6 +184,7 @@ typedef struct OVERLAY_Shaders {
GPUShader *edit_uv_stretching_angle;
GPUShader *edit_uv_stretching_area;
GPUShader *edit_uv_tiled_image_borders;
+ GPUShader *edit_uv_stencil_image;
GPUShader *extra;
GPUShader *extra_select;
GPUShader *extra_groundline;
@@ -237,6 +239,7 @@ void OVERLAY_shader_library_ensure(void)
/* NOTE: Theses needs to be ordered by dependencies. */
DRW_SHADER_LIB_ADD(e_data.lib, common_globals_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_overlay_lib);
+ DRW_SHADER_LIB_ADD(e_data.lib, common_colormanagement_lib);
DRW_SHADER_LIB_ADD(e_data.lib, common_view_lib);
}
}
@@ -1062,6 +1065,16 @@ GPUShader *OVERLAY_shader_grid_image(void)
return sh_data->grid_image;
}
+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);
+ }
+ return sh_data->edit_uv_stencil_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_stencil_image_vert.glsl b/source/blender/draw/engines/overlay/shaders/edit_uv_stencil_image_vert.glsl
new file mode 100644
index 00000000000..d22cc795e66
--- /dev/null
+++ b/source/blender/draw/engines/overlay/shaders/edit_uv_stencil_image_vert.glsl
@@ -0,0 +1,14 @@
+#pragma BLENDER_REQUIRE(common_view_lib.glsl)
+
+in vec3 pos;
+out vec2 uvs;
+
+void main()
+{
+ /* `pos` contains the coordinates of a quad (-1..1). but we need the coordinates of an image
+ * plane (0..1) */
+ vec3 image_pos = pos * 0.5 + 0.5;
+ vec4 position = point_object_to_ndc(image_pos);
+ gl_Position = position;
+ uvs = image_pos.xy;
+}
diff --git a/source/blender/draw/engines/overlay/shaders/image_frag.glsl b/source/blender/draw/engines/overlay/shaders/image_frag.glsl
index 4d37f1599a3..6e68d156f25 100644
--- a/source/blender/draw/engines/overlay/shaders/image_frag.glsl
+++ b/source/blender/draw/engines/overlay/shaders/image_frag.glsl
@@ -1,3 +1,4 @@
+#pragma BLENDER_REQUIRE(common_colormanagement_lib.glsl)
uniform sampler2D imgTexture;
uniform bool imgPremultiplied;
diff --git a/source/blender/draw/tests/shaders_test.cc b/source/blender/draw/tests/shaders_test.cc
index 703099477d6..39d8e45cc19 100644
--- a/source/blender/draw/tests/shaders_test.cc
+++ b/source/blender/draw/tests/shaders_test.cc
@@ -240,6 +240,7 @@ TEST_F(DrawTest, overlay_glsl_shaders)
EXPECT_NE(OVERLAY_shader_edit_uv_stretching_area_get(), nullptr);
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_extra(false), nullptr);
EXPECT_NE(OVERLAY_shader_extra(true), nullptr);
EXPECT_NE(OVERLAY_shader_extra_groundline(), nullptr);