Can I decrease lag when using multiple images?

Hi! 3rd question here and this time I don't think I can solve it by myself.

I have a bunch of images displayed and rotating. It runs fine in a smaller window but lags in a larger. So I'm wondering if there's a better way for me to do this. I'll post the main sketch and the class pic_map that actually draws it. Please help my brain. Am I using to many pictures? The average size of the images are 7k.

Main:

pic_map[] p;

PImage[] img; 

color[] c = new color[24];

int[] x = {415, 285, 143, 459, 336, 195, 524, 435, 340, 629, 600, 554, 754, 779, 813, 865, 944, 1039, 923, 1044, 1181, 944, 1070, 1220};

int[] y = {684, 698, 711, 553, 508, 454, 446, 351, 241, 380, 250, 113, 389, 261, 115, 454, 350, 247, 558, 510, 454, 687, 691, 692};

int[] s_ize = {120, 130, 150, 120, 130, 150, 120, 130, 150, 120, 130, 150, 120, 130, 150, 120, 130, 150, 120, 130, 150, 120, 130, 150};

String[][] path = {
  {"bilder/A/0.png", "bilder/A/1.png"},
  {"bilder/B/0.png", "bilder/B/1.png", "bilder/B/2.png"},
  {"bilder/C/0.png", "bilder/C/1.png"},
  {"bilder/D/0.png", "bilder/D/1.png", "bilder/D/2.png"},
  {"bilder/E/0.png", "bilder/E/1.png"},
  {"bilder/F/0.png"},
  {"bilder/G/0.png", "bilder/G/1.png", "bilder/G/1.png"},
  {"bilder/H/0.png", "bilder/H/1.png", "bilder/H/2.png", "bilder/H/3.png"},
  {"bilder/I/0.png", "bilder/I/1.png", "bilder/I/2.png", "bilder/I/3.png"},
  {"bilder/J/0.png", "bilder/J/1.png"},
}; 

float[][] rot = {
  {0.5, 1.0},
  {0.5, 1.1, -0.2},
  {0.6, -1.0},
  {0.5, 1.0, -0.3},
  {0.5, 1.0},
  {0.3},
  {0.5, 0.5, -0.5},
  {0.6, 0.4, -0.5, 0.4},
  {0.5, 0.5, -0.5, 0.4},
  {0.8, 0.3, -0.5}
};

float ratio = 1;


void setup() {
  //fullScreen();

  frameRate(30
  );

  size(500,300);
  ratio = float(width) / 1280.0;
  print(ratio);

  p = new pic_map[10];
  for(int i = 0; i < 10; i++){
    p[i] = new pic_map(s_ize[i]*ratio, path[i], rot[i]);
  }

  rectMode(CENTER);
}

void draw()
{
  test_set();
}

void test_set(){
  background(0);
  for (int i = 0; i < 24; i++) {
      int h = i%10;
      p[h].draw_it(x[i]*ratio, y[i]*ratio);
    }
}

Pic map:

class pic_map{

  PImage[] img;
  float size;

  float[] rotate_box;

  float[] rotation = {1,1,1};

  //Scale
  int scale = 0;
  int top = 50;
  int low = 0;

  pic_map(float siz, String[] path, float[] rot) {

    rotate_box = new float[rot.length];
    rotate_box = rot;

    size = siz;

    img = new PImage[path.length];
    for(int i = 0; i < path.length; i++){
      img[i] = loadImage(path[i]);
    }

    rotation = new float[path.length];

    imageMode(CENTER);
  }

  void rotate_it(int index, float rot){
    rotate_box[index] = rot;
  }


  void scale_set(int s, int t, int l){
    scale = s;
    top = t;
    low = l;
  }

  void draw_it(float x, float y){

    size = size + scale % (top-low);

    for(int i = 0; i < img.length; i++){
      rotation[i] = (rotation[i] + rotate_box[i]) % 100;
      pushMatrix();
      translate(x, y);
      rotate(PI*(rotation[i]/100 * 2));
      image(img[i], 0, 0, size+low, size+low);
      popMatrix();

    }
  }
}
Tagged:

Answers

  • edited June 2017

    I feel like the issue is that I call pushMatrix() and popMatrix() on each instance of pic_map. Tried to remove that and just have one in test_set() and everything ran without lag. But all images were all flying all over the place.

  • The average size of the images are 7k.

    7 thousand what though? bytes, pixels?

    images are converted to pixels during loading, one byte per pixel. so file size doesn't really help us.

    calling push and pop matrix copies about a dozen numbers to a stack. displaying a resized image uses a lot of maps and copies a lot of pixels. that'll be your problem.

  • 7k bytes.

    Yes. Feels like I need to rotate them in another way!

  • the resizing is also expensive.

    can you use textures?

  • Never thought about that. Are they much less expensive?

  • image with 5 parameters is expensive:

     image(img[i], 0, 0, size+low, size+low);
    

    better use it with 3 parameters

     image(img[i], 0, 0); 
    

    and instead do a resize() in setup() which runs only once

    you could pre-caculate all image sizes you need in setup and store the images of the sizes in setup and just call these stored images

    frameRate()

    also you use frameRate(30); - get rid of this

  • Using textures will offload the rescaling work to the dedicated cores inside the GPU and will generally be a lot faster

  • It's working now! Made a version with textures but found an even easier solution. Just had to do it in P2D. So in fullScreen(P2D) everything is running amazing.

Sign In or Register to comment.