Использование объектов буфера вершин (VBO) в OpenGL es (Iphone) для повышения производительности - PullRequest
5 голосов
/ 27 августа 2011

Я пишу простое приложение для iphone, которое отображает вращающийся куб. Я использую glDrawElements (openGl es), чтобы нарисовать треугольники куба и повернуть его. Я заметил, что когда я увеличиваю размер куба до 100 * 100 * 100 вокселей, производительность дисплея ухудшается (пояснение: я не рисую весь куб, я рисую только его контур (сетку). Я получаю все треугольники сетки, применяя алгоритм кубов к кубу ... в конце концов, я получаю что-то вроде треугольника 120 К для рисования представлены вершинами 40k) ...

Чтобы нарисовать куб, я держу массив вершин, массив цветов и массив индексов вершин. Массив indices определяет треугольники вершин, которые нужно нарисовать. Он передается в glDrawElements в качестве параметра.

Недавно я рассказал о другой технике рисования куба с использованием Vertex Buffer Objects (VBO). Я реализовал это, но производительность была еще хуже, чем в предыдущей технике

Вот мой код, Может быть, я сделал глупую ошибку, Любые предложения по улучшению будут хорошо приняты :)

кстати, я использовал следующие статьи в качестве ссылок:

http://playcontrol.net/ewing/jibberjabber/opengl_vertex_buffer_object.html http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-table-of.html

//all the 7 variables down are initialized by other function at the beginning 
GLushort* meshIndices;    //array of indices (ushort)
MeshVertex* meshVertices; //array of vertices (floats)
Color3D* meshColors;      //array of colors  (floats)

int numberOfTriangles; //number of Triangle to draw the cube
int numberOfVertices;  //number of all Vertices to draw the cube
int numberOfIndices;   //number of all Indices to draw the cube, each 3 indices define 3 vertices which define 1 triangle
int numberOfColors;    //number of colors used to draw the cube. each color is of tip Color3D

//in this function i initializing the VBOs 
- (void) setupMeshVBOs { 

    glGenBuffers(1, &triangleVBO);
    glBindBuffer(GL_ARRAY_BUFFER, triangleVBO);

    const GLsizeiptr vertex_size = numberOfVertices * sizeof(MeshVertex);
    const GLsizeiptr color_size = numberOfColors * sizeof(Color3D);

    glBufferData(GL_ARRAY_BUFFER, vertex_size + color_size, 0, GL_STATIC_DRAW);

    GLvoid* vbo_buffer = glMapBufferOES(GL_ARRAY_BUFFER, GL_WRITE_ONLY_OES); 
    memcpy(vbo_buffer, meshVertices, vertex_size);

    GLbyte* temp = (GLbyte*)vbo_buffer;
    temp += vertex_size;
    memcpy((GLvoid*)temp, meshColors, color_size);

    glUnmapBufferOES(GL_ARRAY_BUFFER); 

    glVertexPointer(3, GL_FLOAT, 0, (GLvoid*)((char*)NULL));

    glColorPointer(4, GL_FLOAT, 0, (GLvoid*)((char*)NULL+vertex_size));

    glGenBuffers(1, &triangleIBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangleIBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, numberOfIndices * sizeof(GLushort), meshIndices, GL_STATIC_DRAW);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

//this function is the one which draws the VBOs
- (void)drawView:(GLView*)view;
{

    static GLfloat rot = 0.0;


    glLoadIdentity();
    glTranslatef(-1.0f,-2.0f,-20.0f);
    glRotatef(rot,1.0f,1.0f,1.0f);
    glClearColor(0.7, 0.7, 0.7, 1.0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glBindBuffer(GL_ARRAY_BUFFER, triangleVBO);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, triangleIBO);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_COLOR_ARRAY);

        glDrawElements(GL_TRIANGLE_STRIP, numberOfIndices, GL_UNSIGNED_SHORT, (GLvoid*)((char*)NULL));

        glDisableClientState(GL_VERTEX_ARRAY);
        glDisableClientState(GL_COLOR_ARRAY);

    static NSTimeInterval lastDrawTime;
    if (lastDrawTime)
    {
        NSTimeInterval timeSinceLastDraw = [NSDate timeIntervalSinceReferenceDate] - lastDrawTime;
        rot+=50 * timeSinceLastDraw;                
    }
    lastDrawTime = [NSDate timeIntervalSinceReferenceDate];
}

1 Ответ

5 голосов
/ 27 августа 2011

Во-первых, чтобы нарисовать карту кубов размером 100x100x100, вам не следует рисовать каждый кубик отдельно.Если у вас есть, скажем, шесть коробок подряд, вы должны нарисовать их как один длинный кубоид для итогов двенадцати треугольников.Любой куб, который окружен с шести сторон, определенно не должен рассматриваться.Вам следует применять стратегии, подобные этим, чтобы значительно уменьшить количество геометрических элементов.

Совет Apple по оптимизации GL: здесь .Итоговая версия заключается в том, что вы должны стремиться использовать VBO с выровненными, чередующимися данными, используя наименьшие допустимые типы.Таким образом, неявное чтение данных является узким местом.Использование двух отдельных списков, вероятно, может вдвое снизить скорость ввода геометрии, а использование чисел с плавающей запятой, вероятно, приведет к дальнейшему замедлению.

...