在xcode 4.2中找到的OpenGL游戏模板(此代码中发生了什么?!!)

Poc*_*chi 4 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);
Run Code Online (Sandbox Code Playgroud)

这属于在xcode 4.2上创建OpenGL游戏的模板.但是我很困惑,如果有人能向我解释,我会很高兴.

首先,如何生成并绑定_vertexArray而不向其添加任何内容?

其次,IF 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,
Run Code Online (Sandbox Code Playgroud)

我想我正在为以下命令处理这个数组,其中我启用GLK属性,这就是我使用指针(仍然使用prev绑定的).但是,如果我没有弄错的语法是,(属性设置,顶点的大小,类型,假,结构的大小(我认为不是24),并从数据偏移(12来自哪里?!))

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

编辑:要诚实我DID尝试在各个站点研究opengl但我只能遇到理论而不是实践.这就是我问这个问题的原因.

Chr*_*ica 21

好的,一步一步:

glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
Run Code Online (Sandbox Code Playgroud)

这将绑定并生成顶点数组对象(VAO).现在VAO不包含任何数据.它只包含与顶点数组/属性相关的所有状态,例如启用的属性或使用的设置glVertexAttribPointer.

glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
Run Code Online (Sandbox Code Playgroud)

现在,这将创建并绑定一个顶点缓冲区对象(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,
Run Code Online (Sandbox Code Playgroud)

您的数据被布置为一堆浮点数(每个32位/ 4字节),每六个值代表一个顶点,而顶点又包含一个位置(3个浮点数)和一个正常值(3个浮点数).

glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
Run Code Online (Sandbox Code Playgroud)

这指定了每个顶点包含3个浮点值的第一个属性(位置),每个顶点之间的步长为24个字节.这意味着它是从一个顶点的属性值(在这种情况下为位置)的起点到下一个顶点的属性数据的开头的24个字节.事实上,24个字节是6个浮点数的大小,因此是我们的顶点数据中单个顶点的数据,所以这恰好相符.最后一个参数表示位置数据从当前绑定的VBO(包含我们的顶点数据)的开始处开始,因为它是我们顶点数据中的第一个属性.

glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
Run Code Online (Sandbox Code Playgroud)

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

glEnableVertexAttribArray(GLKVertexAttribPosition);
glEnableVertexAttribArray(GLKVertexAttribNormal);
Run Code Online (Sandbox Code Playgroud)

这些最终启用了渲染属性.

glBindVertexArrayOES(0);
Run Code Online (Sandbox Code Playgroud)

所以这现在绑定默认(无)VAO,因为我们已完成指定它.我想这整个代码片段是一些初始化例程的一部分.所以现在每当我们想要渲染我们的顶点数据时,也许是使用glDrawArrays,我们只需要glBindVertexArray在调用draw方法之前使用绑定VAO,并且每个顶点数组状态由最后绑定时得到的值设置glEnableVertexAttribArrayglVertexAttribPointer得到的值,就像在我们的初始化程序.如果您不使用VAO,则每次要绘制此顶点数据时都必须调用glBindBuffer两个glEnableVetrexAttribArrayglVertexAttribPointer调用.

但所有这些解释都假设您或多或少熟悉这些概念.如果所有这些话都没有告诉你任何事情,那么在尝试破译其他人的代码之前,你应该从学习一些真正的学习资源开始.