Pixels buffer and framerate


#1

Dear Team,
When using pixels array i experience framerate drop (20 fps) after 4 or 5 draw() loops.
when i use a void keypressed() the framerate doesnt drop and stays above 55 fps.
(of course i require to press a key which in the final code will not occur).

Is there a way to keep the framerate high by (delete stored buffer perhaps)?

I included a mockup to illustrate the issue


int value = 0;
PVector  v1 = new PVector(1000, 750, 0);
PVector  v2 = new PVector(60, 80, 0); 

void setup(){
 size(1500,900,P2D); 
 //smooth(4);
}

void draw(){
    //background(0);                  //DIRECTLY IN DRAW    FRAMERATE DROPS TOWARDS 20 FPS AFTER A FEW ITERATIONS
    // loadPixels();
    //      for (int i = 0; i < (width*height)-width; i++)  {
    //          float f= map(i,  0,  ((width*height)-width),  0,  255);
    //          float d = v1.dist(v2);
    //          v2.x= f;
    //          v2.y= f;
    //          v1.x= mouseX;
    //          v1.y= mouseY;
    //          pixels[i] = color(f, d/5, 50);
    // }
    // updatePixels();
    // fill(0);
    // textSize(34);
    // text(frameRate,0,height-100); 
}




void keyPressed(){
  if (value == 0) {                       // FRAMERATE STAYS ABOVE 55 FPS  
     background(0);
     loadPixels();
          for (int i = 0; i < (width*height)-width; i++)  {
              float f= map(i,  0,  ((width*height)-width),  0,  255);
              float d = v1.dist(v2);
              v2.x= f;
              v2.y= f;
              v1.x= mouseX;
              v1.y= mouseY;
              pixels[i] = color(f, d/5, 50);
            
     }

     updatePixels();
     fill(0);
     textSize(34);
     text(frameRate,0,height-100); 
     
  } else{  value= 0;}
  
  
}

#2

Hi, I have no problem with low frame rate on my computer.


#3

Hi JB4X,
thank you for taking time.
currently its in the keypressed () option, when putting comments off in draw() section , it will drop


#4

I think the difference is that in draw() it happens every frame, but in keyPressed() it happens only once when you press the key and it won’t affect the frame rate that much if one frame where the calculation happens takes longer.

It looks like each row of the pixels has almost the same color. What you can do is instead of looping over every pixel, loop over each row, calculate the color for the row, and then set all the pixels in the row to that color. This will be much faster, because calculating distance and color for each pixel is a lot of work even for a computer.


#5

I understood the issue so I tried with the code in draw, not the one in keyPressed.


#6

Jakub,
Happy to know I am not overlooking methods that could potentially speedup the process.
I will take into account the looping method wherever applicable to the real project.

thank you so much


#7

It has definetly to do with you window size. 1500*900 in a loop is a lot. Thats 1.35m and that just doesn‘t go in draw. A loop (on my System at least) of 1m does take around 0.3s. So if your framerate is 60/s it delays one Second to a total of 18 seconds each Second, and that causes problems. Either divide the loop to get it to be stabile, or change the size, or the frameRate.


#8

Lexyth,
Good to know what causes it, sounds logical. Whilst trying I recalled a PGraphics method that people sometimes use.
it manages to increase the framerates by a factor two ( from 20 to 40) using PGraphics.

PGraphics pg;
int value = 0;
PVector  v1 = new PVector(1000, 750, 0);
PVector  v2 = new PVector(60, 80, 0); 

void setup(){
 size(1500,900,P2D); 
 pg = createGraphics(1500, 900);
 //smooth(4);
}

void draw(){
    background(0);                  //DIRECTLY IN DRAW    FRAMERATE DROPS TOWARDS 20 FPS AFTER A FEW ITERATIONS
     
     pg.beginDraw();
     pg.loadPixels();
          for (int i = 0; i < (width*height)-width; i++)  {
              float f= map(i,  0,  ((width*height)-width),  0,  255);
              float d = v1.dist(v2);
              v2.x= f;
              v2.y= f;
              v1.x= mouseX;
              v1.y= mouseY;
              pg.pixels[i] = color(f, d/5, 50);
     }
     pg.updatePixels();
     pg.fill(0);
     pg.textSize(34);
     pg.text(frameRate,0,height-100); 
     pg.endDraw();
     image(pg,0,0);
}


#9

Nice find!

To clarify, this is because the PGraphics you created uses default renderer (Java2D) instead of OpenGL renderer (P2D or P3D). Java2D is faster for loadPixels() and updatePixels(), because all the pixels are in RAM. P2D and P3D need to transfer the pixels from the GPU memory to RAM and then upload them back, which is a bit slower.

You can achieve the same or even larger speedup in your original sketch by changing the renderer for the whole sketch:

size(1500,900); // using default renderer (Java2D)

#10

Jakub,

I am very happy to know the explanation behind it as it is murky at times to know why things work (and why not).
much apreciated with the shared thoughts.


#11

Just another Suggestion. If you don‘t Need the image be updated 60 Times a second, you could just envelop the draw in (by draw i mean only the things that draw to the canvas):

if(frameCount % 2 = 0) {
  //code in draw
}

This way it only draws the pixels half the time, But you can keep the Rest of your code outside, to let calculations still go at 60. Also, this way you don‘t use as much power just to draw an image 60 Times a Second, which is pretty much if you don‘t really Need it that fast.


#12

a welcomed remark Lexyth