Added two new blend modes to image painting brushes, erase alpha and

add alpha, for painting transparency in images. When using the eraser
tool of a tablet pen, the erase alpha blend mode is activated.
This commit is contained in:
2006-11-07 00:10:37 +00:00
parent b48c514db8
commit 2ef6c48a65
6 changed files with 53 additions and 31 deletions

View File

@@ -227,6 +227,8 @@ typedef enum IMB_BlendMode {
IMB_BLEND_MUL = 3,
IMB_BLEND_LIGHTEN = 4,
IMB_BLEND_DARKEN = 5,
IMB_BLEND_ERASE_ALPHA = 6,
IMB_BLEND_ADD_ALPHA = 7,
IMB_BLEND_COPY = 1000,
IMB_BLEND_COPY_RGB = 1001,

View File

@@ -117,7 +117,8 @@ static void blend_color_darken(char *cp, char *cp1, char *cp2, int fac)
unsigned int IMB_blend_color(unsigned int src1, unsigned int src2, int fac, IMB_BlendMode mode)
{
unsigned int dst, temp;
unsigned int dst;
int temp;
char *cp, *cp1, *cp2;
if (fac==0)
@@ -141,11 +142,19 @@ unsigned int IMB_blend_color(unsigned int src1, unsigned int src2, int fac, IMB_
case IMB_BLEND_DARKEN:
blend_color_darken(cp, cp1, cp2, fac); break;
default:
return src1;
cp[0]= cp1[0];
cp[1]= cp1[1];
cp[2]= cp1[2];
}
temp= (cp1[3] + fac*cp2[3]/255);
cp[3]= (temp > 255)? 255: temp;
if (mode == IMB_BLEND_ERASE_ALPHA) {
temp= (cp1[3] - fac*cp2[3]/255);
cp[3]= (temp < 0)? 0: temp;
}
else { /* this does ADD_ALPHA also */
temp= (cp1[3] + fac*cp2[3]/255);
cp[3]= (temp > 255)? 255: temp;
}
return dst;
}
@@ -244,8 +253,14 @@ void IMB_blend_color_float(float *dst, float *src1, float *src2, float fac, IMB_
dst[2]= src1[2];
}
dst[3]= (src1[3] + fac*src2[3]);
if (dst[3] > 1.0f) dst[3] = 1.0f;
if (mode == IMB_BLEND_ERASE_ALPHA) {
dst[3]= (src1[3] - fac*src2[3]);
if (dst[3] < 0.0f) dst[3] = 0.0f;
}
else { /* this does ADD_ALPHA also */
dst[3]= (src1[3] + fac*src2[3]);
if (dst[3] > 1.0f) dst[3] = 1.0f;
}
}
/* clipping */

View File

@@ -73,12 +73,14 @@ typedef struct Brush {
#define BRUSH_FIXED_TEX 64
/* Brush.blend */
#define BRUSH_BLEND_MIX 0
#define BRUSH_BLEND_ADD 1
#define BRUSH_BLEND_SUB 2
#define BRUSH_BLEND_MUL 3
#define BRUSH_BLEND_LIGHTEN 4
#define BRUSH_BLEND_DARKEN 5
#define BRUSH_BLEND_MIX 0
#define BRUSH_BLEND_ADD 1
#define BRUSH_BLEND_SUB 2
#define BRUSH_BLEND_MUL 3
#define BRUSH_BLEND_LIGHTEN 4
#define BRUSH_BLEND_DARKEN 5
#define BRUSH_BLEND_ERASE_ALPHA 6
#define BRUSH_BLEND_ADD_ALPHA 7
#define PAINT_TOOL_DRAW 0
#define PAINT_TOOL_SOFTEN 1

View File

@@ -4544,7 +4544,7 @@ static void editing_panel_mesh_paint(void)
if(brush && !brush->id.lib) {
butw= 320-(xco+10);
uiDefButS(block, MENU, B_NOP, "Mix %x0|Add %x1|Subtract %x2|Multiply %x3|Lighten %x4|Darken %x5", xco+10,yco,butw,19, &brush->blend, 0, 0, 0, 0, "Blending method for applying brushes");
uiDefButS(block, MENU, B_NOP, "Mix %x0|Add %x1|Subtract %x2|Multiply %x3|Lighten %x4|Darken %x5|Erase Alpha %x6|Add Alpha %x7", xco+10,yco,butw,19, &brush->blend, 0, 0, 0, 0, "Blending method for applying brushes");
uiDefButBitS(block, TOG|BIT, BRUSH_TORUS, B_BRUSHCHANGE, "Wrap", xco+10,yco-25,butw,19, &brush->flag, 0, 0, 0, 0, "Enables torus wrapping");

View File

@@ -804,7 +804,7 @@ static void image_editvertex_buts(uiBlock *block)
digits= 2;
}
uiDefBut(block, LABEL, 0, "UV Vertex:",10,55,302,19,0,0,0,0,0,"");
uiDefBut(block, LABEL, 0, "UV Vertex:",10,55,300,19,0,0,0,0,0,"");
uiBlockBeginAlign(block);
if(nactive==1) {
uiDefButF(block, NUM, B_TRANS_IMAGE, "Vertex X:", 10, 35, 290, 19, &ocent[0], -10*imx, 10.0*imx, step, digits, "");
@@ -1084,7 +1084,7 @@ static void image_panel_paint(short cntrl) // IMAGE_HANDLER_PROPERTIES
if(brush && !brush->id.lib) {
butw= 320-(xco+10);
uiDefButS(block, MENU, B_SIMANOTHING, "Mix %x0|Add %x1|Subtract %x2|Multiply %x3|Lighten %x4|Darken %x5", xco+10,yco,butw,19, &brush->blend, 0, 0, 0, 0, "Blending method for applying brushes");
uiDefButS(block, MENU, B_SIMANOTHING, "Mix %x0|Add %x1|Subtract %x2|Multiply %x3|Lighten %x4|Darken %x5|Erase Alpha %x6|Add Alpha %x7", xco+10,yco,butw,19, &brush->blend, 0, 0, 0, 0, "Blending method for applying brushes");
uiDefButBitS(block, TOG|BIT, BRUSH_TORUS, B_SIMABRUSHCHANGE, "Wrap", xco+10,yco-25,butw,19, &brush->flag, 0, 0, 0, 0, "Enables torus wrapping");

View File

@@ -103,7 +103,7 @@
typedef struct ImagePaintState {
Brush *brush;
short tool;
short tool, blend;
Image *image;
ImBuf *canvas;
ImBuf *clonecanvas;
@@ -409,7 +409,7 @@ static int imapaint_paint_op(void *state, ImBuf *ibufb, float *lastpos, float *p
ImagePaintState *s= ((ImagePaintState*)state);
ImBuf *clonebuf= NULL;
short torus= s->brush->flag & BRUSH_TORUS;
short blend= s->brush->blend;
short blend= s->blend;
float *offset= s->brush->clone.offset;
float liftpos[2];
int bpos[2], blastpos[2], bliftpos[2];
@@ -518,7 +518,7 @@ static void imapaint_canvas_free(ImagePaintState *s)
imb_freerectfloatImBuf(s->clonecanvas);
}
static int imapaint_do_paint(ImagePaintState *s, BrushPainter *painter, Image *image, short texpaint, float *uv, double time, int update, float pressure)
static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter, Image *image, short texpaint, float *uv, double time, int update, float pressure)
{
float pos[2];
@@ -535,7 +535,7 @@ static int imapaint_do_paint(ImagePaintState *s, BrushPainter *painter, Image *i
else return 0;
}
static void imapaint_do(ImagePaintState *s, BrushPainter *painter, short texpaint, short *prevmval, short *mval, double time, float pressure)
static void imapaint_paint_stroke(ImagePaintState *s, BrushPainter *painter, short texpaint, short *prevmval, short *mval, double time, float pressure)
{
Image *newimage = NULL;
float fwuv[2], bkuv[2], newuv[2];
@@ -565,7 +565,7 @@ static void imapaint_do(ImagePaintState *s, BrushPainter *painter, short texpain
if (breakstroke) {
texpaint_pick_uv(s->ob, s->me, s->faceindex, mval, fwuv);
redraw |= imapaint_do_paint(s, painter, s->image, texpaint, fwuv,
redraw |= imapaint_paint_sub_stroke(s, painter, s->image, texpaint, fwuv,
time, 1, pressure);
imapaint_clear_partial_redraw();
brush_painter_break_stroke(painter);
@@ -579,9 +579,9 @@ static void imapaint_do(ImagePaintState *s, BrushPainter *painter, short texpain
/* paint in new image */
if (newimage) {
if (breakstroke)
redraw|= imapaint_do_paint(s, painter, newimage, texpaint,
redraw|= imapaint_paint_sub_stroke(s, painter, newimage, texpaint,
bkuv, time, 0, pressure);
redraw|= imapaint_do_paint(s, painter, newimage, texpaint, newuv,
redraw|= imapaint_paint_sub_stroke(s, painter, newimage, texpaint, newuv,
time, 1, pressure);
}
@@ -593,7 +593,7 @@ static void imapaint_do(ImagePaintState *s, BrushPainter *painter, short texpain
}
else {
imapaint_compute_uvco(mval, newuv);
redraw |= imapaint_do_paint(s, painter, s->image, texpaint, newuv,
redraw |= imapaint_paint_sub_stroke(s, painter, s->image, texpaint, newuv,
time, 1, pressure);
}
@@ -613,15 +613,16 @@ void imagepaint_paint(short mousebutton, short texpaint)
float pressure;
const GHOST_TabletData *td;
if(!settings->imapaint.brush)
return;
/* initialize state */
memset(&s, 0, sizeof(s));
s.brush= settings->imapaint.brush;
s.tool= settings->imapaint.tool;
s.brush = settings->imapaint.brush;
s.tool = settings->imapaint.tool;
if(texpaint && (s.tool == PAINT_TOOL_CLONE))
s.tool = PAINT_TOOL_DRAW;
if(!s.brush)
return;
s.blend = s.brush->blend;
if(texpaint) {
s.ob = OBACT;
@@ -653,8 +654,9 @@ void imagepaint_paint(short mousebutton, short texpaint)
time= PIL_check_seconds_timer();
prevmval[0]= mval[0];
prevmval[1]= mval[1];
s.blend = (td->Active == 2)? BRUSH_BLEND_ERASE_ALPHA: s.brush->blend;
imapaint_do(&s, painter, texpaint, prevmval, mval, time, pressure);
imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
/* paint loop */
do {
@@ -662,16 +664,17 @@ void imagepaint_paint(short mousebutton, short texpaint)
if(td) {
td= get_tablet_data();
pressure= (td)? td->Pressure: 1.0f;
s.blend = (td->Active == 2)? BRUSH_BLEND_ERASE_ALPHA: s.brush->blend;
}
time= PIL_check_seconds_timer();
if((mval[0] != prevmval[0]) || (mval[1] != prevmval[1])) {
imapaint_do(&s, painter, texpaint, prevmval, mval, time, pressure);
imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
prevmval[0]= mval[0];
prevmval[1]= mval[1];
}
else if (s.brush->flag & BRUSH_AIRBRUSH)
imapaint_do(&s, painter, texpaint, prevmval, mval, time, pressure);
imapaint_paint_stroke(&s, painter, texpaint, prevmval, mval, time, pressure);
else
BIF_wait_for_statechange();