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.
:)