ofThread Help

So I’m working with particle systems and ofThreading.

I have a hard time understanding how this works but I have something working. It is lame but working. The thread class has include to all the particle classes. I pass a number to set the particle system to be used.

This works here are some issues.
You need to make the thread sleep for a mill sec cause it runs so fast. This gets weird. in the thradFunction() I sleep for ofSleepMillis(30); But I get some flickering everery so offeten.

Is there a better way to do this? Can I use ofThread in the particle class itself? any help would be awesome.

Thanks,
T

Here is my thread Class:

  
#ifndef OF_PARTICLE_MANAGER  
#define OF_PARTICLE_MANAGER  
  
#include "ofMain.h"  
#include "ofThread.h"  
  
//All Particles  
#include "particleBubble.h"  
#include "Burst.h"  
  
  
class threadManager : public ofThread {  
  
	public:  
		  
		vector <Burst>				particles_0;  
		vector <particleBubble>		particles_1;  
		int index;  
		  
		//---------------------------------------------------------  
		threadManager() {  
		}  
		  
		//---------------------------------------------------------  
		//This is called in the setup  
		void setSystem(int _index) {  
			index = _index;  
		}  
		  
		//---------------------------------------------------------  
		void threadedFunction() {  
		  
			while(isThreadRunning() != 0) {  
				if(lock()) {  
					  
					//Tails  
					if(index == 0) {  
						for(int i=0; i<particles_0.size(); i++) {  
							particles_0[i].update(5,5,5);  
							particles_0[i].death();  
							if(particles_0[i].dead) particles_0.erase(particles_0.begin()+i);  
						}  
						  
						unlock();  
						ofSleepMillis(30);  
					}  
  
					//Bubbles  
					if(index == 1) {   
						for(int i=0; i<particles_1.size(); i++) {  
							particles_1[i].update();  
							particles_1[i].death();  
							if(particles_1[i].dead) particles_1.erase(particles_1.begin()+i);  
						}  
						  
						unlock();  
						ofSleepMillis(30);  
					}  
					  
				}  
			}  
			  
		}  
			  
		//--------------------------------------------------------- Add  
		void add(float x, float y) {  
			if(lock()) {  
				if(index == 0) particles_0.push_back(Burst(x, y, 0, 0, 0, 3));  
				if(index == 1) particles_1.push_back(particleBubble(x, y, 0, 0, 0, 3));  
				unlock();  
			}  
		}  
	  
		//--------------------------------------------------------- Draw  
		void draw() {  
			if(lock()) {  
			  
				//Tails  
				if(index == 0) {  
					for(int i=0; i<particles_0.size(); i++) {  
						particles_0[i].draw();  
					}  
				}  
				  
				//Bubbles  
				if(index == 1) {  
					for(int i=0; i<particles_1.size(); i++) {  
						particles_1[i].draw();  
					}  
				}  
				  
				  
				unlock();  
			}  
		}  
};  
#endif  

Hey Todd,

Could you explain what you are trying to do by having the particle manager threaded - or at least what you want to happen?

Regarding the flickering or any bugs you might be having - check this page about the recent fix to ofxThread which affects lock() and unlock()

http://forum.openframeworks.cc/t/addons-update—r9—fixes-for-ofxxmlsettings,-ofxthread/639/0

Theo

one important about threading to note is that opengl is not multithread capable, meaning you can’t do any opengl commands (or OF commands that work with opengl) in a separate thread then the main app.

I’ve wasted hours of my life learning this lesson :slight_smile: – (for example, allocating a texture in a thread but it not existing, etc…). it’s super important to know that any drawing / opengl related code must be done in the main thread (testApp::update(), testApp::draw(), etc).

hope that helps!
zach

Im trying to have a particle system be updated and rendered on its on thread.

In this example I made the ofThread example just add particles to a vector as you move the mouse around. It was fast there are about 16k particles with 8 threads all running.

The opengl rendering was called in the thread class. But that function was called in the main app draw()

void testapp::draw() {
thread_1.draw();
thread_2.draw();
thread_3.draw();
. …
}

I want to make a new class that has its own particle system and is using its own thread to update and call the gl rendering. I thought that this would speed it up and allow for tons of particles. I may be totally wrong.

not sure how to do this maybe:
vitural void updateParticles(…)

Ahh okay.

The only part of ofxThread that is actually threaded is the threadedFunction (and whatever functions it calls). So you won’t have any problems with openGL as long as you don’t try and draw within threadedFunction.

As zach mentioned it is not possible to render in a separate thread than the main app due to the way openGL is designed.

Doing all the expensive calculations in separate threads and then drawing them in the main thread could still give you quite a big performance boost - as you are currently seeing!

It looks like you have the lock and unlock stuff working right.

The reason you are having to make the threadedFunction sleep for a bit is that otherwise it will not give a chance for any of your other function to call lock();

I should also probably explain there are two ways which lock() can work.
Note:Important that you get the patch for ofxThread which fixes the behavior of lock - http://forum.openframeworks.cc/t/addons-update—r9—fixes-for-ofxxmlsettings,-ofxthread/639/0

If startThread is called with blocking set to true then lock will block the app until the other thread has called unlock. This means that you know that the code between lock and unlock will get executed as soon as the existing lock (from the other thread) is unlocked. - Quite a mouthful!

If startThread is called with blocking set to false, calling lock(); when it is already locked by the other thread will return immediately with false. This is why we check the result of lock with

  
if(lock){  
   //do some stuff here  
  unlock();  
}  
  

As it works for both blocking and non-blocking mode.

In your case blocking mode is more ideal. Non-blocking and trying to draw will result in occasionally nothing being drawn (which would explain the flashes).

Anyway please get the patch of ofxThread as it is very directly related to your issue (the fix corrects blocking behaving like non-blocking on macs).

I would also suggest playing around with the amount of time you have the threadedFunction sleep.

this is slightly unrelated, but the way your code is written you’d be better off speed-wise going with a linked list, (or a std::list) than a vector.

linked lists are a bunch faster than vectors if you’re doing a lot of deleting elements from the middle or start and aren’t doing random access.

ohh man this sounds great! I’m going to try the updated threading with simple particle systems. Ill post the code. Thanks everyone!