iphone - OpenGL ES - glDrawElements - 难以理解索引

标签 iphone objective-c xcode opengl-es indices

我想知道是否有人可以帮助我了解索引如何与 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);

最佳答案

索引数组中的每个值都同时指向位置、法线和纹理坐标。

它们仅以 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,
…
};

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

顶点位置:0.176567、0.143711、0.264963

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

顶点纹理坐标:0.867291, 0.359728

...

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

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

enter image description here

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

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

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

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

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

关于iphone - OpenGL ES - glDrawElements - 难以理解索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9275035/

相关文章:

iphone - 使用 iPhone SDK 4 GM 运行 cocos2d

iphone - 没有使用 ASIHTTPRequest 发送请求信息

ios - 以圆周运动绕一点移动物体

ios - 如果以模态方式呈现另一个 View ,则保持 AVSpeechSynthesizer 播放

iphone - UIView动画异常

iphone - 在 UIWebView 中打开的 HTML 页面中自动填充用户名和密码

objective-c - 在 Swift 中导入 Objective-c 框架?

iphone - 在 Cocoa Touch 环境中使用 AppKit 的等效 NSBox 是什么?

ios - 如何将 UIBarButtonItem 放在 Swift4 上的 NavigationController 的 ViewController 上?

Objective-C if 语句输入错误