2012-02-14 18 views
6

Mi chiedo se qualcuno possa aiutarmi a capire come funzionano gli indici con glDrawElements. Nell'esempio che segue (tratto da http://www.everita.com/lightwave-collada-and-opengles-on-the-iphone) l'autore menziona che si può avere solo una serie di indici, in questo casoOpenGL ES - glDrawElements - Problema Comprensione degli indici

const GLushort tigerBottomIndices[] = { 
0,1,2, 
3,0,4, 
1,5,6, 
… 

};

La mia domanda è che cosa descrivono questi indici? Ho ragione nel pensare che le prime tre sono le posizioni dei vertici, le seconde tre sono le normali corrispondenti e le ultime tre le co-orditure?

Grazie in anticipo!

#import "OpenGLCommon.h" 

const Vertex3D tigerBottomPositions[] = { 
{0.176567, 0.143711, 0.264963}, 
{0.176567, 0.137939, 0.177312}, 
{0.198811, 0.135518, 0.179324}, 
… 
}; 
const Vertex3D tigerBottomNormals[] = { 
{-0.425880, -0.327633, 0.350967}, 
{-0.480159, -0.592888, 0.042138}, 
{-0.113803, -0.991356, 0.065283}, 
… 
}; 
const GLfloat tigerBottomTextureCoords[] = { 
0.867291, 0.359728, 
0.779855, 0.359494, 
0.781798, 0.337223, 
… 
}; 
const GLushort tigerBottomIndices[] = { 
0,1,2, 
3,0,4, 
1,5,6, 
… 
}; 

glEnableClientState(GL_VERTEX_ARRAY); 
glEnableClientState(GL_NORMAL_ARRAY); 
glEnableClientState(GL_TEXTURE_COORD_ARRAY);  

glBindTexture(GL_TEXTURE_2D, tigerTextures[5]); 
glVertexPointer(3, GL_FLOAT, 0, tigerBottomPositions); 
glNormalPointer(GL_FLOAT, 0, tigerBottomNormals); 
glTexCoordPointer(2, GL_FLOAT, 0, tigerBottomTextureCoords); 
glDrawElements(GL_TRIANGLES, 210, GL_UNSIGNED_SHORT, tigerBottomIndices); 

glDisableClientState(GL_VERTEX_ARRAY); 
glDisableClientState(GL_NORMAL_ARRAY); 
glDisableEnableClientState(GL_TEXTURE_COORD_ARRAY); 

risposta

26

Ogni valore nell'array indice punta allo allo stesso tempo per una posizione, una coordinata normale e una trama.

Sono organizzati solo in gruppi di 3 perché stanno semplicemente scrivendo i vertici di un triangolo, quindi 3 vertici = 1 triangolo, ovviamente.

const GLushort tigerBottomIndices[] = { 
0,1,2, // #1 Triangle 
3,0,4, // #2 Triangle 
1,5,6, // #3 Triangle 
… 

Quindi cerchiamo di raccogliere il primo valore di questi indici, è .

Ciò significa:

scegliere il numero di posizione del vertice 0

Inoltre, raccogliere il vertice normale numero 0

e scegliere la texture coordinate numero 0

const Vertex3D tigerBottomPositions[] = { 
{0.176567, 0.143711, 0.264963}, // This is the position number 0 
{0.176567, 0.137939, 0.177312}, 
{0.198811, 0.135518, 0.179324}, 
… 
}; 
const Vertex3D tigerBottomNormals[] = { 
{-0.425880, -0.327633, 0.350967}, // This is the normal number 0 
{-0.480159, -0.592888, 0.042138}, 
{-0.113803, -0.991356, 0.065283}, 
… 
}; 
const GLfloat tigerBottomTextureCoords[] = { 
0.867291, 0.359728, // These are the tex-coords number 0 
0.779855, 0.359494, 
0.781798, 0.337223, 
… 
}; 

Quindi queste informazioni viene inviato al vertex shader:

VertexPosition: 0,176,567 mila, 0,143,711 mila, 0,264963

VertexNormal: -,425880, -0,327633, 0,350967

VertexTextureCoordinates: 0,867,291 mila, 0,359728

...

Se fate non indici uso, opengl invierà quelli dati vertex linearmente, così dopo l'invio dei dati vertice numero 0, sarebbe inviare i dati alla posizione 1 degli array, poi 2, 3, 4, ecc ..

Va bene, ma a volte i triangoli finiscono con uno o due vertici identici. Considerate questo:

enter image description here

Si può vedere 2 triangoli formano un quadrato, e hanno 2 vertici in comune, 0 e 2. Quindi, invece di avere 6 vertici, essendo 3 per ogni triangolo, abbiamo solo 4 e i 2 traingles usano gli stessi dati per 2 dei loro vertici. Ciò è positivo per le prestazioni, specialmente quando si hanno modelli grandi con centinaia di triangoli.

Per elaborare il primo triangolo, abbiamo bisogno del vertici numero 0, 1 e 2 e per il secondo triangolo dobbiamo vertici numero 0, 2 e 3.

See, senza un array di indici, opengl proverei ad usare i vertici 0, 1 e 2 (ok per il primo triangolo) ma per il secondo triangolo opengl cercherebbe i vertici 3, 4 e 5. Che è sbagliato.

Ed è per questo che creiamo l'array di indice, così opengl può inviare i vertici giusti per il vertex shader. Nel nostro caso il nostro array di indici sarebbe il seguente:

const GLushort tigerBottomIndices[] = { 
0,1,2, 
0,2,3, 
} 
+3

Grazie - esattamente la chiara spiegazione di cui avevo bisogno. – GuybrushThreepwood

+0

Una delle migliori spiegazioni che ho visto. Thx –

+0

Grande spiegazione – dbryson

1

Gli indici sono intesi nel senso di indici di elementi in un array. L'indice 0 indirizza il primo elemento di un array, indice 1 il secondo e così via.

Nel tuo esempio i primi indici 0, 1, 2 indirizzo i primi tre vertici, che hanno le posizioni dei primi tre Vertex3D elementi di matrice tigerBottomPositions, i normali dei primi tre elementi di tigerBottomNormals (con 3 galleggianti formando uno vettore normale) e lo stesso per le coordinate della trama.

Il primo argomento nella chiamata glDrawElements indica a OpenGL come formare le primitive dai vertici indicizzati. GL_TRIANGLES significa che ogni tre vertici indicizzati formano un triangolo.

Quindi i vertici con indici 0, 1, 2 formano un triangolo, 3,0,4 formano il successivo, 1,5,6 formano un altro triangolo e così via.

+0

Grazie haffax, ma sono ancora confuso. Quindi nei primi indici (0,1,2) questo descrive solo le informazioni vertice, o anche le informazioni normali e le informazioni sulla trama? – GuybrushThreepwood

+0

Tutti e tre gli attributi del vertice: Posizione, Normale, TexCoord. Con le funzioni glXxxPointer si definisce l'inizio degli array per ciascun attributo. Gli indici contano da questo inizio. – haffax