I’m new to Processing, and have my project working but with some performance issues.
Basically I have 10 images that I’m scaling and moving (with lerp) when a key is pressed. Eventually I’d like to get this up to 100 images, but the performance is pretty bad with just 10.
Here’s the code:
Shard[] shards = new Shard[10];
void setup() {
size(800, 600);
for (int i = 0; i < 10; i++) {
shards[i] = new Shard("square.png");
}
smooth();
frameRate(30);
}
void keyPressed() {
if (key == ' ') {
for (int i = 0; i < 10; i++) {
shards[i].triggerPulse();
}
}
}
void draw(){
background(0);
for (int i = 0; i < 10; i++) {
shards[i].move();
shards[i].display();
}
}
This is the code for the Shard class:
class Shard {
PVector target;
PVector origin;
PVector current;
float targetScale;
float startScale;
float currentScale;
float speed;
PImage image;
Shard(String imagePath) {
origin = new PVector(width/2, height/2);
target = new PVector(random(width), random(height));
current = new PVector(origin.x, origin.y);
currentScale = 1.0;
startScale = 1.0;
targetScale = 1.0;
speed = 0;
image = loadImage(imagePath);
}
void display() {
imageMode(CENTER);
image(image, current.x, current.y, image.width * currentScale, image.height * currentScale);
}
void triggerPulse() {
target = new PVector(random(width), random(height));
targetScale = random(2.0);
}
void move() {
speed += 0.1;
// Compute the new positions
current.x = lerp(current.x, target.x, sin(speed));
current.y = lerp(current.y, target.y, sin(speed));
currentScale = lerp(currentScale, targetScale, sin(speed));
if (current.x == target.x || current.y == target.y) {
target = new PVector(origin.x, origin.y);
targetScale = startScale;
speed = 0;
}
if (current.x == origin.x || current.y == origin.y) {
speed = 0;
}
}
}
Any obvious mistakes here or improvements I can make to speed this up?
1 Like
kll
February 17, 2019, 6:37am
2
while you move and re-scale all pictures the FPS will drop,
but when stop moving actually no use to show “many” pictures, only the ONE.
example:
// https://discourse.processing.org/t/tips-for-speeding-up-this-sketch/8468
int many =10;
Shard[] shards = new Shard[many];
int showid = 0;
void setup() {
size(800, 600);
for (int i = 0; i <many; i++) shards[i] = new Shard("square.png", i);
}
void keyPressed() {
if (key == ' ') {
for (int i = 0; i <many; i++) shards[i].triggerPulse();
showid = (int)random(many); // select next random picture to show
println("new pic "+showid);
}
}
void draw() {
surface.setTitle("my gallery "+nf(frameRate,1,1));
background(200, 200, 0);
for (int i = 0; i < many; i++) shards[i].moveAndshow();
}
class Shard {
PVector target;
PVector origin;
PVector current;
float targetScale;
float startScale;
float currentScale;
float speed;
PImage image;
int id;
Shard(String imagePath, int id) {
origin = new PVector(width/2, height/2);
target = new PVector(random(width), random(height));
current = new PVector(origin.x, origin.y);
currentScale = 1.0;
startScale = 1.0;
targetScale = 1.0;
speed = 0;
image = loadImage(imagePath);
this.id = id;
}
void display() {
imageMode(CENTER);
image(image, current.x, current.y, image.width * currentScale, image.height * currentScale);
fill(0);
text(id, width/2, height/2);
}
void triggerPulse() {
target = new PVector(random(width), random(height));
targetScale = random(2.0);
}
void moveAndshow() {
if (current.x == target.x || current.y == target.y) {
target = new PVector(origin.x, origin.y);
targetScale = startScale;
speed = 0;
} else {
speed += 0.1;
// Compute the new positions
current.x = lerp(current.x, target.x, sin(speed));
current.y = lerp(current.y, target.y, sin(speed));
currentScale = lerp(currentScale, targetScale, sin(speed));
}
if (current.x == origin.x || current.y == origin.y) speed = 0;
// show it from here, not need extra call from draw
if ( speed > 0 ) display(); // show all while moving // very slow
else if ( id == showid ) display(); // show only one random pic
}
}
2 Likes
i think if you switch over to the P2D renderer you will get much better results.
this runs 100 well on my machine
int amount;
Shard[] shards;
void setup() {
size(800, 600, P2D);
amount = 100;
shards = new Shard[amount];
for (int i = 0; i < amount; i++) {
shards[i] = new Shard("square.png");
}
imageMode(CENTER);
smooth();
frameRate(30);
}
void keyPressed() {
if (key == ' ') {
for (int i = 0; i < amount; i++) {
shards[i].triggerPulse();
}
}
}
void draw(){
background(0);
for (int i = 0; i < amount; i++) {
shards[i].move();
shards[i].display();
}
}
class Shard {
PVector target;
PVector origin;
PVector current;
float targetScale;
float startScale;
float currentScale;
float speed;
PImage image;
Shard(String imagePath) {
origin = new PVector(width/2, height/2);
target = new PVector(random(width), random(height));
current = new PVector(origin.x, origin.y);
currentScale = 1.0;
startScale = 1.0;
targetScale = 1.0;
speed = 0;
image = loadImage(imagePath);
}
void display() {
image(image, current.x, current.y, image.width * currentScale, image.height * currentScale);
}
void triggerPulse() {
target.x = random(width);
target.y = random(height);
targetScale = random(2.0);
}
void move() {
speed += 0.1;
// Compute the new positions
float n = sin(speed);
current.x = lerp(current.x, target.x, n);
current.y = lerp(current.y, target.y, n);
currentScale = lerp(currentScale, targetScale, n);
if (current.x == target.x || current.y == target.y) {
//if(PVector.dist(current, target) < 10) {
target.x = origin.x;
target.y = origin.y;
targetScale = startScale;
speed = 0;
}
}
}
if you mix this with kll’s great optimizations i think you will have found your solution.
2 Likes
Awesome - switching renderers made a huge difference.
Thank you!
Hmm - eventually, I’ll be using different images with varying levels of opacity, so they will need to remain visible even when not moving.
Creating a variable to hold the number of shards is a great idea though, thank you!