xcode OpenGL ES - glDrawElements - 无法理解索引

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9275035/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 23:18:29  来源:igfitidea点击:

OpenGL ES - glDrawElements - Trouble Understanding Indices

iphoneobjective-cxcodeopengl-esindices

提问by GuybrushThreepwood

I wonder if anyone can help me understand how indices work with glDrawElements. In the below example (taken from http://www.everita.com/lightwave-collada-and-opengles-on-the-iphone) the author mentions that you can only have one set of indices, in this case

我想知道是否有人可以帮助我了解索引如何与 glDrawElements 一起使用。在下面的例子中(取自http://www.everita.com/lightwave-collada-and-opengles-on-the-iphone)作者提到你只能有一组索引,在这种情况下

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

};

};

My question is what do these indices describe ? Am I right in thinking that the first three are the vertice positions, the second three are then the corresponding normals and the last three the texture co-ords ?

我的问题是这些指数描述了什么?我是否认为前三个是顶点位置,后三个是相应的法线,最后三个是纹理坐标?

Thanks in advance !

提前致谢 !

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

回答by Delta

Each and every value in the index array points at the same timefor a position, a normal and a texture coordinate.

每个与在索引阵列点的每一个值同时为一个位置,一个正常的和一个纹理坐标。

They are only organized in groups of 3 because they are simply discribing the vertices of a triangle, so 3 vertices = 1 triangle, of course.

它们仅以 3 个为一组进行组织,因为它们只是在描述三角形的顶点,因此当然 3 个顶点 = 1 个三角形。

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

So let's pick the first value of these indices, it's 0.

所以让我们选择这些索引的第一个值,它是0

This means:

这意味着:

Pick the vertex position number 0

选取顶点位置编号 0

Also, pick the vertex normal number 0

另外,选择顶点法线数 0

And pick the texture coordinates number 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,
…
};

So this information gets sent to the vertex shader:

所以这个信息被发送到顶点着色器:

VertexPosition: 0.176567, 0.143711, 0.264963

顶点位置:0.176567、0.143711、0.264963

VertexNormal: -0.425880, -0.327633, 0.350967

顶点法线:-0.425880、-0.327633、0.350967

VertexTextureCoordinates: 0.867291, 0.359728

顶点纹理坐标:0.867291、0.359728

...

...

If you do notuse indices, opengl will send those vertex data linearly, so after sending vertex data number 0, it would send the data at position 1 of the arrays, then 2, 3, 4 etc...

如果使用索引,opengl 将线性发送这些顶点数据,因此在发送顶点数据编号 0 后,它将在数组的位置 1 处发送数据,然后是 2、3、4 等...

That's good but sometimes your triangles end up with one or two identical vertices. Consider this:

这很好,但有时你的三角形最终会有一两个相同的顶点。考虑一下:

enter image description here

在此处输入图片说明

You can see 2 triangles forming a square, and they have 2 vertices in common, 0 and 2. So instead of having 6 vertices, being 3 for each triangle, we have only 4 and the 2 traingles use the same data for 2 of their vertices. That's good for performance, especially when you have big models with hundreds of triangles.

你可以看到 2 个三角形组成一个正方形,它们有 2 个共同的顶点,0 和 2。所以不是有 6 个顶点,每个三角形有 3 个,我们只有 4 个,并且 2 个三角形对它们的 2 个使用相同的数据顶点。这对性能有好处,尤其是当您拥有包含数百个三角形的大型模型时。

In order to draw the first triangle, we need the vertices number 0, 1 and 2 and for the second triangle we need the vertices number 0, 2 and 3.

为了绘制第一个三角形,我们需要顶点编号 0、1 和 2,而对于第二个三角形,我们需要顶点编号 0、2 和 3。

See, without an index array, opengl would try to use vertices 0, 1 and 2 (ok for the first triangle) but for the second triangle opengl would look for the vertices 3, 4 and 5. Which is wrong.

看,如果没有索引数组,opengl 会尝试使用顶点 0、1 和 2(对于第一个三角形可以),但是对于第二个三角形,opengl 会寻找顶点 3、4 和 5。这是错误的。

And that's why we create the index array, so opengl can send the right vertices for the vertex shader. In our case our index array would look like this:

这就是我们创建索引数组的原因,以便 opengl 可以为顶点着色器发送正确的顶点。在我们的例子中,我们的索引数组看起来像这样:

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

回答by haffax

The indices are meant in the sense of indices of elements in an array. Index 0 addresses the first element in an array, index 1 the second and so on.

索引是指数组中元素的索引。索引 0 寻址数组中的第一个元素,索引 1 寻址第二个元素,依此类推。

In your example the first indices 0, 1, 2 address the first three vertices, which have the positions of the first three Vertex3Ditems of array tigerBottomPositions, the normals of the first three elements of tigerBottomNormals(with 3 floats forming one normal vector) and same for texture coordinates.

在您的示例中,第一个索引 0, 1, 2 指向前三个顶点,它们具有Vertex3Darray的前三个项的位置,tigerBottomPositions前三个元素的法线tigerBottomNormals(3 个浮点数形成一个法线向量)和纹理相同坐标。

The first argument in the glDrawElementscall tells OpenGL how to form primitives from the indexed vertices. GL_TRIANGLESmeans every three indexed vertices form a triangle.

glDrawElements调用中的第一个参数告诉 OpenGL 如何从索引顶点形成图元。GL_TRIANGLES意味着每三个索引顶点形成一个三角形。

So vertices with indices 0, 1, 2 form a triangle, 3,0,4 form the next, 1,5,6 form another triangle and so on.

所以索引为 0、1、2 的顶点形成一个三角形,3、0、4 形成下一个,1、5、6 形成另一个三角形,依此类推。