OpenGLES2 iOS: как лучше всего передавать потоковую анимацию для динамической местности? - PullRequest
3 голосов
/ 02 апреля 2012

Я пишу приложение, которое создает динамический ландшафт 640 * 480 (меняет каждый кадр).Каждый ландшафт хранится в файле необработанных данных, который представляет собой строку значений (плавающих) высот.До сих пор я мог последовательно читать файлы в память и динамически создавать сетку на основе значений высоты каждого кадра (и частота кадров на самом деле разумна), но я максимально увеличился до 20 кадров, прежде чем мое приложение завершит работу без ошибок или стека.след.

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

Вот раздел из моего класса данных, который содержит коллекцию terrains:

- (void)addModelWithID:(int)modelID;
{
    NSString* resourcePath  = [[NSBundle mainBundle] resourcePath];
    NSString* fileName      = [NSString stringWithFormat:@"depth_%i.raw", modelID];
    NSString* fullPath = [resourcePath stringByAppendingPathComponent:fileName];

    NSData *myData = [NSData dataWithContentsOfFile:fullPath];
    if (!myData)
      return;

    const float *data = [myData bytes];

    int meshWidth               = 640;
    int meshHeight              = 480;

    Model *kModel = [[Model alloc] init];

    int indicesPtr  = 0;
    int depthPtr = 2;

    for (int y=0;y<meshHeight;y++)    // Loop through y pixels
        {
            for (int x=0;x<meshWidth;x++)   // Loop through x pixels
            {
                // Set up vertex positions
                int index  = y*meshWidth+x;
                float xpos = ((float)x/(float)(meshWidth-1)) - 0.5f;
                float ypos = ((float)y/(float)(meshHeight-1)) - 0.5f;
                float zpos = (float)data[index];

                kModel.vertices1[index*3+0] = xpos;
                kModel.vertices1[index*3+1] = ypos;
                kModel.vertices1[index*3+2] = zpos;

                // Create a new index based on whether the current line is even or odd (flipped horizontally if odd)
                int _index = (y%2==0) ? index : (y*meshWidth) + ((meshWidth-1)-x); 

                //Create the first index
                kModel.indices[indicesPtr++] = _index;

                // Create the second index
                if ((x<meshWidth-1) || (x==meshWidth-1 && y==meshHeight-2))
                    kModel.indices[indicesPtr++] = _index+meshWidth;
            }
        }
    }

    // Add the model to the data object
    [Models addObject:kModel];
    [kModel release];
}

И мой код рисования (каждый кадр, который я называю своей территорией, надеюсь, до 500 или около того, но я не превышаю ~ 20:

{
    ...
        Model *kModel = [kData.kinectModels objectAtIndex:sequenceCurrentFrame];

        glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)kModel.vertices1);

        glEnableVertexAttribArray(vertexHandle);

        glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE, (const GLfloat*)&modelViewProjection.data[0]);
        glDrawElements(GL_TRIANGLE_STRIP, kModel.numIndices, GL_UNSIGNED_SHORT, (const GLvoid*)kModel.indices);
    ...
}

Большое спасибо за вашу помощь,

Джош

1 Ответ

3 голосов
/ 02 апреля 2012

Вы можете сохранить данные о высоте в текстуре, а затем использовать функцию texture2D в вершинном шейдере для изменения текущей высоты вершины.

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

Если вы уверены, что привязаны к графическому процессору, формат текстуры, используемый для поиска данных о высоте, также может быть дополнительно оптимизирован.Скажем, ваша карта высот варьируется от 0-255, учитывая формат GL_RGBA, вы можете использовать одну и ту же текстуру для рендеринга до 4 кадров (первый кадр считывает высоту из красного компонента, следующий кадр из синего компонента и т. Д.).Сделав текстуру подложки в два раза больше (1280x960), вы сможете хранить до 16 кадров в одной текстуре.Еще одна вещь, о которой стоит упомянуть в отношении текстур, это то, что использование собственного формата для вашего GPU также может повысить производительность в обоих сценариях, связанных с GPU / IO.Для iDevices этот формат - PVRTC .

. Я действительно думаю, что проблема заключается только в выделении 300k + вершин для каждого кадра в отдельности ..., что в сумме составляет 640 * 480 * 3 * 4 = 3 686 400 байт выделил каждый кадр, и вы не упомянули, через сколько кадров вы прекращаете выделять память (подождите ... вы? ).Это слишком много для такой ограниченной ресурсной среды.

...