Problems when trying to draw to a P3D PGraphics when called from a thread?

Although it’s pretty much a hack, here’s the workaround I’ve come up w/: :crazy_face:

/**
 * Threaded PGraphics II (v1.0.1)
 * GoToLoop (2018/Dec/07)
 *
 * https://Discourse.Processing.org/t/
 * problems-when-trying-to-draw-to-a-p3d-pgraphics-
 * when-called-from-a-thread/6301/4
 *
 * https://Forum.Processing.org/two/discussion/25799/
 * how-to-draw-a-rect-in-a-thread#Item_2
 */

static final int W = 250, H = 200, FPS = 10;
Layer layer;

void settings() {
  size(W, H, JAVA2D);
  smooth(3);
}

void setup() {
  frameRate(FPS);
  colorMode(RGB);
  imageMode(CORNER);

  final String[] switches = { ARGS_SKETCH_FOLDER + sketchPath(), "" };
  runSketch(switches, layer = new Layer());

  while (layer.img == null)  delay(1);
}

void draw() {
  getSurface().setTitle("Frames: " + frameCount);
  background((color) random(#000000));
  image(layer.img, 0, 0);
}

public static class Layer extends PApplet {
  static final short INTERVAL = 1*1000, TXT_SIZE = 40;
  static final float BOLD = 2.5;
  static final color BORDER = 0, TXT_COLOR = -1;

  PGraphics pg;
  PImage img;

  void settings() {
    size(1, 1, P2D);
  }

  void setup() {
    getSurface().setVisible(false);
    initDisplay();
  }

  void draw() {
    displayLoop();
  }

  void displayLoop() {
    final PGraphics graph = pg;
    final int cx = pg.width>>1, cy = pg.height>>1;

    for (int frames = 1;; delay(INTERVAL), ++frames) {
      graph.beginDraw();

      graph.clear();
      graph.fill((color) random(#000000));
      graph.rect(cx, cy, cx, cy);

      graph.fill(TXT_COLOR);
      graph.text(frames, cx, cy);

      graph.endDraw();

      transferDisplay();
    }
  }

  void transferDisplay() {
    pg.loadPixels();
    arrayCopy(pg.pixels, img.pixels);
    img.updatePixels();
  }

  void initDisplay() {
    pg = createGraphics(W, H, P2D);
    pg.smooth(8);

    pg.beginDraw();

    pg.colorMode(RGB);
    pg.rectMode(CENTER);

    pg.strokeWeight(BOLD);
    pg.stroke(BORDER);

    pg.textSize(TXT_SIZE);
    pg.textAlign(CENTER, CENTER);

    pg.endDraw();

    img = pg.get();
  }
}
2 Likes