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/intern/draw_cache_impl_mesh.c18
-rw-r--r--source/blender/draw/modes/paint_texture_mode.c48
-rw-r--r--source/blender/draw/modes/shaders/paint_texture_frag.glsl26
-rw-r--r--source/blender/draw/modes/shaders/paint_texture_vert.glsl14
-rw-r--r--source/blender/gpu/GPU_vertex_format.h2
-rw-r--r--source/blender/makesrna/intern/rna_mesh.c1
6 files changed, 92 insertions, 17 deletions
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 89972d03758..c00a639028f 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -237,6 +237,7 @@ typedef struct MeshRenderData {
MLoopUV **uv;
int uv_len;
int uv_active;
+ int uv_mask_active;
MLoopCol **vcol;
int vcol_len;
@@ -389,6 +390,17 @@ static void mesh_cd_calc_active_uv_layer(
}
}
+static void mesh_cd_calc_active_mask_uv_layer(
+ const Mesh *me, ushort cd_lused[CD_NUMTYPES])
+{
+ const CustomData *cd_ldata = (me->edit_mesh) ? &me->edit_mesh->bm->ldata : &me->ldata;
+
+ int layer = CustomData_get_stencil_layer(cd_ldata, CD_MLOOPUV);
+ if (layer != -1) {
+ cd_lused[CD_MLOOPUV] |= (1 << layer);
+ }
+}
+
static void mesh_cd_calc_active_vcol_layer(
const Mesh *me, ushort cd_lused[CD_NUMTYPES])
{
@@ -839,6 +851,7 @@ static MeshRenderData *mesh_render_data_create_ex(
}
rdata->cd.layers.uv_active = CustomData_get_active_layer(cd_ldata, CD_MLOOPUV);
+ rdata->cd.layers.uv_mask_active = CustomData_get_stencil_layer(cd_ldata, CD_MLOOPUV);
rdata->cd.layers.vcol_active = CustomData_get_active_layer(cd_ldata, CD_MLOOPCOL);
rdata->cd.layers.tangent_active = rdata->cd.layers.uv_active;
@@ -848,6 +861,7 @@ static MeshRenderData *mesh_render_data_create_ex(
} ((void)0)
CD_VALIDATE_ACTIVE_LAYER(rdata->cd.layers.uv_active, cd_lused[CD_MLOOPUV]);
+ CD_VALIDATE_ACTIVE_LAYER(rdata->cd.layers.uv_mask_active, cd_lused[CD_MLOOPUV]);
CD_VALIDATE_ACTIVE_LAYER(rdata->cd.layers.tangent_active, cd_lused[CD_TANGENT]);
CD_VALIDATE_ACTIVE_LAYER(rdata->cd.layers.vcol_active, cd_lused[CD_MLOOPCOL]);
@@ -2987,6 +3001,9 @@ static void mesh_create_loop_uv_and_tan(MeshRenderData *rdata, GPUVertBuf *vbo)
if (i == rdata->cd.layers.uv_active) {
GPU_vertformat_alias_add(&format, "u");
}
+ if (i == rdata->cd.layers.uv_mask_active) {
+ GPU_vertformat_alias_add(&format, "mu");
+ }
}
for (uint i = 0; i < tangent_len; i++) {
@@ -3959,6 +3976,7 @@ static void texpaint_request_active_uv(MeshBatchCache *cache, Mesh *me)
/* This should not happen. */
BLI_assert(!"No uv layer available in texpaint, but batches requested anyway!");
}
+ mesh_cd_calc_active_mask_uv_layer(me, cd_lneeded);
bool cd_overlap = mesh_cd_layers_type_overlap(cache->cd_vused, cache->cd_lused,
cd_vneeded, cd_lneeded);
if (cd_overlap == false) {
diff --git a/source/blender/draw/modes/paint_texture_mode.c b/source/blender/draw/modes/paint_texture_mode.c
index 0a9746b3de5..7696ce4707b 100644
--- a/source/blender/draw/modes/paint_texture_mode.c
+++ b/source/blender/draw/modes/paint_texture_mode.c
@@ -106,6 +106,7 @@ static struct {
* free in PAINT_TEXTURE_engine_free(); */
struct GPUShader *fallback_sh;
struct GPUShader *image_sh;
+ struct GPUShader *image_masking_sh;
struct GPUShader *wire_overlay_shader;
struct GPUShader *face_overlay_shader;
@@ -136,6 +137,12 @@ static void PAINT_TEXTURE_engine_init(void *UNUSED(vedata))
datatoc_paint_texture_frag_glsl,
datatoc_common_globals_lib_glsl, NULL);
+ e_data.image_masking_sh = DRW_shader_create_with_lib(
+ datatoc_paint_texture_vert_glsl, NULL,
+ datatoc_paint_texture_frag_glsl,
+ datatoc_common_globals_lib_glsl,
+ "#define TEXTURE_PAINT_MASK\n");
+
e_data.wire_overlay_shader = DRW_shader_create_with_lib(
datatoc_paint_wire_vert_glsl, NULL,
datatoc_paint_wire_frag_glsl,
@@ -148,6 +155,28 @@ static void PAINT_TEXTURE_engine_init(void *UNUSED(vedata))
}
}
+static DRWShadingGroup* create_texture_paint_shading_group(PAINT_TEXTURE_PassList *psl, const struct GPUTexture *texture, const DRWContextState *draw_ctx, const bool nearest_interp)
+{
+ Scene *scene = draw_ctx->scene;
+ const ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
+ const bool masking_enabled = imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL && imapaint->stencil != NULL;
+
+ DRWShadingGroup *grp = DRW_shgroup_create(masking_enabled?e_data.image_masking_sh:e_data.image_sh, psl->image_faces);
+ DRW_shgroup_uniform_texture(grp, "image", texture);
+ DRW_shgroup_uniform_float(grp, "alpha", &draw_ctx->v3d->overlay.texture_paint_mode_opacity, 1);
+ DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
+ DRW_shgroup_uniform_bool_copy(grp, "nearestInterp", nearest_interp);
+
+ if (masking_enabled) {
+ const bool masking_inverted = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) > 0;
+ GPUTexture *stencil = GPU_texture_from_blender(imapaint->stencil, NULL, GL_TEXTURE_2D, false);
+ DRW_shgroup_uniform_texture(grp, "maskingImage", stencil);
+ DRW_shgroup_uniform_vec3(grp, "maskingColor", imapaint->stencil_col, 1);
+ DRW_shgroup_uniform_bool_copy(grp, "maskingInvertStencil", masking_inverted);
+ }
+ return grp;
+}
+
/* Here init all passes and shading groups
* Assume that all Passes are NULL */
static void PAINT_TEXTURE_cache_init(void *vedata)
@@ -192,15 +221,10 @@ static void PAINT_TEXTURE_cache_init(void *vedata)
Material *ma = give_current_material(ob, i + 1);
Image *ima = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
int interp = (ma && ma->texpaintslot) ? ma->texpaintslot[ma->paint_active_slot].interp : 0;
- GPUTexture *tex = ima ?
- GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false) : NULL;
+ GPUTexture *tex = GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false);
if (tex) {
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.image_sh, psl->image_faces);
- DRW_shgroup_uniform_texture(grp, "image", tex);
- DRW_shgroup_uniform_float(grp, "alpha", &draw_ctx->v3d->overlay.texture_paint_mode_opacity, 1);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
- DRW_shgroup_uniform_bool_copy(grp, "nearestInterp", interp == SHD_INTERP_CLOSEST);
+ DRWShadingGroup *grp = create_texture_paint_shading_group(psl, tex, draw_ctx, interp == SHD_INTERP_CLOSEST);
stl->g_data->shgroup_image_array[i] = grp;
}
else {
@@ -210,15 +234,10 @@ static void PAINT_TEXTURE_cache_init(void *vedata)
}
else {
Image *ima = imapaint->canvas;
- GPUTexture *tex = ima ?
- GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false) : NULL;
+ GPUTexture *tex = GPU_texture_from_blender(ima, NULL, GL_TEXTURE_2D, false);
if (tex) {
- DRWShadingGroup *grp = DRW_shgroup_create(e_data.image_sh, psl->image_faces);
- DRW_shgroup_uniform_texture(grp, "image", tex);
- DRW_shgroup_uniform_float(grp, "alpha", &draw_ctx->v3d->overlay.texture_paint_mode_opacity, 1);
- DRW_shgroup_uniform_block(grp, "globalsBlock", G_draw.block_ubo);
- DRW_shgroup_uniform_bool_copy(grp, "nearestInterp", imapaint->interp == IMAGEPAINT_INTERP_CLOSEST);
+ DRWShadingGroup *grp = create_texture_paint_shading_group(psl, tex, draw_ctx, imapaint->interp == IMAGEPAINT_INTERP_CLOSEST);
stl->g_data->shgroup_image_array[0] = grp;
}
else {
@@ -345,6 +364,7 @@ static void PAINT_TEXTURE_draw_scene(void *vedata)
static void PAINT_TEXTURE_engine_free(void)
{
DRW_SHADER_FREE_SAFE(e_data.image_sh);
+ DRW_SHADER_FREE_SAFE(e_data.image_masking_sh);
DRW_SHADER_FREE_SAFE(e_data.wire_overlay_shader);
DRW_SHADER_FREE_SAFE(e_data.face_overlay_shader);
}
diff --git a/source/blender/draw/modes/shaders/paint_texture_frag.glsl b/source/blender/draw/modes/shaders/paint_texture_frag.glsl
index 68fd1be0886..aadbf8c58c0 100644
--- a/source/blender/draw/modes/shaders/paint_texture_frag.glsl
+++ b/source/blender/draw/modes/shaders/paint_texture_frag.glsl
@@ -1,11 +1,21 @@
in vec2 uv_interp;
+#ifdef TEXTURE_PAINT_MASK
+in vec2 masking_uv_interp;
+#endif
+
out vec4 fragColor;
uniform sampler2D image;
uniform float alpha = 1.0;
uniform bool nearestInterp;
+#ifdef TEXTURE_PAINT_MASK
+uniform sampler2D maskingImage;
+uniform vec3 maskingColor;
+uniform bool maskingInvertStencil;
+#endif
+
void main()
{
vec2 uv = uv_interp;
@@ -13,5 +23,19 @@ void main()
vec2 tex_size = vec2(textureSize(image, 0).xy);
uv = (floor(uv_interp * tex_size) + 0.5) / tex_size;
}
- fragColor = vec4(texture(image, uv).rgb, alpha);
+
+ vec4 color = texture(image, uv);
+ color.a *= alpha;
+
+#ifdef TEXTURE_PAINT_MASK
+ vec4 mask = vec4(texture(maskingImage, masking_uv_interp).rgb, 1.0);
+ if (maskingInvertStencil) {
+ mask.rgb = 1.0 - mask.rgb;
+ }
+ float mask_step = smoothstep(0, 3.0, mask.r+mask.g+mask.b);
+ mask.rgb *= maskingColor;
+ color = mix(color, mask, mask_step);
+#endif
+
+ fragColor = color;
}
diff --git a/source/blender/draw/modes/shaders/paint_texture_vert.glsl b/source/blender/draw/modes/shaders/paint_texture_vert.glsl
index c53439f46a0..43a353f0278 100644
--- a/source/blender/draw/modes/shaders/paint_texture_vert.glsl
+++ b/source/blender/draw/modes/shaders/paint_texture_vert.glsl
@@ -5,15 +5,27 @@ uniform mat4 ModelMatrix;
in vec2 u; /* active uv map */
in vec3 pos;
+#ifdef TEXTURE_PAINT_MASK
+in vec2 mu; /* masking uv map */
+#endif
+
out vec2 uv_interp;
+#ifdef TEXTURE_PAINT_MASK
+out vec2 masking_uv_interp;
+#endif
+
void main()
{
gl_Position = ModelViewProjectionMatrix * vec4(pos, 1.0);
uv_interp = u;
+#ifdef TEXTURE_PAINT_MASK
+ masking_uv_interp = mu;
+#endif
+
#ifdef USE_WORLD_CLIP_PLANES
- world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
+ world_clip_planes_calc_clip_distance((ModelMatrix * vec4(pos, 1.0)).xyz);
#endif
}
diff --git a/source/blender/gpu/GPU_vertex_format.h b/source/blender/gpu/GPU_vertex_format.h
index 515fa545b0e..63ff430033b 100644
--- a/source/blender/gpu/GPU_vertex_format.h
+++ b/source/blender/gpu/GPU_vertex_format.h
@@ -29,7 +29,7 @@
#include "GPU_common.h"
#define GPU_VERT_ATTR_MAX_LEN 16
-#define GPU_VERT_ATTR_MAX_NAMES 3
+#define GPU_VERT_ATTR_MAX_NAMES 4
#define GPU_VERT_ATTR_NAME_AVERAGE_LEN 11
#define GPU_VERT_ATTR_NAMES_BUF_LEN ((GPU_VERT_ATTR_NAME_AVERAGE_LEN + 1) * GPU_VERT_ATTR_MAX_LEN)
diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c
index c9a8da51e40..158f4535303 100644
--- a/source/blender/makesrna/intern/rna_mesh.c
+++ b/source/blender/makesrna/intern/rna_mesh.c
@@ -2642,6 +2642,7 @@ static void rna_def_mesh(BlenderRNA *brna)
RNA_def_property_int_funcs(prop, "rna_Mesh_uv_layer_stencil_index_get",
"rna_Mesh_uv_layer_stencil_index_set", "rna_Mesh_uv_layer_index_range");
RNA_def_property_ui_text(prop, "Mask UV loop layer Index", "Mask UV loop layer index");
+ RNA_def_property_update(prop, 0, "rna_Mesh_update_data");
/* Vertex colors */