我想知道是否有人可以帮助我理解指数如何与glDrawElements一起使用。在下面的例子中(摘自http://www.everita.com/lightwave-collada-and-opengles-on-the-iphone),作者提到你只能有一组索引,在这种情况下
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);
答案 0 :(得分: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
选择纹理坐标编号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.1743711,0.264963
VertexNormal:-0.425880,-0.327633,0.350967
VertexTextureCoordinates:0.867291,0.359728
...
如果你不使用索引,opengl会线性发送这些顶点数据,所以在发送顶点数据0后,它会在数组的第1位发送数据,然后是2,3, 4等...
这很好但有时你的三角形最终会有一个或两个相同的顶点。考虑一下:
你可以看到2个三角形形成一个正方形,它们有两个共同的顶点,0和2.所以我们只有4个而2个traingles使用相同的数据,而不是6个顶点,每个三角形为3个。 2个顶点。这对性能有好处,特别是当您拥有包含数百个三角形的大型模型时。
为了绘制第一个三角形,我们需要顶点编号0,1和2,而对于第二个三角形,我们需要顶点编号0,2和3。
请注意,如果没有索引数组,opengl会尝试使用顶点0,1和2(第一个三角形可以)但是对于第二个三角形,opengl会查找顶点3,4和5.这是错误的。< / p>
这就是我们创建索引数组的原因,因此opengl可以为顶点着色器发送正确的顶点。在我们的例子中,我们的索引数组如下所示:
const GLushort tigerBottomIndices[] = {
0,1,2,
0,2,3,
}
答案 1 :(得分:1)
索引是指数组中元素索引的意义。索引0表示数组中的第一个元素,索引1表示第二个元素,依此类推。
在您的示例中,第一个索引0,1,2对前三个顶点进行寻址,这三个顶点具有数组Vertex3D
的前三个tigerBottomPositions
项的位置,前三个元素的法线tigerBottomNormals
(3个浮点数形成一个法线向量)和纹理坐标相同。
glDrawElements
调用中的第一个参数告诉OpenGL如何从索引顶点形成基元。 GL_TRIANGLES
表示每三个索引顶点形成一个三角形。
因此,带有索引0,1,2的顶点形成一个三角形,3,0,4形成下一个,1,5,6形成另一个三角形,依此类推。