2012-02-14 89 views
6

我想知道有沒有人能幫我理解索引如何處理glDrawElements。在下面的例子中(從http://www.everita.com/lightwave-collada-and-opengles-on-the-iphone取)作者提到,你只能有一個索引集,在這種情況下OpenGL ES - glDrawElements - 故障理解索引

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

};

我的問題是這些指數描述的是什麼?我是否認爲前三個是頂點位置,後三個是相應的法線,最後三個是紋理合成?

在此先感謝!

#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); 

回答

26

對於位置,法線和紋理座標,索引數組中的每個值都指向同一時間

它們只組成3個組,因爲它們只是描述三角形的頂點,所以當然3個頂點= 1個三角形。

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

所以讓我們挑選這些指標的第一個值,它是。

這意味着:

選擇頂點位置數0

另外,挑頂點正常數0

,並挑選紋理座標數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, 
… 
}; 

所以這個信息被髮送到頂點着色器:

VertexPosition:0.176567,0.143711,0.264963

VertexNormal:-0.425880,-0.327633,0.350967

VertexTextureCoordinates:0.867291,0.359728

...

如果你不使用指數,OpenGL的將線性發送這些頂點數據,所以發送頂點數據號0之後,它將在陣列的1位發送數據,然後2,3,4等。

這很好,但有時候你的三角形最終會有一個或兩個相同的頂點。試想一下:

enter image description here

你可以看到2個三角形形成一個正方形,他們有2個頂點共同點,0和2。因此,而不是具有6個頂點,每個三角形爲3,我們只有4 2個traingles爲它們的2個頂點使用相同的數據。這對性能很有好處,特別是當你有幾百個三角形的大型模型時。

爲了繪製第一個三角形,我們需要的頂點編號爲0,1和2以及對所述第二三角形我們需要的頂點編號0,2和3

見,沒有索引陣列,OpenGL的會嘗試使用頂點0,1和2(對於第一個三角形是ok),但對於第二個三角形,opengl會查找頂點3,4和5.哪個是錯誤的。

這就是爲什麼我們創建索引數組,所以opengl可以發送頂點着色器的右頂點。在我們的例子中,我們的索引數組看起來像這樣:

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

謝謝 - 我需要的確切解釋。 – GuybrushThreepwood 2012-02-14 16:08:43

+0

我見過的最好的解釋之一。 Thx – 2012-06-12 21:42:48

+0

很好的解釋 – dbryson 2012-10-11 00:35:48

1

索引是指數組中元素的索引。索引0指向數組中的第一個元素,索引1指向第二個元素,依此類推。

在您的實例中,第一索引0,1,2個地址的前三個頂點,其具有前三個Vertex3D項目陣列tigerBottomPositions的的位置,tigerBottomNormals(3浮子形成一個的前三個元件的法線法線向量),紋理座標相同。

glDrawElements調用中的第一個參數告訴OpenGL如何從索引頂點形成圖元。 GL_TRIANGLES意味着每三個索引頂點形成一個三角形。

因此,索引爲0,1,2的頂點構成一個三角形,3,0,4構成另一個三角形,1,5,6構成另一個三角形,依此類推。

+0

感謝haffax,但我仍然感到困惑。因此,在第一個索引(0,1,2)中,這是隻描述頂點信息還是正常和紋理協調信息? – GuybrushThreepwood 2012-02-14 14:35:40

+0

所有三個頂點屬性:位置,正常,TexCoord。使用glXxxPointer函數,可以爲每個屬性定義數組的開始。指數從這個開始算起。 – haffax 2012-02-14 15:36:26