Skia Graphics as background

Hi, I’m trying to use skiaGraphics on linux as background.
See this post for more explanation on skia : skia Discussion
In my code, I must choose : even skia works and PGraphics not or vice versa.

import micycle.processingSkia.SkiaCanvas;
import org.jetbrains.skija.*;
PGraphics pg;
Canvas skiaCanvas;
Rect rect;
void settings() {
    size(1024, 768, P2D);
}
void setup() {
    skiaCanvas = SkiaCanvas.getSkiaCanvas(this);
    rect = new Rect(0, 0, width, height);
    pg = createGraphics(width, height, P2D);    
}
void draw() {  
    Paint fill = new Paint().setShader(Shader.makeLinearGradient(77, 184, -11, 539, new int[] {0xffffa527, 0xFF4CA387}));
    skiaCanvas.drawRect(rect, fill);
    pg.beginDraw();
    pg.fill(20, 220, 200);
    pg.ellipse(200, 200, 220, 300);
    pg.endDraw();
    image(pg, 0, 0);
}

There is way to work around ?
Thanks for help

I encountered this issue when making the library and couldn’t find a workaround.

It’s happening because both Processing and Skija are flushing to the GL canvas/graphics context.

As per below, Processing only flushes when something’s been drawn with the loop – that’s why Skija works as long as no Processing drawing happens.

I’m not experienced enough in OPENGL enough to figure out why both cannot flush after each other, and whether anything can be done to fix the problem (integrating the two) – anyone?


That said, you should be able to do render all the primitives you need with the Skija renderer alone:

The problem is that I need to write text and use mask for images.
I wanted to use skia as background of my program.
It’s pity, thanks for help anyway.

Hi @matheynen ,

You could write a linear gradient with a frag shader.

cap

linear.frag

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

uniform vec4 aColor;
uniform vec4 bColor;
uniform vec2 origin;
uniform vec2 dest;

void main() {
    vec2 a = gl_FragCoord.xy - origin;
    vec2 b = dest - origin;
    float fac = clamp(dot(a, b) / dot(b, b), 0.0, 1.0);
    gl_FragColor = mix(aColor, bColor, fac);
}

sketch:

PGraphics2D main;
PGraphics2D buff;
PShader linearGradient;
float[] aColor = { 1.0f, 0.64705884f, 0.15294118f, 1.0f };
float[] bColor = { 0.29803923f, 0.6392157f, 0.5294118f, 1.0f };
float[] origin = { 77.0f, 184.0f };
float[] dest = { -11.0f, 539.0f };

void settings() {
  size(512, 384, P2D);
}

void setup() {
  main = (PGraphics2D)getGraphics();
  buff = (PGraphics2D)createGraphics(1024, 768, P2D);
  linearGradient = loadShader("linear.frag");
  linearGradient.set("origin", origin[0], origin[1]);
  linearGradient.set("dest", dest[0], dest[1]);
  linearGradient.set("aColor", aColor[0], aColor[1], aColor[2], aColor[3]);
  linearGradient.set("bColor", bColor[0], bColor[1], bColor[2], bColor[3]);
}

void draw() {
  buff.beginDraw();
  buff.shader(linearGradient);
  buff.ellipse(buff.width * 0.5f, buff.height * 0.5f, 750, 750);
  buff.endDraw();

  main.background(0xff000000);
  main.image(buff, 0.0f, 0.0f, main.width, main.height);
}

The coordinate part of the shader is the easy part. If makeLinearGradient does anything like gamma correction, then it gets a bit more involved; i left it at an sRGB blend.

Best,
Jeremy

Ok, thanks for help but I’m not fluent with shaders.
So I did it myself. Here’s my solution :

pgFond.beginDraw();
  for (int i=0; i<pgFond.height; i++) {
        color c = lerpColor(backCol[0], backCol[1], map(i, 0, pgFond.height, 0, 1));
        pgFond.stroke(c);
        pgFond.line(0, i, pgFond.width, i);
     }
 pgFond.endDraw();

Bye