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--release/scripts/startup/bl_ui/space_view3d_toolbar.py42
-rw-r--r--source/blender/blenkernel/BKE_paint.h2
-rw-r--r--source/blender/blenkernel/intern/paint.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c391
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c6
-rw-r--r--source/blender/makesrna/intern/rna_brush.c2
6 files changed, 351 insertions, 98 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 847d1fa43e4..c0c84c4449f 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -670,6 +670,19 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
col.prop(brush, "use_persistent")
col.operator("sculpt.set_persistent_base")
+ col = layout.column(align=True)
+ col.label(text="Overlay:")
+
+ row = col.row()
+ if brush.use_cursor_overlay:
+ row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
+ else:
+ row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
+
+ sub = row.row()
+ sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
+ sub.prop(brush, "cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
+
# Texture Paint Mode #
elif context.image_paint_object and brush:
@@ -693,6 +706,20 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
col.active = (brush.blend not in {'ERASE_ALPHA', 'ADD_ALPHA'})
col.prop(brush, "use_alpha")
+ col = layout.column(align=True)
+ col.label(text="Overlay:")
+
+ row = col.row()
+ if brush.use_cursor_overlay:
+ row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
+ else:
+ row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
+
+ sub = row.row()
+ sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
+ sub.prop(brush, "cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
+
+
# Weight Paint Mode #
elif context.weight_paint_object and brush:
layout.prop(toolsettings, "use_auto_normalize", text="Auto Normalize")
@@ -736,6 +763,19 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
col.prop(brush, "vertex_tool", text="Blend")
+ col = layout.column(align=True)
+ col.label(text="Overlay:")
+
+ row = col.row()
+ if brush.use_cursor_overlay:
+ row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF')
+ else:
+ row.prop(brush, "use_cursor_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
+
+ sub = row.row()
+ sub.prop(brush, "cursor_overlay_alpha", text="Alpha")
+ sub.prop(brush, "cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
+
class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
bl_label = "Texture"
@@ -811,7 +851,7 @@ class VIEW3D_PT_tools_mask_texture(View3DPanel, Panel):
row.prop(brush, "use_secondary_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON')
sub = row.row()
- sub.prop(brush, "texture_overlay_alpha", text="Alpha")
+ sub.prop(brush, "mask_overlay_alpha", text="Alpha")
sub.prop(brush, "cursor_overlay_override", toggle=True, text="", icon='BRUSH_DATA')
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index ff5efd3b02b..5b53f1d34c9 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -79,7 +79,7 @@ void BKE_paint_invalidate_overlay_tex(struct Scene *scene, const struct Tex *tex
void BKE_paint_invalidate_cursor_overlay(struct Scene *scene, struct CurveMapping *curve);
void BKE_paint_invalidate_overlay_all(void);
OverlayControlFlags BKE_paint_get_overlay_flags(void);
-void BKE_paint_reset_overlay_invalid(void);
+void BKE_paint_reset_overlay_invalid(OverlayControlFlags flag);
void BKE_paint_set_overlay_override(bool flag);
bool BKE_paint_get_overlay_override(void);
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 59bfb987a19..ef751d130db 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -108,11 +108,9 @@ bool BKE_paint_get_overlay_override(void)
}
-void BKE_paint_reset_overlay_invalid(void)
+void BKE_paint_reset_overlay_invalid(OverlayControlFlags flag)
{
- overlay_flags &= ~(PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY |
- PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY |
- PAINT_INVALID_OVERLAY_CURVE);
+ overlay_flags &= ~(flag);
}
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 7525085fd53..3770ff7b85d 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -69,9 +69,13 @@
*/
typedef struct TexSnapshot {
+ GLuint overlay_texture;
int winx;
int winy;
bool init;
+ int old_size;
+ int old_zoom;
+ bool old_col;
} TexSnapshot;
typedef struct CurveSnapshot {
@@ -80,35 +84,35 @@ typedef struct CurveSnapshot {
bool init;
} CurveSnapshot;
-static int same_tex_snap(TexSnapshot *snap, Brush *brush, ViewContext *vc)
+static int same_tex_snap(TexSnapshot *snap, MTex *mtex, ViewContext *vc, bool col, float zoom)
{
- MTex *mtex = &brush->mtex;
-
return (/* make brush smaller shouldn't cause a resample */
//(mtex->brush_map_mode != MTEX_MAP_MODE_VIEW ||
//(BKE_brush_size_get(vc->scene, brush) <= snap->BKE_brush_size_get)) &&
(mtex->brush_map_mode != MTEX_MAP_MODE_TILED ||
(vc->ar->winx == snap->winx &&
- vc->ar->winy == snap->winy))
+ vc->ar->winy == snap->winy)) &&
+ snap->old_zoom == zoom &&
+ snap->old_col == col
);
}
-static void make_tex_snap(TexSnapshot *snap, ViewContext *vc)
+static void make_tex_snap(TexSnapshot *snap, ViewContext *vc, float zoom)
{
+ snap->old_zoom = zoom;
snap->winx = vc->ar->winx;
snap->winy = vc->ar->winy;
}
-static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col)
+static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col, bool primary)
{
- static GLuint overlay_texture = 0;
static int init = 0;
- static TexSnapshot snap;
- static int old_size = -1;
- static int old_zoom = -1;
- static bool old_col = -1;
+ static TexSnapshot primary_snap = {0};
+ static TexSnapshot secondary_snap = {0};
+ TexSnapshot *target;
+ MTex *mtex = (primary) ? &br->mtex : &br->mask_mtex;
OverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags();
GLubyte *buffer = NULL;
@@ -116,29 +120,29 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col)
int j;
int refresh;
GLenum format = col ? GL_RGBA : GL_ALPHA;
+ OverlayControlFlags invalid = (primary) ? (overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY) :
+ (overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_SECONDARY);
+
+ target = (primary) ? &primary_snap : &secondary_snap;
- if (br->mtex.brush_map_mode != MTEX_MAP_MODE_VIEW && !br->mtex.tex) return 0;
+ if (mtex->brush_map_mode != MTEX_MAP_MODE_VIEW && !mtex->tex) return 0;
refresh =
- !overlay_texture ||
- (overlay_flags & PAINT_INVALID_OVERLAY_TEXTURE_PRIMARY) ||
- (overlay_flags & PAINT_INVALID_OVERLAY_CURVE) ||
- old_zoom != zoom ||
- old_col != col ||
- !same_tex_snap(&snap, br, vc);
+ !target->overlay_texture ||
+ (invalid != 0) ||
+ !same_tex_snap(target, mtex, vc, col, zoom);
if (refresh) {
struct ImagePool *pool = NULL;
/* stencil is rotated later */
- const float rotation = (br->mtex.brush_map_mode != MTEX_MAP_MODE_STENCIL) ?
- -br->mtex.rot : 0;
+ const float rotation = (mtex->brush_map_mode != MTEX_MAP_MODE_STENCIL) ?
+ -mtex->rot : 0;
float radius = BKE_brush_size_get(vc->scene, br) * zoom;
- old_zoom = zoom;
- make_tex_snap(&snap, vc);
+ make_tex_snap(target, vc, zoom);
- if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
int s = BKE_brush_size_get(vc->scene, br);
int r = 1;
@@ -150,32 +154,30 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col)
if (size < 256)
size = 256;
- if (size < old_size)
- size = old_size;
+ if (size < target->old_size)
+ size = target->old_size;
}
else
size = 512;
- if (old_size != size) {
- if (overlay_texture) {
- glDeleteTextures(1, &overlay_texture);
- overlay_texture = 0;
+ if (target->old_size != size) {
+ if (target->overlay_texture) {
+ glDeleteTextures(1, &target->overlay_texture);
+ target->overlay_texture = 0;
}
init = 0;
- old_size = size;
+ target->old_size = size;
}
if (col)
buffer = MEM_mallocN(sizeof(GLubyte) * size * size * 4, "load_tex");
else
buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
- if (br->mtex.tex)
+ if (mtex->tex)
pool = BKE_image_pool_new();
- curvemapping_initialize(br->curve);
-
#pragma omp parallel for schedule(static)
for (j = 0; j < size; j++) {
int i;
@@ -192,7 +194,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col)
x = (float)i / size;
y = (float)j / size;
- if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) {
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
x *= vc->ar->winx / radius;
y *= vc->ar->winy / radius;
}
@@ -206,47 +208,39 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col)
len = sqrtf(x * x + y * y);
- if (ELEM(br->mtex.brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_STENCIL) || len <= 1) {
+ if (ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_STENCIL) || len <= 1) {
/* it is probably worth optimizing for those cases where
* the texture is not rotated by skipping the calls to
* atan2, sqrtf, sin, and cos. */
- if (br->mtex.tex && (rotation > 0.001f || rotation < -0.001f)) {
- const float angle = atan2f(y, x) + rotation;
+ if (mtex->tex && (rotation > 0.001f || rotation < -0.001f)) {
+ const float angle = atan2f(y, x) + rotation;
x = len * cosf(angle);
y = len * sinf(angle);
}
- x *= br->mtex.size[0];
- y *= br->mtex.size[1];
+ x *= mtex->size[0];
+ y *= mtex->size[1];
- x += br->mtex.ofs[0];
- y += br->mtex.ofs[1];
+ x += mtex->ofs[0];
+ y += mtex->ofs[1];
if (col) {
float rgba[4];
- if (br->mtex.tex)
- paint_get_tex_pixel_col(&br->mtex, x, y, rgba, pool);
+ if (mtex->tex)
+ paint_get_tex_pixel_col(mtex, x, y, rgba, pool);
- if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
- float curve_str = BKE_brush_curve_strength(br, len, 1.0f);
- CLAMP(curve_str, 0.0f, 1.0f);
- mul_v4_fl(rgba, curve_str); /* Falloff curve */
- }
buffer[index * 4] = rgba[0] * 255;
buffer[index * 4 + 1] = rgba[1] * 255;
buffer[index * 4 + 2] = rgba[2] * 255;
buffer[index * 4 + 3] = rgba[3] * 255;
}
else {
- float avg = br->mtex.tex ? paint_get_tex_pixel(&br->mtex, x, y, pool) : 1;
+ float avg = mtex->tex ? paint_get_tex_pixel(mtex, x, y, pool) : 1;
avg += br->texture_sample_bias;
- if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW)
- avg *= BKE_brush_curve_strength(br, len, 1.0f); /* Falloff curve */
-
/* clamp to avoid precision overflow */
CLAMP(avg, 0.0f, 1.0f);
buffer[index] = 255 - (GLubyte)(255 * avg);
@@ -269,17 +263,17 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col)
if (pool)
BKE_image_pool_free(pool);
- if (!overlay_texture)
- glGenTextures(1, &overlay_texture);
+ if (!target->overlay_texture)
+ glGenTextures(1, &target->overlay_texture);
}
else {
- size = old_size;
+ size = target->old_size;
}
- glBindTexture(GL_TEXTURE_2D, overlay_texture);
+ glBindTexture(GL_TEXTURE_2D, target->overlay_texture);
if (refresh) {
- if (!init || (old_col != col)) {
+ if (!init || (target->old_col != col)) {
glTexImage2D(GL_TEXTURE_2D, 0, format, size, size, 0, format, GL_UNSIGNED_BYTE, buffer);
init = 1;
}
@@ -290,7 +284,7 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col)
if (buffer)
MEM_freeN(buffer);
- old_col = col;
+ target->old_col = col;
}
glEnable(GL_TEXTURE_2D);
@@ -299,16 +293,154 @@ static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col)
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
}
- BKE_paint_reset_overlay_invalid();
+ BKE_paint_reset_overlay_invalid(invalid);
+
+ return 1;
+}
+
+static int load_tex_cursor(Brush *br, ViewContext *vc, float zoom)
+{
+ static GLuint overlay_texture = 0;
+ static int init = 0;
+ static int old_size = -1;
+ static int old_zoom = -1;
+
+ OverlayControlFlags overlay_flags = BKE_paint_get_overlay_flags();
+ GLubyte *buffer = NULL;
+
+ int size;
+ int j;
+ int refresh;
+
+ if (br->mtex.brush_map_mode != MTEX_MAP_MODE_VIEW && !br->mtex.tex) return 0;
+
+ refresh =
+ !overlay_texture ||
+ (overlay_flags & PAINT_INVALID_OVERLAY_CURVE) ||
+ old_zoom != zoom;
+
+ if (refresh) {
+ int s, r;
+ float radius;
+
+ old_zoom = zoom;
+
+ s = BKE_brush_size_get(vc->scene, br);
+ r = 1;
+ radius = s * zoom;
+
+ for (s >>= 1; s > 0; s >>= 1)
+ r++;
+
+ size = (1 << r);
+
+ if (size < 256)
+ size = 256;
+
+ if (size < old_size)
+ size = old_size;
+
+ if (old_size != size) {
+ if (overlay_texture) {
+ glDeleteTextures(1, &overlay_texture);
+ overlay_texture = 0;
+ }
+
+ init = 0;
+
+ old_size = size;
+ }
+ buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex");
+
+ curvemapping_initialize(br->curve);
+
+ #pragma omp parallel for schedule(static)
+ for (j = 0; j < size; j++) {
+ int i;
+ float y;
+ float len;
+
+ for (i = 0; i < size; i++) {
+
+ // largely duplicated from tex_strength
+
+ int index = j * size + i;
+ float x;
+
+ x = (float)i / size;
+ y = (float)j / size;
+
+ if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) {
+ x *= vc->ar->winx / radius;
+ y *= vc->ar->winy / radius;
+ }
+ else {
+ x -= 0.5f;
+ y -= 0.5f;
+
+ x *= 2;
+ y *= 2;
+ }
+
+ len = sqrtf(x * x + y * y);
+
+ if (len <= 1) {
+ float avg = BKE_brush_curve_strength(br, len, 1.0f); /* Falloff curve */
+
+ /* clamp to avoid precision overflow */
+ CLAMP(avg, 0.0f, 1.0f);
+ buffer[index] = 255 - (GLubyte)(255 * avg);
+
+ }
+ else {
+ buffer[index] = 0;
+ }
+ }
+ }
+
+ if (!overlay_texture)
+ glGenTextures(1, &overlay_texture);
+ }
+ else {
+ size = old_size;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, overlay_texture);
+
+ if (refresh) {
+ if (!init) {
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
+ init = 1;
+ }
+ else {
+ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer);
+ }
+
+ if (buffer)
+ MEM_freeN(buffer);
+ }
+
+ glEnable(GL_TEXTURE_2D);
+
+ glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
+
+ BKE_paint_reset_overlay_invalid(PAINT_INVALID_OVERLAY_CURVE);
return 1;
}
+
+
static int project_brush_radius(ViewContext *vc,
float radius,
const float location[3])
@@ -397,36 +529,25 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc,
/* Draw an overlay that shows what effect the brush's texture will
* have on brush strength */
-/* TODO: sculpt only for now */
-static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
- ViewContext *vc, int x, int y, float zoom, PaintMode mode)
+static void paint_draw_tex_overlay(UnifiedPaintSettings *ups, Brush *brush,
+ ViewContext *vc, int x, int y, float zoom, bool col, bool primary)
{
rctf quad;
- bool col;
/* check for overlay mode */
- if (!((brush->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL && brush->mtex.tex) ||
- ((brush->overlay_flags & BRUSH_OVERLAY_PRIMARY) &&
- ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_TILED))))
+ MTex *mtex = (primary) ? &brush->mtex : &brush->mask_mtex;
+ bool valid = (primary) ? (brush->overlay_flags & BRUSH_OVERLAY_PRIMARY) != 0 :
+ (brush->overlay_flags & BRUSH_OVERLAY_SECONDARY) != 0;
+ int overlay_alpha = (primary) ? brush->texture_overlay_alpha : brush->mask_overlay_alpha;
+
+ if (!((mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL && mtex->tex) ||
+ (valid &&
+ ELEM(mtex->brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_TILED))))
{
return;
}
- col = ELEM3(mode, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D, PAINT_VERTEX) ? true: false;
- /* save lots of GL state
- * TODO: check on whether all of these are needed? */
- glPushAttrib(GL_COLOR_BUFFER_BIT |
- GL_CURRENT_BIT |
- GL_DEPTH_BUFFER_BIT |
- GL_ENABLE_BIT |
- GL_LINE_BIT |
- GL_POLYGON_BIT |
- GL_STENCIL_BUFFER_BIT |
- GL_TRANSFORM_BIT |
- GL_VIEWPORT_BIT |
- GL_TEXTURE_BIT);
-
- if (load_tex(brush, vc, zoom, col)) {
+ if (load_tex(brush, vc, zoom, col, primary)) {
glEnable(GL_BLEND);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
@@ -437,7 +558,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
glPushMatrix();
glLoadIdentity();
- if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) {
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) {
/* brush rotation */
glTranslatef(0.5, 0.5, 0);
glRotatef((double)RAD2DEGF(ups->brush_rotation),
@@ -445,7 +566,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
glTranslatef(-0.5f, -0.5f, 0);
/* scale based on tablet pressure */
- if (ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) {
+ if (primary && ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) {
glTranslatef(0.5f, 0.5f, 0);
glScalef(1.0f / ups->pressure_value, 1.0f / ups->pressure_value, 1);
glTranslatef(-0.5f, -0.5f, 0);
@@ -466,7 +587,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
quad.ymax = y + radius;
}
}
- else if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) {
+ else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) {
quad.xmin = 0;
quad.ymin = 0;
quad.xmax = BLI_rcti_size_x(&vc->ar->winrct);
@@ -482,7 +603,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glTranslatef(brush->stencil_pos[0], brush->stencil_pos[1], 0);
- glRotatef(RAD2DEGF(brush->mtex.rot), 0, 0, 1);
+ glRotatef(RAD2DEGF(mtex->rot), 0, 0, 1);
glMatrixMode(GL_TEXTURE);
}
@@ -491,12 +612,12 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
glColor4f(1.0,
1.0,
1.0,
- brush->texture_overlay_alpha / 100.0f);
+ overlay_alpha / 100.0f);
else
glColor4f(U.sculpt_paint_overlay_col[0],
U.sculpt_paint_overlay_col[1],
U.sculpt_paint_overlay_col[2],
- brush->texture_overlay_alpha / 100.0f);
+ overlay_alpha / 100.0f);
/* draw textured quad */
glBegin(GL_QUADS);
@@ -512,11 +633,103 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
glPopMatrix();
- if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL) {
+ if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) {
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
}
}
+}
+
+/* Draw an overlay that shows what effect the brush's texture will
+ * have on brush strength */
+static void paint_draw_cursor_overlay(UnifiedPaintSettings *ups, Brush *brush,
+ ViewContext *vc, int x, int y, float zoom)
+{
+ rctf quad;
+ /* check for overlay mode */
+
+ if (!(brush->overlay_flags & BRUSH_OVERLAY_CURSOR))
+ {
+ return;
+ }
+
+ if (load_tex_cursor(brush, vc, zoom)) {
+ glEnable(GL_BLEND);
+
+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ glDepthMask(GL_FALSE);
+ glDepthFunc(GL_ALWAYS);
+
+ /* scale based on tablet pressure */
+ if (ups->draw_pressure && BKE_brush_use_size_pressure(vc->scene, brush)) {
+ glTranslatef(0.5f, 0.5f, 0);
+ glScalef(1.0f / ups->pressure_value, 1.0f / ups->pressure_value, 1);
+ glTranslatef(-0.5f, -0.5f, 0);
+ }
+
+ if (ups->draw_anchored) {
+ const float *aim = ups->anchored_initial_mouse;
+ quad.xmin = aim[0] - ups->anchored_size;
+ quad.ymin = aim[1] - ups->anchored_size;
+ quad.xmax = aim[0] + ups->anchored_size;
+ quad.ymax = aim[1] + ups->anchored_size;
+ }
+ else {
+ const int radius = BKE_brush_size_get(vc->scene, brush) * zoom;
+ quad.xmin = x - radius;
+ quad.ymin = y - radius;
+ quad.xmax = x + radius;
+ quad.ymax = y + radius;
+ }
+
+ glColor4f(U.sculpt_paint_overlay_col[0],
+ U.sculpt_paint_overlay_col[1],
+ U.sculpt_paint_overlay_col[2],
+ brush->cursor_overlay_alpha / 100.0f);
+
+ /* draw textured quad */
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0);
+ glVertex2f(quad.xmin, quad.ymin);
+ glTexCoord2f(1, 0);
+ glVertex2f(quad.xmax, quad.ymin);
+ glTexCoord2f(1, 1);
+ glVertex2f(quad.xmax, quad.ymax);
+ glTexCoord2f(0, 1);
+ glVertex2f(quad.xmin, quad.ymax);
+ glEnd();
+ }
+}
+
+static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush,
+ ViewContext *vc, int x, int y, float zoom, PaintMode mode)
+{
+ /* color means that primary brush texture is colured and secondary is used for alpha/mask control */
+ bool col = ELEM3(mode, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D, PAINT_VERTEX) ? true: false;
+
+ /* save lots of GL state
+ * TODO: check on whether all of these are needed? */
+ glPushAttrib(GL_COLOR_BUFFER_BIT |
+ GL_CURRENT_BIT |
+ GL_DEPTH_BUFFER_BIT |
+ GL_ENABLE_BIT |
+ GL_LINE_BIT |
+ GL_POLYGON_BIT |
+ GL_STENCIL_BUFFER_BIT |
+ GL_TRANSFORM_BIT |
+ GL_VIEWPORT_BIT |
+ GL_TEXTURE_BIT);
+
+
+ /* coloured overlay should be drawn separately */
+ if (col) {
+ paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, true, true);
+ paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, false, false);
+ paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
+ } else {
+ paint_draw_tex_overlay(ups, brush, vc, x, y, zoom, false, true);
+ paint_draw_cursor_overlay(ups, brush, vc, x, y, zoom);
+ }
glPopAttrib();
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 14330229aba..de3c4db3b60 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -3796,6 +3796,7 @@ static void *do_projectpaint_thread(void *ph_v)
/* for smear only */
float pos_ofs[2] = {0};
float co[2];
+ float texmask = 1.0;
float mask = 1.0f; /* airbrush wont use mask */
unsigned short mask_short;
const float radius = (float)BKE_brush_size_get(ps->scene, brush);
@@ -3909,7 +3910,8 @@ static void *do_projectpaint_thread(void *ph_v)
}
if (ps->is_maskbrush) {
- alpha *= BKE_brush_sample_masktex(ps->scene, ps->brush, projPixel->projCoSS, thread_index, pool);
+ texmask = BKE_brush_sample_masktex(ps->scene, ps->brush, projPixel->projCoSS, thread_index, pool);
+ alpha *= texmask;
}
if (!ps->do_masking) {
@@ -3922,7 +3924,7 @@ static void *do_projectpaint_thread(void *ph_v)
falloff = 1.0f - falloff;
falloff = 1.0f - (falloff * falloff);
- mask_short = (unsigned short)(projPixel->mask * (BKE_brush_alpha_get(ps->scene, brush) * falloff));
+ mask_short = (unsigned short)(projPixel->mask * (BKE_brush_alpha_get(ps->scene, brush) * falloff)) * texmask;
if (mask_short > projPixel->mask_max) {
mask = ((float)mask_short) / 65535.0f;
projPixel->mask_max = mask_short;
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index ef7fbec3742..4369c6dfabd 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -523,7 +523,7 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "brush_map_mode");
RNA_def_property_enum_items(prop, prop_mask_paint_map_mode_items);
RNA_def_property_ui_text(prop, "Mode", "");
- RNA_def_property_update(prop, 0, "rna_TextureSlot_update");
+ RNA_def_property_update(prop, 0, "rna_TextureSlot_brush_update");
}
static void rna_def_sculpt_capabilities(BlenderRNA *brna)