templates - xcode 4.2 中的 OpenGL 游戏模板(这段代码发生了什么?!!)

标签 templates opengl-es-2.0

您好,我已尝试尽可能多地了解这部分代码中发生了什么,但我没有任何运气。

glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

glBindVertexArrayOES(0);

这属于在xcode 4.2上创建OpenGL游戏的模板。但是,我完全感到困惑,如果有人可以向我解释,我会很高兴。

首先,如何在不添加任何内容的情况下生成和绑定(bind) _vertexArray?

其次,如果 gCubeVertexData 是一个 216 的数组,具有以下内容:
GLfloat gCubeVertexData[216] = 
{
    // Data layout for each line below is:
    // positionX, positionY, positionZ,     normalX, normalY, normalZ,
    0.5f, -0.5f, -0.5f,        1.0f, 0.0f, 0.0f,
    0.5f, 0.5f, -0.5f,         1.0f, 0.0f, 0.0f,

我想我会为以下命令处理这个数组,在该命令中我启用了 GLK 属性,这就是我使用指针的目的(仍然使用 prev 绑定(bind)的)。但是,如果我没记错的话,语法是(设置的属性、顶点的大小、类型、错误、结构的大小(我认为不是 24),以及与数据的偏移量(12 来自哪里?!))

最后一个问题,为什么我现在将 0 绑定(bind)到顶点数组?

编辑:老实说,我确实尝试在各个站点上研究opengl,但我只能遇到理论而不是实践。这就是我问这个问题的原因。

最佳答案

好的,一步一步来:

glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

这将绑定(bind)并生成一个顶点数组对象 (VAO)。现在,VAO 不包含任何数据。它只包含与顶点数组/属性相关的所有状态,例如启用的属性或使用 glVertexAttribPointer 进行的设置.
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);

这现在创建并绑定(bind)了一个顶点缓冲区对象 (VBO),它本质上是一个由 OpenGL 管理的普通数据缓冲区,并将顶点数据复制到其中。

让我们看看这个数据:
GLfloat gCubeVertexData[216] = 
{
    // Data layout for each line below is:
    // positionX, positionY, positionZ,     normalX, normalY, normalZ,
    0.5f, -0.5f, -0.5f,        1.0f, 0.0f, 0.0f,

您的数据被布置为一堆浮点数(每个 32 位/4 字节),每六个值代表一个顶点,该顶点又由一个位置(3 个浮点数)和一个法线(3 个浮点数)组成。
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));

这指定第一个属性(位置)每个顶点包含 3 个浮点值,每个顶点之间的步长为 24 个字节。这意味着从一个顶点的属性值(在这种情况下为位置)的开始到下一个顶点的属性数据的开始有 24 个字节。实际上 24 字节是 6 个浮点数的大小,因此也是我们顶点数据中单个顶点数据的大小,所以这完全符合。最后一个参数表示位置数据从当前绑定(bind)的 VBO(包含我们的顶点数据)的开头开始,因为它是我们的顶点数据中的第一个属性。
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));

这指定第二个属性(正常)每个顶点包含 3 个浮点值,同样步长为 24 字节,就像从相同数据中获取它一样。因此,从一个正常到下一个,它也是 24 个字节(6 个浮点数)。现在最后一个参数表示普通数据在当前绑定(bind)的 VBO(包含我们的顶点数据)开始后 12 个字节(3 个浮点数)开始。这是必要的,因为法线是我们顶点数据中的第二个属性,所以我们需要“跳过”前三个值(即位置)才能得到法线数据。如果我们再次使用 0,我们将采用与位置相同的数据。
glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribNormal);

这些最终启用了渲染属性。
glBindVertexArrayOES(0);

所以这现在绑定(bind)了默认(无)VAO,因为我们已经完成了指定它。我猜这整个代码片段是一些初始化例程的一部分。所以现在每当我们以后想要渲染我们的顶点数据时,可能使用 glDrawArrays ,我们只需要使用glBindVertexArray绑定(bind)VAO在调用 glEnableVertexAttribArray 绘制方法和每个顶点数组状态之前或 glVertexAttribPointer获取上次绑定(bind) VAO 时设置的值,就像在我们的初始化例程中一样。如果您不使用 VAO,则必须调用 glBindBuffer和两个 glEnableVetrexAttribArrayglVertexAttribPointer每次要绘制此顶点数据时调用。

但是所有这些解释都假设您或多或少熟悉这些概念。如果所有这些话都没有告诉你任何事情,那么你应该先从一些真正的学习资源中学习,然后再尝试破译其他人的密码。

关于templates - xcode 4.2 中的 OpenGL 游戏模板(这段代码发生了什么?!!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8394714/

相关文章:

c++ - 将多种(不同)类型的参数传递给模板函数

android - OpenGL ES 纹理包装有时会产生奇怪的结果

c++ - 无法在 OpenGL ES2 中显示 RGB 纹理

c# - 如何在内容控件上显示数据模板?

c++ - c++11标准中关于可变参数模板的困惑

c++ - 如何使用模板设置 union 字段

c++ - 模板特化子类

opengl-es - 如何将 OpenGL ES 纹理转换为 CIImage

android - 未使用 OpenGL ES 2.0 和 Android NDK 绘制纹理

opengl-es - GLSL低p : syntax error