Reputation: 305
I'm working on iOS app with sand particles simulation. Here is a video of alpha version showing the logic of it http://www.youtube.com/watch?v=cYgw6jHx6QE
But I have a problem with particle algorithm performance.
Now I'm doing it in the following way (app is made on cocos2d, but it does not really matter):
Every 0.03 seconds I get screen pixel data with
glReadPixels(0,0,WindowSize.width,WindowSize.height,GL_RGBA,GL_UNSIGNED_BYTE,&ScreenBuffer);
I also have a function to compare pixel color with background color
- (BOOL) GetColorAtPoint: (int) GetX : (int)GetY
{
int YSize = (int)WindowSize.width*4;
Byte R = ScreenBuffer[(YSize*GetY) + 0 + (4 * GetX)];
Byte G = ScreenBuffer[(YSize*GetY) + 1 + (4 * GetX)];
Byte B = ScreenBuffer[(YSize*GetY) + 2 + (4 * GetX)];
Byte A = ScreenBuffer[(YSize*GetY) + 3 + (4 * GetX)];
return (R==255 && G == 0 && B == 0 && A == 255);
}
I define struct for particles and have array for them
struct SandParticle
{
CGPoint Position;
BOOL CMTop;
BOOL CMBottom;
BOOL CMLeft;
BOOL CMRight;
};
struct SandParticle SandMatrix[5000];
int ParticlesCounter;
So, my logic is following. Every 0.03 seconds I create new particle with SandParticle struct and add it to the SandMatrix array and increase ParticlesCounter. Then I iterate over SandMatrix array and for each particle I get background color (using GetColorAtPoint method mentioned above) on positions Y-1 for bottom, Y-1 X-1 for left, Y-1 X+1 for right. If background color is red, then particle can go down, left or right.
Full code for that is available here https://gist.github.com/8e6c4710950d17ed3d3c#L122 (do not judge strictly, it is a draft version)
The main problem is, that I have frame-rate drops on iOS device (everything is ok in Simulator) for particles quantity over ±800. The problem is an iteration cycle (UpdateParticles method). But I don't have any idea how I can make it in another way. Is there anything I can do here?
Upvotes: 3
Views: 1630
Reputation: 9661
I don't know exactly the algo, but usually good random generators are rather slow; maybe you could avoid that call, doing it at the initialization phase, filling an array and getting the value by index like
int Randomized = precomputed_arc4rand_unif2[CPLoop];
Supposing optimizations are at their best, I think rearranging code shouldn't give important benefits in term of performance, except maybe you can check if to continue before copying into CurrentParticle, and in general you could avoid such a copy, if you want a shorter way to write it, use a define or go through a pointer (but maybe optimization saves this too), i.e.
struct SandParticle *CurrentParticle = &SandMatrix[CPLoop];
and then you do CurrentParticle->
instead of CurrentParticle.
and delete the final "copy-back" of CurrentParticle, which is not needed.
But I don't know if it would make the performance so much better.
Upvotes: 1