正确理解 opengl 的 vao(知乎)

作者:禾惠

链接:https://www.zhihu.com/question/30095978/answer/87995822
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

OpenGL在画画的时候,要用到很多的信息,如顶点的坐标、纹理、颜色等等.... 假如一个顶点包含了坐标和颜色的信息,那么这个顶点处的数据格式可能如下:
x, y, z, r, g, b
这些值会被存储在一个叫VBO (vertex buffer object)的地方。
因而,可以把VBO理解成一个数据区域,这里面存放了渲染所需要的一切信息。但需要注意的是,数据在VBO里面的时候,OpenGL是并不知道这里面的每个数据所代表的具体含义的,只是一堆数值罢了。
这时候,VAO(vertex array object)就派上用场了。
VAO指定了读取VBO的方式~~

假如VBO里面现在存放了如下的内容:
x0, y0, z0, r0, g0, b0
x1, y1, z1, r1, g1, b1
x2, y2, z2, r2, g2, b2

VAO可以定义一种格式说,我每次只取VBO里面的x,y,z的值;也可以定义一种格式说,每次只取VBO里面的r,g,b的值。这样我们就可以在渲染的时候,绑定不同的VAO,实现按照不同的格式将VBO里面的东西渲染出来~

通过定义VBO里面数据存放的方式、VAO的格式以及合适的GLSL 语言,就能够灵活地画出我们所需要的各种图形。



作者:Vinjn张静
链接:https://www.zhihu.com/question/30095978/answer/57775171
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

VAO 记录的是

  1. vertex attribute 的格式,由 glVertexAttribPointer 设置。
  2. vertex attribute 对应的 VBO 的名字, 由一对 glBindBuffer 和 glVertexAttribPointer 设置。
  3. #当前#绑定的 GL_ELEMENT_ARRAY_BUFFER 的名字,由 glBindBuffer 设置。

VAO 中并不保存#当前#绑定的 GL_ARRAY_BUFFER,VBO 和 vertex attribute 的绑定是在 glVertexAttribPointer 中完成的。

完整信息参考  Vertex Specification



画一张图就很好理解了 所谓的VAO定义了顶点属性 而VBO只是一堆本质上没区别的数据

作者:知乎用户
链接:https://www.zhihu.com/question/30095978/answer/67147426
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

VertextAttribPoint,把这个 buffer 设置为某个 vao 的某个属性。这样,vao 的某个属性就有了实际数据。

画个示意图是这样:
          ___________
vao ---> | attrib[0] |--- vbo ---> vec3 array { {x,y,z}, ... }; //3d-坐标
         |-----------|
         | attrib[1] |--- vbo ---> vec2 array { {x,y}, ... }; //whatever
         |-----------|
         |   ...     |
         |-----------|
         | attrib[k] |--- vbo ---> vec4 array { {x,y,z,w}, ... };
          ~~~~~~~~~~~

作者:MichaelCheng
链接:https://www.zhihu.com/question/30095978/answer/57755570
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

(1)显示列表是一组预先编译好的OpenGL函数语句,是记录的一组过程;而VAO对应的是一组内存缓存区组成的对象,是在显存里划分的。
(2)VAO是一个对象,一个VAO可以包含都多个VBO,是一种关联关系;而VBO又可以有保存不同的类型,包括顶点坐标、UV、法线、颜色、索引等,通过glBufferData给VBO可以指定相应的类型,再通过glVertexAttribPointer给VBO指定相应的数据格式。
(3)glBindVertexArray 可以设置当前绑定的VAO,然后glGenBuffers生成VBO后,通过glBindBuffer能够关联到当前的VAO。VAO里的VBOs都设置好了以后,在绘制的地方只需要设置当前绑定的VAO是哪个,就能按照初始化的VAO来绘制,即调用glDrawArrays。也就是说在初始化的时候,事先确定VAO的格式,在需要的调用的时候,只需要绑定这个特定的VAO就好。
(4)glBindVertexArray(0)表示当前不用VAO了,并不是VAO释放了

你可能感兴趣的:(OpenGL)