2011-08-27 13 views
5

Sto scrivendo una semplice applicazione per iPhone che visualizza un cubo rotante. Sto usando glDrawElements (openGl es) per disegnare i triangoli del cubo e ruotarlo. Ho notato che quando aumento la dimensione del cubo a 100 * 100 * 100 voxel le prestazioni dello schermo si mettono male (chiarimento: non disegno l'intero cubo, disegno solo il suo contorno (mesh). Ottengo tutti i triangoli della mesh applicando l'algoritmo dei cubi in marcia sul cubo ... alla fine ottengo qualcosa come il triangolo 120k per disegnare che sono rappresentati da 40k vertici) ...Utilizzo di VBO (Vertex Buffer Objects) in OpenGL es (Iphone) per migliorare le prestazioni

Per disegnare il cubo tengo un array di vertici, array di colori e una matrice se indici ai vertici. L'array di indici definisce i triangoli dei vertici da disegnare. È passato a glDrawElements come parametro.

Recentemente ho rosso su una tecnica diversa per disegnare il cubo utilizzando Vertex Buffer Objects (VBO). Ho implementato, ma la prestazione è stata Anche worser poi con la tecnica precedente

Ecco il mio codice, Forse ho fatto un errore stupido, eventuali proposte di miglioramento saranno ben accolti :)

tra l'altro, ho usato i seguenti articoli come riferimenti:

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]; 
} 
+2

Prima di tutto, si dice che a 100^3 voxel la performance peggiora. Non è affatto una sorpresa, dal momento che ciò equivale a 1 milione di voxel. Suppongo che ogni voxel sia un cubo, composto da 12 triangoli. Sarebbero 12 milioni di triangoli per chiamata di rendering. Questo è molto*. Si noti inoltre che i VBO * potrebbero * essere più efficienti quando i dati dei vertici e dei colori sono intercalati. Tuttavia, come per l'iPhone (PowerVR), non so se questo è il caso. – Arne

+0

sì, non mi sono spiegato bene, ho modificato la domanda di conseguenza. Il cubo è 100 * 100 * 100 ma non disegno l'intero cubo, disegno solo il suo contorno (mesh). Ottengo tutti i triangoli della mesh applicando l'algoritmo di cubi marching sul cubo ... alla fine ottengo qualcosa come 120k triangle per disegnare che sono rappresentati da 40k vertici ... – alexpov

risposta

5

In primo luogo, per disegnare una mappa di cubi 100x100x100, non si deve disegnare ogni cubo singolarmente. Se hai, per esempio, sei scatole di fila, dovresti disegnarle come un cubo lungo per dodici triangoli in totale. Nessun cubo circondato da sei lati non ha assolutamente bisogno di essere considerato. Dovresti applicare strategie come quelle per ridurre significativamente il numero di geometrie.

I consigli di Apple sull'ottimizzazione GL sono here. La versione di riepilogo è che dovresti mirare a utilizzare i VBO con dati allineati e interlacciati, usando i tipi accettabili più piccoli. Quindi, implicitamente, la lettura dei dati è un collo di bottiglia. L'utilizzo di due elenchi separati potrebbe teoricamente dimezzare la velocità di input della geometria e l'utilizzo di float probabilmente rallenterà ulteriormente.

+0

ciao, ho redato la documentazione che hai suggerito e contiene tutte le risposte, ... grazie :) – alexpov

Problemi correlati