Opengl glvertexattributepointer澄清

Opengl glvertexattributepointer澄清,opengl,Opengl,只是想确保我正确地理解这一点(我会在SO Chat上询问,但它死在那里了!): 我们有一个顶点数组,我们通过绑定它使它成为“当前的” 然后我们有一个缓冲区,我们将它绑定到一个目标 然后我们通过glBufferData 它基本上填充了绑定到该目标的任何内容,即我们的缓冲区 然后我们调用glvertexattributepointer,它描述了数据是如何布局的——数据是绑定到GL\u数组\u缓冲区的任何数据 这个描述符被保存到原始的顶点数组中 (1) 我的理解正确吗? 关于每件事之间的关系,这个问题

只是想确保我正确地理解这一点(我会在SO Chat上询问,但它死在那里了!):

我们有一个顶点数组,我们通过绑定它使它成为“当前的”
然后我们有一个缓冲区,我们将它绑定到一个目标
然后我们通过
glBufferData
它基本上填充了绑定到该目标的任何内容,即我们的缓冲区
然后我们调用
glvertexattributepointer
,它描述了数据是如何布局的——数据是绑定到
GL\u数组\u缓冲区的任何数据
这个描述符被保存到原始的顶点数组中

(1) 我的理解正确吗?
关于每件事之间的关系,这个问题有点含糊不清

(2) 是否存在某种默认的顶点数组?因为我忘记/省略了
glgenvertexarray
glbinvertexarray
,没有它我的程序运行得很好


编辑:我错过了一步<代码>GlenableVertexAttribute数组

(3) 顶点属性是否在调用
glVertexAttribPointer
时绑定到顶点数组,然后我们可以通过
glEnableVertexAttribArray
随时启用/禁用该属性,而不管当前绑定的是哪个顶点数组


或者(3b)顶点属性是否在调用
glEnableVertexAttribArray
时绑定到顶点数组,因此我们可以在绑定不同顶点数组的不同时间调用
glEnableVertexAttribArray
将同一顶点属性添加到多个顶点数组中?

有些术语有点错误:

  • 顶点数组
    只是一个包含顶点数据的数组(通常是
    浮点[]
    )。它不需要绑定到任何东西。不要将其与
    顶点数组对象
    或VAO混淆,稍后我将介绍它们
  • 缓冲区对象
    ,通常在存储顶点时称为
    顶点缓冲区对象
    ,简称VBO,您称之为
    缓冲区
  • 不会将任何内容保存回顶点数组,
    glvertexattributepointer
    的工作方式与
    glvertexinter
    glTexCoordPointer
    的工作方式完全相同,只需提供一个指定自己属性的数字,而不是命名属性。将此值作为
    索引传递。所有
    glvertexattributepointer
    调用都会排队等待下次调用
    glDrawArrays
    glDrawElements
    。如果有VAO绑定,VAO将存储所有属性的设置
这里的主要问题是将顶点属性与VAO混淆。顶点属性只是为绘图定义顶点、纹理坐标、法线等的新方法。VAOs存储状态。我将首先解释如何使用顶点属性进行绘图,然后解释如何使用VAO减少方法调用的数量:

  • 在着色器中使用属性之前,必须先启用该属性。例如,如果要将顶点发送到着色器,则最有可能将其作为第一个属性0发送。因此,在渲染之前,需要使用
    GlenableVertexAttributeArray(0)启用它
  • 现在属性已启用,您需要定义它将要使用的数据。为此,您需要绑定VBO-
    glBindBuffer(GL_数组_BUFFER,myBuffer)
  • 现在我们可以定义属性-
    glvertexattributepointer(0,3,GL_FLOAT,GL_FALSE,0,0)。按参数顺序:0是您定义的属性,3是每个顶点的大小,
    GL_FLOAT
    是类型,
    GL_FALSE
    表示不规范每个顶点,最后2个零表示顶点上没有跨步或偏移
  • 用它画一些东西-
    gldrawArray(GL_三角形,0,6)
  • 您绘制的下一个对象可能不会使用属性0(实际上会,但这是一个示例),因此我们可以禁用它-
    glDisableVertexAttributeArray(0)
  • 将其包装在
    glUseProgram()
    调用中,您就拥有了一个能够正确使用着色器的渲染系统。但假设有5种不同的属性,顶点、纹理坐标、法线、颜色和光照贴图坐标。首先,您将对每个属性进行一个
    glvertexattributepointer
    调用,并且必须事先启用所有属性。假设您定义了属性0-4,正如我列出的那样。您可以这样启用所有这些功能:

    for (int i = 0; i < 5; i++)
        glEnableVertexAttribArray(i);
    
    for(int i=0;i<5;i++)
    GlenableVertexAttributeArray(i);
    
    然后,您必须为每个属性绑定不同的VBO(除非您将它们全部存储在一个VBO中并使用偏移量/跨距),然后您需要从
    glVertexAttribPointer(0,…)进行5个不同的
    glVertexAttribPointer
    调用
    glvertexattributepointer(4,…)分别用于顶点到光照贴图坐标

    希望这个系统本身就有意义。现在,我将继续讨论VAO,以解释在进行这种类型的渲染时如何使用它们来减少方法调用的数量。请注意,不需要使用VAO

    顶点数组对象
    或VAO用于存储所有
    glvertexattributepointer
    调用的状态,以及在进行每个
    glvertexattributepointer
    调用时所针对的VBO的状态

    通过调用
    glgenvertexarray
    生成一个。要在VAO中存储所需的所有内容,请将其与
    glBindVertexArray
    绑定,然后执行全绘制调用。所有的draw-bind调用都被VAO截获并存储。您可以使用
    glBindVertexArray(0)解除VAO的绑定

    现在,当您想要绘制对象时,不需要重新调用所有VBO绑定或
    glvertexattributepointer
    调用,只需使用
    glbinvertexarray
    绑定VAO,然后调用
    glDrawArrays