Launcher for Multi-Renderer PApplets

Hello folks!

This is an exploration of a launcher for PApplets (JAVA2D, P2D, P3D, FX2D):

/**
 * Launcher for Multi-Renderer PApplets
 * 
 * Author: glv
 * Date: 2025-07-07
 * 
 * Description:
 * Launches four separate Processing sketches (PApplets) using different renderers:
 * - JAVA2D
 * - P2D
 * - P3D
 * - FX2D
 * 
 * Each renderer runs in its own thread, with readiness flags for communication.
 * Allows visual comparison of renderer behavior and DPI scaling issues on Windows.
 * 
 * Notes:
 * - Uses `volatile` flags to ensure safe thread communication.
 * - Each PApplet has a window title and custom location.
 * - Both lambda and traditional Runnable launch methods shown for `app_0`.
 * - Can be extended for inter-applet communication or benchmarking.
 * 
 * Assisted by: ChatGPT (OpenAI)
 */


// Processing JavaFX library
import processing.javafx.*;

// Renderer Applets:
renderApp_0 app_0; // JAVA2D
renderApp_1 app_1; // P2D
renderApp_2 app_2; // P3D
renderApp_3 app_3; // FX2D

// Shared volatile flags for thread safety
volatile boolean ready_0 = false;
volatile boolean ready_1 = false;
volatile boolean ready_2 = false;
volatile boolean ready_3 = false;

boolean ready_p0 = false;
boolean ready_p1 = false;
boolean ready_p2 = false;
boolean ready_p3 = false;

int ws = 200;
int sp;

boolean db = false;        // Debug true or false

void settings() {
  size(ws, ws);
  sp = 300;
}

void setup() {
  surface.setTitle("Launcher");
  surface.setVisible(true);
  surface.setLocation(0 * sp, 10);

  displayDensity(1); // Use if necessary

  // app_0 Lambda Thread (active)
  app_0 = new renderApp_0();
  Thread thread_0 = new Thread(() -> PApplet.runSketch(new String[]{"renderapp_0"}, app_0));
  thread_0.start();

  // app_0 Traditional Runnable (commented out)
  /*
  app_0 = new renderApp_0();
  Runnable runnable_0 = new Runnable() {
    @Override
    public void run() {
      PApplet.runSketch(new String[]{"renderapp_0"}, app_0);
    }
  };
  Thread thread_0 = new Thread(runnable_0);
  thread_0.start();
  */

  // app_1
  app_1 = new renderApp_1();
  Thread thread_1 = new Thread(() -> PApplet.runSketch(new String[]{"renderApp_1"}, app_1));
  thread_1.start();

  // app_2
  app_2 = new renderApp_2();
  Thread thread_2 = new Thread(() -> PApplet.runSketch(new String[]{"renderApp_2"}, app_2));
  thread_2.start();

  // app_3  This is 1.25x larger on my W10 PC because of windows scaling settings!
  app_3 = new renderApp_3();
  Thread thread_3 = new Thread(() -> PApplet.runSketch(new String[]{"renderApp_3"}, app_3));
  thread_3.start();
}

void draw() {
  background(255);
  translate(width/2, height/2);

  fill(0);
  textSize(24);
  textAlign(CENTER, CENTER);
  text("Launcher JAVA2D", 0, 0);

  checkStatus();
}

void checkStatus() {
  if (ready_0 && !ready_p0) {
    println("0:", frameCount, millis(), ready_0);
    ready_p0 = true;
  }

  if (ready_1 && !ready_p1) {
    println("1:", frameCount, millis(), ready_1);
    ready_p1 = true;
  }

  if (ready_2 && !ready_p2) {
    println("2:", frameCount, millis(), ready_2);
    ready_p2 = true;
  }

  if (ready_3 && !ready_p3) {
    println("3:", frameCount, millis(), ready_3);
    ready_p3 = true;
  }
}

//****************************************************************

// JAVA2D
class renderApp_0 extends PApplet {
  void settings() {
    if (db) delay(1000);
    size(ws, ws, JAVA2D);
  }

  void setup() {
    surface.setVisible(true);
    surface.setTitle("R0 JAVA2D");
    //surface.setLocation(1*sp, 10);
    surface.setLocation(1 * sp * 4/5, 10); // Adjust for scaling of 1.25x (5/4)
    println("R0 JAVA2D");

    ready_0 = true;
  }

  void draw() {
    background(255);
    translate(width/2, 2 * height/3);

    fill(0);
    textSize(24);
    textAlign(CENTER, CENTER);
    text("Renderer 0: \r\n JAVA2D", 0, -height/2);

    strokeWeight(2);
    line(-50, 50, 50, -50);
    line(-50, -50, 50, 50);
  }
}

//****************************************************************

// P2D
class renderApp_1 extends PApplet {
  void settings() {
    if (db) delay(2000);
    size(ws, ws, P2D);

    //noSmooth();
    smooth(4);
  }

  void setup() {
    surface.setVisible(true);
    surface.setTitle("R1 P2D");
    surface.setLocation(2 * sp, 10);

    println("R1 P2D:");
    println(2 * sp);
  }

  void draw() {
    background(255);
    translate(width/2, 2 * height/3);

    fill(0);
    textSize(24);
    textAlign(CENTER, CENTER);
    text("Renderer 1: \r\n P2D", 0, -height/2);

    strokeWeight(2);
    line(-50, 50, 50, -50);
    line(-50, -50, 50, 50);
    
    ready_1 = true;
  }
}

//****************************************************************

// P3D
class renderApp_2 extends PApplet {
  void settings() {
    if (db) delay(3000);
    size(ws, ws, P3D);
  }

  void setup() {
    surface.setVisible(true);
    surface.setTitle("R2 P3D");
    surface.setLocation(3 * sp, 10);

    println("R2 P3D");
    println(3 * sp);

    ready_2 = true;
  }

  void draw() {
    background(255);
    translate(width/2, height/2);
    lights();

    push();
    translate(0, height/ 8);
    lights();
    fill(0, 255, 0);
    rotateY((frameCount % 360) * (TAU/360));
    //noStroke();
    stroke(128+64);
    sphere(50);
    pop();
    
    //hint(DISABLE_DEPTH_TEST);
    //ortho();
    noLights();
    fill(0);
    textSize(24);
    textAlign(CENTER, CENTER);
    text("Renderer 2: \r\n P3D", 0, -height/3);
    //hint(ENABLE_DEPTH_TEST);        
  }
}

//****************************************************************

// FX2D
class renderApp_3 extends PApplet {
  boolean tog;
  
  void settings() {
    if (db) delay(4000);
    size(ws, ws, FX2D);
  }

  void setup() {
    surface.setVisible(true);
    surface.setTitle("R3 FX2D");
    //surface.setLocation(4 * sp, 10);
    surface.setLocation(4*sp*4/5, 10); // // Adjust for scaling of 1.25x (5/4)

    println("R3 FX2D:");
    println(4*sp);

    ready_3 = true;
  }

  void draw() {
    background(255);
    translate(width/2, 2 * height/3);

    fill(0);
    textSize(24);
    textAlign(CENTER, CENTER);
    text("Renderer 3: \r\n FX2D", 0, -height/2);

    strokeWeight(2);
    line(-50, 50, 50, -50);
    line(-50, -50, 50, 50);
  }
}

Output with Processing 4.4.4, W10, Windows scaling: 1.25x:

Output with Processing 4.3.4, W10, Windows scaling: 1.25x:

I used it for testing Windows scaling (1.25x on my system) for different renderers.

Modify println() and debug code as required.

:)

1 Like

(post deleted by author)

1 Like