*/}}
Browse Source

can't figure out smudge

Yiming Wu 1 year ago
parent
commit
c46803ef5c
2 changed files with 34 additions and 18 deletions
  1. 33 17
      ouroperations.c
  2. 1 1
      ourpaint.h

+ 33 - 17
ouroperations.c

@@ -15,11 +15,20 @@ uniform float uBrushHardness;\n\
 uniform float uBrushSmudge;\n\
 uniform vec4 uBrushColor;\n\
 uniform vec4 uBackgroundColor;\n\
+vec4 mix_over(vec4 colora, vec4 colorb){\n\
+    vec4 c; c.a=colora.a+colorb.a*(1-colora.a);\n\
+    c.rgb=(colora.rgb*colora.a+colorb.rgb*colorb.a*(1-colora.a))/c.a;\n\
+    return c;\n\
+}\n\
+float erase(float a, float target_a, float eraser_a){\n\
+    return mix(a,target_a,eraser_a);\n\
+}\n\
 int dab(float d, vec4 color, float size, float hardness, float smudge, vec4 smudge_color, vec4 last_color, out vec4 final){\n\
-    color.rgb=mix(color,smudge_color,smudge*smudge_color.a).rgb;\n\
-    color.a=color.a*(1-smudge);\n\
-    float a=clamp(color.a*1-pow(d/size,1+1/(1-hardness)),0,1);\n\
-    final=vec4(mix(last_color.rgb,color.rgb,a), 1-(1-last_color.a)*(1-a));\n\
+    vec4 cc; cc.rgb=mix(color,smudge_color,smudge*smudge_color.a).rgb;\n\
+    float fac=(1-pow(d/size,1+1/(1-hardness)));\n\
+    cc.a=clamp(mix(color.a,smudge_color.a,smudge)*fac,0,1);\n\
+    final=mix_over(cc,last_color);\n\
+    final.a=erase(final.a,mix(color.a,smudge_color.a,smudge),fac*smudge*(1-color.a));\n\
     return 1;\n\
 }\n\
 subroutine void BrushRoutines();\n\
@@ -212,7 +221,7 @@ void our_CanvasDrawCanvas(laBoxedTheme *bt, OurPaint *unused_c, laUiItem* ui){
 
     //our_CANVAS_TEST(bt,ui);
 
-    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+    //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
     tnsDrawToOffscreen(e->OffScr,1,0);
     tnsViewportWithScissor(0, 0, W, H);
@@ -222,7 +231,7 @@ void our_CanvasDrawCanvas(laBoxedTheme *bt, OurPaint *unused_c, laUiItem* ui){
     //if(ocd->ShowTiles){ our_CanvasDrawTiles(); }
     our_CanvasDrawTextures();
 
-    glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
+    //glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
 }
 
 OurLayer* our_NewLayer(char* name){
@@ -272,6 +281,9 @@ void our_UiToCanvas(laCanvasExtra* ex, laEvent*e, real* x, real *y){
     *x = (real)((real)e->x - (real)(ex->ParentUi->R - ex->ParentUi->L) / 2 - ex->ParentUi->L) * ex->ZoomX + ex->PanX;
     *y = (real)((real)(ex->ParentUi->B - ex->ParentUi->U) / 2 - (real)e->y + ex->ParentUi->U) * ex->ZoomY + ex->PanY;
 }
+void our_PaintResetBrushState(OurBrush* b){
+    b->BrushRemainingDist = 0; b->SmudgeAccum=0; b->SmudgeRestart=1;
+}
 real our_PaintGetDabStepDistance(OurBrush* b, real pressure){
     if(!b->PressureSize) return b->Size/b->DabsPerSize;
     real d=b->Size/b->DabsPerSize*pressure; if(d<1e-2) d=1e-2; return d;
@@ -339,29 +351,32 @@ void our_PaintDoDabs(OurLayer* l,int tl, int tr, int tu, int tb, int Start, int
 }
 STRUCTURE(OurSmudgeSegement){
     laListItem Item;
-    int Start,End;
+    int Start,End,Resample;
 };
 void our_PaintDoDabsWithSmudgeSegments(OurLayer* l,int tl, int tr, int tu, int tb){
     laListHandle Segments={0}; int from=0,to=Our->NextDab; if(!Our->NextDab) return;
     OurSmudgeSegement* oss;
     oss=lstAppendPointerSized(&Segments, 0,sizeof(OurSmudgeSegement));
     for(int i=1;i<to;i++){
-        if(Our->Dabs[i].ResampleSmudge){ oss->Start=from; oss->End=i; from=i; oss=lstAppendPointerSized(&Segments, 0,sizeof(OurSmudgeSegement)); }
+        if(Our->Dabs[i].ResampleSmudge){ oss->Resample=1;
+             oss->Start=from; oss->End=i; from=i; oss=lstAppendPointerSized(&Segments, 0,sizeof(OurSmudgeSegement)); }
     }
     oss->Start=from; oss->End=to;
+    if(Our->Dabs[0].ResampleSmudge){ ((OurSmudgeSegement*)Segments.pFirst)->Resample=1; }
 
     glUseProgram(Our->CanvasProgram);
 
-    if(!Segments.pFirst){ our_PaintDoDabs(l,tl,tr,tu,tb,0,Our->NextDab); return; }
-
     while(oss=lstPopItem(&Segments)){
-        float x=Our->Dabs[oss->Start].X, y=Our->Dabs[oss->Start].Y;
-        int col=(int)(floor(OUR_TEX_TILE_CTR+x/OUR_TEX_TILE_W_USE+0.5)); TNS_CLAMP(col,0,OUR_TEX_TILES_PER_ROW-1);
-        int row=(int)(floor(OUR_TEX_TILE_CTR+y/OUR_TEX_TILE_W_USE+0.5)); TNS_CLAMP(row,0,OUR_TEX_TILES_PER_ROW-1);
-        glBindImageTexture(0, l->TexTiles[row][col]->Texture->GLTexHandle, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
-        int sx=((real)col-OUR_TEX_TILE_CTR-0.5)*OUR_TEX_TILE_W_USE-OUR_TEX_TILE_SEAM,sy=((real)row-OUR_TEX_TILE_CTR-0.5)*OUR_TEX_TILE_W_USE-OUR_TEX_TILE_SEAM;
-        glBindImageTexture(1, Our->SmudgeTexture->GLTexHandle, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
-        our_PaintDoSample(x,y,sx,sy);
+        if(oss->Resample || Our->CurrentBrush->SmudgeRestart){
+            float x=Our->Dabs[oss->Start].X, y=Our->Dabs[oss->Start].Y;
+            int col=(int)(floor(OUR_TEX_TILE_CTR+x/OUR_TEX_TILE_W_USE+0.5)); TNS_CLAMP(col,0,OUR_TEX_TILES_PER_ROW-1);
+            int row=(int)(floor(OUR_TEX_TILE_CTR+y/OUR_TEX_TILE_W_USE+0.5)); TNS_CLAMP(row,0,OUR_TEX_TILES_PER_ROW-1);
+            glBindImageTexture(0, l->TexTiles[row][col]->Texture->GLTexHandle, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
+            int sx=((real)col-OUR_TEX_TILE_CTR-0.5)*OUR_TEX_TILE_W_USE-OUR_TEX_TILE_SEAM,sy=((real)row-OUR_TEX_TILE_CTR-0.5)*OUR_TEX_TILE_W_USE-OUR_TEX_TILE_SEAM;
+            glBindImageTexture(1, Our->SmudgeTexture->GLTexHandle, 0, GL_FALSE, 0, GL_READ_WRITE, GL_RGBA8);
+            our_PaintDoSample(x,y,sx,sy);
+            Our->CurrentBrush->SmudgeRestart=0;
+        }
 
         //printf("from to %d %d %d\n", oss->Start,oss->End,Our->Dabs[oss->Start].ResampleSmudge);
 
@@ -425,6 +440,7 @@ int ourinv_MoveBrush(laOperator* a, laEvent* e){
 
 int ourinv_Paint(laOperator* a, laEvent* e){
     OurLayer* l=Our->CurrentLayer; OurCanvasDraw *ex = a->This?a->This->EndInstance:0; OurBrush* ob=Our->CurrentBrush; if(!l||!ex||!ob) return LA_CANCELED;
+    our_PaintResetBrushState(ob);
     real x,y; our_UiToCanvas(&ex->Base,e,&x,&y); ex->CanvasLastX=x;ex->CanvasLastY=y;ex->LastPressure=e->Pressure;
     return LA_RUNNING;
 }

+ 1 - 1
ourpaint.h

@@ -38,7 +38,7 @@ STRUCTURE(OurBrush){
     real Hardness;
     real Transparency;
     real Smudge;
-    real SmudgeResampleLength; real SmudgeAccum;
+    real SmudgeResampleLength; real SmudgeAccum; int SmudgeRestart;
     real BrushRemainingDist;
     int UseNodes; // the flexible way
     int PressureSize,PressureHardness,PressureTransparency,PressureSmudge; // the simple way