Low Framerates with 2D graphics

I’m essentially a beginner and have made something that I like the results of, but am looking for a way I can get better than 1 frame per second. Could someone point me in the right direction? Code is here: GitHub - ideocentric/soft-particles: OpenFrameworks soft particles from video.. Any help would be appreciated.

do you know how many particles you are using? if they are always increasing?

Hey @ideocentric , dimitre’s suggestion is great! Particles can accumulate quickly and the vector that contains them can get really big. One way to manage this is to allocate a vector with a certain size, and just replace dead particles with new ones rather than calling .erase() and .push_back() in camrain::draw().

Each particle has its own ofImage that it loads when it’s created by the constructor. So potentially lots of images are getting loaded each cycle as new particles are created. But it looks like it’s the same image for every particle. So, you could instead have 1 image that belongs to the camrain class, and .draw() that one instead. Maybe post back if this idea is confusing or you need some help with how to set it up. Essentially, you could do something like this:

// in particle.hpp:
// remove ofImage dot from the class, and declare a .draw() that takes an ofImage& as an argument
void draw(ofImage& dot);

// in particle.cpp
void particle::draw(ofImage& dot){
    // now dot is supplied by an argument; this function remains as it was written
}

// in camrain.hpp
ofImage dot;

// in camrain.cpp
    for(vector<particle>::iterator it = particles.begin(); it != particles.end();++it) {
        (*it).draw(dot);
    }

ofImage& is a reference to an ofImage. Passing larger objects (like an ofImage) by reference can be much faster because they don’t have to be copied before they get passed to the function.

camrain::draw() draws the particles as well as manages the vector. It is called in ofApp::draw(). It might be helpful to move the “managing the vector” part into something that happens in ofApp::update().

Hope this helps and post back if you need more help!

Thanks for the feedback…

I originally had the cleanup in the update section, but it performed faster in the draw when I moved it…

I’ll try a single image by reference.

Hey sure and let us know how it goes! I’m thinking that calling ofImage::load() when new particles are created is causing the slowdown. So finding a different approach to that should speed things up a bunch. Accessing the file system is (comparatively) very slow, along with memory allocations (creating a new ofImage, ofFbo, etc).

Each particle can have its own unique image too. But there are some different ways to create and recycle them without calling .load() for new ones every cycle.

Thanks all for the feedback. I took a slightly different approach by adding the image as a static variable rather than passing to each of the functions, but essentially the same effect. This increased performance considerably. I made some additional changes that will require further optimization, but if you want to see where I landed you can view the project here:

1 Like

Hi @ideocentric,

I saw this in the Readme,
The cleaning process causes considerable slow downs.

The above code could be replaced by ofRemove and it might speed up this process instead of a loop. Add a function to check if the item should be removed. It can be added in cameraParticles.cpp. Something like

bool shouldRemove( imageParticle& p ) {
    return p.dead;
}
void cameraParticles::update() {
    // other update code
    ofRemove(particles, shouldRemove);
}
1 Like