2012-05-13 4 views
3

Я работаю над приложением iOS с симуляцией частиц песка. Вот видео альфа-версии, показывающее его логику http://www.youtube.com/watch?v=cYgw6jHx6QEFalling sand particle physic

Но у меня проблема с производительностью алгоритма частиц.

Теперь я делаю это следующим образом (приложение сделано на cocos2d, но это действительно не имеет значения):

каждые 0.03 секунды я получаю экран пиксельные данные с

glReadPixels(0,0,WindowSize.width,WindowSize.height,GL_RGBA,GL_UNSIGNED_BYTE,&ScreenBuffer); 

I также есть функция сравнения цвета пикселя с цветом фона

- (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); 
} 

определяю-структуру для частиц и иметь массив для них

struct SandParticle 
{ 
    CGPoint Position; 

    BOOL CMTop; 
    BOOL CMBottom; 
    BOOL CMLeft; 
    BOOL CMRight; 
}; 

struct SandParticle SandMatrix[5000]; 

int ParticlesCounter; 

Итак, моя логика следующая. Каждые 0,03 секунды я создаю новую частицу с помощью структуры SandParticle и добавляю ее в массив SandMatrix и увеличиваю ParticlesCounter. Затем я перебираю массив SandMatrix и для каждой частицы получаю фоновый цвет (используя метод GetColorAtPoint, упомянутый выше) в положениях Y-1 для нижней части, Y-1 X-1 для левой, Y-1 X + 1 для правой. Если цвет фона красный, то частицы могут опускаться, влево или вправо.

Полный код, который доступен здесь https://gist.github.com/8e6c4710950d17ed3d3c#L122 (не судите строго, это черновой вариант)

Основная проблема в том, что у меня есть частота кадров падает на IOS устройства (все нормально в симуляторе) для количества частиц более ± 800. Проблема заключается в итерационном цикле (UpdateParticles method). Но я не знаю, как я могу это сделать по-другому. Я могу здесь что-нибудь сделать?

ответ

1

Я не знаю точно, что такое алго, но обычно хорошие случайные генераторы довольно медленны; может быть, вы могли бы избежать этого вызова, делая это на этапе инициализации, заполняя массив и получить значение по индексу, как

 int Randomized = precomputed_arc4rand_unif2[CPLoop]; 

, предполагающее оптимизации в лучшем случае, я думаю, переставляя код не должен дать важные преимуществ в перспективе производительности, за исключением, может быть, вы можете проверить, следует ли продолжить до, копируя в CurrentParticle, и в общем вы могли бы избежать такой копии, если хотите более короткий способ ее написать, используйте определение или пройдите указатель (но, возможно, оптимизацию это также сохраняет), т.е.

 struct SandParticle *CurrentParticle = &SandMatrix[CPLoop]; 

, а затем вы d o CurrentParticle-> вместо CurrentParticle. и удалите окончательную «копию назад» CurrentParticle, которая не нужна.

Но я не знаю, улучшит ли производительность.

+0

, когда вы говорите, проблема там, я полагаю, вы профилировали код, конечно – ShinTakezou