刚学的,理解可能还不到位,有错误请指正:
参考了:
https://www.bilibili.com/read/cv10477263?spm_id_from=333.999.0.0
开始:
setAttributeArray("pos",vertices,3 ): 设置当前VAO中,顶点属性【pos】的数据来源为数组【vertices】.每次从CPU内存取数据。
setAttributeValue() : 只是传递一个数据的指针过去
setAttributeBuffer() : 使用的是当前缓存对象(Buffer Object)作为数据来源,因此在调用这个函数时,必须要绑定当前缓存对象,如果你没绑定,会将一个空缓存对象ID(0)存放到VAO中,当你调用draw函数时,则会出现内存泄漏导致程序崩溃,因此请务必注意这里.
举例,从CPU内存读取数据:
// 每次在paintGL()中调用 VAO.bind() // 最好不用0、1这些数据,容易搞混,直接传GLSL定义的变量更好,比如: // shaderProgram.setAttributeArray("vertexPos" ,vertices ,3 ,6*sizeof (GLfloat)); shaderProgram.setAttributeArray(0 ,vertices ,3 ,6*sizeof (GLfloat)); shaderProgram.setAttributeArray(1 ,vertices + 3 ,3 ,6*sizeof (GLfloat)); VAO.release();
VBO:这样记:是GPU 的一块内存;
从GPU内存读数据:
// 只要在initGL()调用一次即可 VAO.bind(); VBO.bind(); shaderProgram.setAttributeBuffer(0,GL_FLOAT,0,3,sizeof(GLfloat)*6); shaderProgram.setAttributeBuffer(1,GL_FLOAT,sizeof(GLfloat)*3,3,sizeof(GLfloat)*6); VBO.release(); VAO.release();
而且顶点位置、颜色数组直接分开来,不然放一起还要考虑彼此的间隔,没啥意思!
知乎的这个解释比较到位:
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 语言,就能够灵活地画出我们所需要的各种图形。
一张图搞定这些鸟函数关系(原创):