### 前言 VBO、VAO和EBO是OpenGL中三个很基础的概念,但一开始时总是分不清他们的区别与联系。 ### 正文 * VBO:顶点缓冲对象

  • 是在显卡存储空间中开辟的一块内存缓存区,用于存储顶点的各类属性(顶点坐标、顶点法向量、顶点颜色等)

  • 渲染时,可以直接从VBO中取出顶点的各类属性数据

  • 每个VBO都有其唯一标识ID

  • 使用glGenBuffers开辟VBO并分配id

  • 通过glBindBuffer将某种类型的顶点数据绑定到某个VBO上(可以暂时理解为告诉该VBO它要存储的数据的类型,当然这是不准确的,因为同一类型的顶点数据一次只能绑定一个VBO)。绑定的类型必须是以下几种中的一种

    • GL_ARRAY_BUFFER
    • GL_ELEMENT_ARRAY_BUFFER
    • GL_PIXEL_PACK_BUFFER
    • GL_PIXEL_UNPACK_BUFFER
  • 通过glBufferData将数据传送到绑定的VBO中

  • 使用glVertexAttribPointer告知OpenGL如何处理某个VBO中的数据

    • 第一个参数指定顶点属性位置,与顶点着色器中的layout(location=0)对应
    • 第二个参数指定一个顶点属性组的大小(数据元素个数)
    • 第三个参数指定顶点属性数据类型
    • 第四个参数指定数据是否要被标准化
    • 第五个参数是步长,指定连续顶点属性组之间的间隔。比方说三个GL_FLOAT数据表示一个坐标点,那就把他们作为一个属性组,步长就是3*sizeof(float)
    • 第六个参数是数据起始位置距离缓冲区中起始位置的偏移量
  • 使用glEnableVertexAttribArray开启glVertexAttribPointer。由于glVertexAttribPointer默认是关闭的,所以使用时要用顶点属性位置的值为参数,通过glEnableVertexAttribArray来开启这一功能

  • VAO:顶点数组对象

    • 保存了很多VBO的引用,相当于把很多VBO统一到一个对象中进行管理

    • 使用glGenVertexArrays得到一个VAO,并分配id

    • 使用glBindVertexArray绑定VAO。绑定后,后面所有VBO的引用都会被保存在这一个VAO中。

    • VAO的存在意义是减少绑定的工作量。因为每次绘制某些之前都需要绑定顶点的所有信息到对应的VBO中。这样做未免有点太麻烦,尤其是数据量很大的情况下。使用VAO,可以把所有顶点信息都绑定到VBO后,再通过VAO把所有顶点信息绑定到一个对象上(VAO),后面只需要绑定VAO这一个对象即可。

  • EBO:索引缓存对象

    • 存储顶点的索引,避免因为某些点重复存储导致的空间浪费