2012-02-14 78 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