*/}}
Browse Source

multiply mode

YimingWu 1 day ago
parent
commit
59a75bbea4
3 changed files with 28 additions and 2 deletions
  1. 1 1
      GenerateAppimage.py
  2. 26 1
      ouroperations.c
  3. 1 0
      ourpaint.h

+ 1 - 1
GenerateAppimage.py

@@ -7,7 +7,7 @@ AppDir:
     id: chengdu.littlea.ourpaint
     name: OurPaint
     icon: application-x-executable
-    version: v0.5
+    version: v0.5a
     exec: OurPaint
     exec_args: $@
   apt:

+ 26 - 1
ouroperations.c

@@ -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);

+ 1 - 0
ourpaint.h

@@ -153,6 +153,7 @@ STRUCTURE(OurTexTile){
 
 #define OUR_BLEND_NORMAL 0
 #define OUR_BLEND_ADD 1
+#define OUR_BLEND_MULTIPLY 2
 
 typedef struct OurLayerImageSegmented{
     uint32_t Sizes[32];