|
|
@@ -186,6 +186,16 @@ void our_CanvasAdd(OUR_PIX_COMPACT* target, OUR_PIX_COMPACT* source, real alpha)
|
|
|
uint32_t b=((uint32_t)source[2]*alpha+(uint32_t)target[2]); TNS_CLAMP(b,0,OUR_PIX_MAX);
|
|
|
target[3]=a; target[0]=r; target[1]=g; target[2]=b;
|
|
|
}
|
|
|
+void our_CanvasMultiply(OUR_PIX_COMPACT* target, OUR_PIX_COMPACT* source, real alpha){
|
|
|
+ uint64_t a=target[3]; real fac=((real)source[3])/OUR_PIX_MAX*alpha; real fac_1=1.0f-fac; real fac_1t=((real)target[3]/OUR_PIX_MAX);
|
|
|
+ real rr=((real)target[0]/fac_1t/OUR_PIX_MAX);
|
|
|
+ real rg=((real)target[1]/fac_1t/OUR_PIX_MAX);
|
|
|
+ real rb=((real)target[2]/fac_1t/OUR_PIX_MAX);
|
|
|
+ uint64_t r=(fac_1t>0.0f)?((rr)*fac_1 + ((real)((real)source[0]/OUR_PIX_MAX)*rr))*OUR_PIX_MAX:0; TNS_CLAMP(r,0,OUR_PIX_MAX);
|
|
|
+ uint64_t g=(fac_1t>0.0f)?((rg)*fac_1 + ((real)((real)source[1]/OUR_PIX_MAX)*rg))*OUR_PIX_MAX:0; TNS_CLAMP(g,0,OUR_PIX_MAX);
|
|
|
+ uint64_t b=(fac_1t>0.0f)?((rb)*fac_1 + ((real)((real)source[2]/OUR_PIX_MAX)*rb))*OUR_PIX_MAX:0; TNS_CLAMP(b,0,OUR_PIX_MAX);
|
|
|
+ target[3]=a; target[0]=r*fac_1t; target[1]=g*fac_1t; target[2]=b*fac_1t;
|
|
|
+}
|
|
|
void our_CanvasAlphaOverStraight(OUR_PIX_COMPACT* target, OUR_PIX_COMPACT* source, real alpha){
|
|
|
real a_1=(real)(OUR_PIX_MAX-source[3]*alpha)/OUR_PIX_MAX;
|
|
|
uint64_t a=(uint64_t)(source[3])*alpha+(uint64_t)(target[3])*a_1; TNS_CLAMP(a,0,OUR_PIX_MAX);
|
|
|
@@ -201,6 +211,16 @@ void our_CanvasAddStraight(OUR_PIX_COMPACT* target, OUR_PIX_COMPACT* source, rea
|
|
|
uint64_t b=((uint64_t)source[2]*alpha*source[3]+(uint64_t)target[2]*target[3])/a; TNS_CLAMP(b,0,OUR_PIX_MAX);
|
|
|
target[3]=a; target[0]=r; target[1]=g; target[2]=b;
|
|
|
}
|
|
|
+void our_CanvasMultiplyStraight(OUR_PIX_COMPACT* target, OUR_PIX_COMPACT* source, real alpha){
|
|
|
+ uint64_t a=target[3]; real fac=((real)source[3])/OUR_PIX_MAX*alpha; real fac_1=1.0f-fac;
|
|
|
+ real rr=((real)target[0]/OUR_PIX_MAX);
|
|
|
+ real rg=((real)target[1]/OUR_PIX_MAX);
|
|
|
+ real rb=((real)target[2]/OUR_PIX_MAX);
|
|
|
+ uint64_t r=(rr*fac_1 + ((real)((real)source[0]/OUR_PIX_MAX)*rr)*fac)*OUR_PIX_MAX; TNS_CLAMP(r,0,OUR_PIX_MAX);
|
|
|
+ uint64_t g=(rg*fac_1 + ((real)((real)source[1]/OUR_PIX_MAX)*rg)*fac)*OUR_PIX_MAX; TNS_CLAMP(g,0,OUR_PIX_MAX);
|
|
|
+ uint64_t b=(rb*fac_1 + ((real)((real)source[2]/OUR_PIX_MAX)*rb)*fac)*OUR_PIX_MAX; TNS_CLAMP(b,0,OUR_PIX_MAX);
|
|
|
+ target[3]=a; target[0]=r; target[1]=g; target[2]=b;
|
|
|
+}
|
|
|
|
|
|
typedef void (*our_MixFuncRGBA)(OUR_PIX_COMPACT* target, OUR_PIX_COMPACT* source, real alpha);
|
|
|
|
|
|
@@ -987,7 +1007,9 @@ void our_CanvasDrawTextures(tnsOffscreen* off1,tnsOffscreen* off2){
|
|
|
elif(Our->SketchMode == 2){ a=0.0f; }
|
|
|
}
|
|
|
tnsVectorSet4(MultiplyColor,a,a,a,a); int any=0;
|
|
|
- int mixmode=TNS_MIX_NORMAL; if(l->BlendMode==OUR_BLEND_ADD){ mixmode=TNS_MIX_ADD; }
|
|
|
+ int mixmode=TNS_MIX_NORMAL;
|
|
|
+ if(l->BlendMode==OUR_BLEND_ADD){ mixmode=TNS_MIX_ADD; }
|
|
|
+ elif(l->BlendMode==OUR_BLEND_MULTIPLY){ mixmode=TNS_MIX_MULTIPLY; }
|
|
|
if(Our->PigmentMode){
|
|
|
glUniform1f(OURU->uMixingTop,a);
|
|
|
}
|
|
|
@@ -2294,9 +2316,11 @@ void our_TileTextureToImage(OurTexTile* ot, int SX, int SY, int composite, int B
|
|
|
if(Our->AlphaMode){
|
|
|
if(BlendMode==OUR_BLEND_NORMAL) mixfunc=our_CanvasAlphaOverStraight;
|
|
|
elif(BlendMode==OUR_BLEND_ADD) mixfunc=our_CanvasAddStraight;
|
|
|
+ elif(BlendMode==OUR_BLEND_MULTIPLY) mixfunc=our_CanvasMultiplyStraight;
|
|
|
}else{
|
|
|
if(BlendMode==OUR_BLEND_NORMAL) mixfunc=our_CanvasAlphaOver;
|
|
|
elif(BlendMode==OUR_BLEND_ADD) mixfunc=our_CanvasAdd;
|
|
|
+ elif(BlendMode==OUR_BLEND_MULTIPLY) mixfunc=our_CanvasMultiply;
|
|
|
}
|
|
|
for(int row=0;row<OUR_TILE_W_USE;row++){
|
|
|
for(int col=0;col<OUR_TILE_W_USE;col++){
|
|
|
@@ -5535,6 +5559,7 @@ void ourRegisterEverything(){
|
|
|
p=laAddEnumProperty(pc,"blend_mode","Blend Mode","How this layer is blended onto the stuff below",0,0,0,0,0,offsetof(OurLayer,BlendMode),0,ourset_LayerBlendMode,0,0,0,0,0,0,0,0);
|
|
|
laAddEnumItemAs(p,"NORMAL","Normal","Normal alpha blend",OUR_BLEND_NORMAL,0);
|
|
|
laAddEnumItemAs(p,"ADD","Add","Pixel values are simply added together",OUR_BLEND_ADD,0);
|
|
|
+ laAddEnumItemAs(p,"MULTIPLY","Multiply","Pixel values are multiplied together",OUR_BLEND_MULTIPLY,0);
|
|
|
laAddRawProperty(pc,"segmented_info","Segmented Info","Image segmented info",0,0,ourget_LayerImageSegmentedInfo,ourset_LayerImageSegmentedInfo,LA_UDF_ONLY);
|
|
|
p=laAddRawProperty(pc,"image","Image","The image data of this tile",0,0,ourget_LayerImage,ourset_LayerImage,LA_UDF_ONLY);
|
|
|
laRawPropertyExtraFunctions(p,ourget_LayerImageSegmented,ourget_LayerImageShouldSegment);
|