开始opengl第八版-1.VAO与VBO
来源:互联网 发布:最好的公交查询软件 编辑:程序博客网 时间:2024/05/17 00:08
http://www.cnblogs.com/MyGameAndYOU/p/4678657.html
http://blog.csdn.net/candycat1992/article/details/39676669 理解VAO与VBO
传递顶点数据
那么,现在的问题是,如果是你,你会怎么把顶点和它相关的信息,例如纹理坐标、法线等,传递给GLSL呢?一般人都会想到多维数组。我们下面把它称为顶点流(Vertex Stream)。(什么?!你不是这么想的?!没关系,OpenGL是这么想的就好。。。)
我们负责创建这个顶点流,然后只需要告诉OpenGL怎样解读它就可以了。
为了渲染一个对象,我们必须使用一个shader program。而这个program会定义一系列顶点属性,例如上述Vertex Shader中的vPosition一行。这些属性决定了我们需要传递哪些顶点数据。每一个属性对应了一个数组,并且这些数据的维度都必须相等,即是一一对应的关系。
比如我们想要渲染3个顶点,我们会定义下面的数据:
这些顶点的顺序是非常重要的,OpenGL将会根据这些顺序渲染网格。我们可以直接使用上述这种数据来直接渲染,也可以使用索引(indices)来指定顺序,这样可以重复使用同一个顶点。
例如,我们使用下面的索引列表:
那么OpenGL将会渲染6个顶点:
现在,我们还想传递一个新的顶点属性,即每个顶点的纹理坐标,那么新的纹理数组可能长这样:
注意,纹理数据的维度大小一定要和上面的坐标数组大小一致,而其他顶点属性数组的维度也要满足这个条件。这是非常容易理解的。
那么,合并后的顶点属性列表就是:
OpenGL的做法:VAO和VBO
OpenGL使用了VAO来实现上述管理顶点数据的数据作用,以及VBO来存放真正的顶点属性数据。
VAO(Vertex Array Object)
我们这里遇到了第一种OpenGL对象——VAO(Vertex Array Object)。前面说到OpenGL对象是状态的集合,那么VAO就是所有顶点数据的状态集合。它存储了顶点数据的格式以及顶点数据数据所需的缓存对象的引用。前面提过,OpenGL对象都有三个非常重要的函数,而VAO对应的就是glGenVertexArrays、glDeleteVertexArrays和glBindVertexArray。
VAO负责管理顶点属性,而这些顶点属性从0到GL_MAX_VERTEX_ATTRIBS - 1被编号。这些属性在Vertex Shader里的表现就是类似下面的语句:
上述顶点属性vPosition被编号为0。
每个属性可以被enable或者disable,被disable的属性是不会传递给shader的,即便在shader里定义了这些属性,它们读出的值也会是一个常量,而非真正的数据。一个新建的VAO的所有属性访问都是disable的。而开启一个属性是通过下面的函数:
glDisableVertexAttribArray 函数。
与其对应的是而为了使用上述函数来改变VAO的状态,我们首先需要把VAO绑定到当前的context上。
VBO(Vertex Buffer Object)
VBO是一种Buffer Object,即它也是一个OpenGl对象。VBO是顶点数组数据真正所在的地方。
为了指定一个属性数据的格式和来源,我们需要告诉OpenGL,编号为0的属性使用哪个VBO,编号为1的属性使用哪个VBO等等。为了实现它,我们可以这么做。
首先,我们要知道,任何VBO都需要先绑定到GL_ARRAY_BUFFER才可以对它进行操作。绑定后,我们可以调用下面的函数之一:
GL_ARRAY_BUFFER的VBO。为了更好理解,我们举例:
它们的作用大同小异,就是告诉OpenGl,编号为index的属性使用当前绑定在GL_ARRAY_BUFFER上。第二行意味着,编号为0的属性将使用buf1的数据,因为当前绑定到GL_ARRAY_BUFFER上的是buf1。第三行将缓存对象0绑定到了GL_ARRAY_BUFFER上,这不会对顶点属性有任何影响,只有glVertexAttribPointer函数可以影响它们!
上面第一行代码将buf1绑定到了这个过程就像一个中介人的作用,而中介人就是GL_ARRAY_BUFFER。我们可以这么想,glBindBuffer 设置了一个全局变量,然后glVertexAttribPointer读取了这个全局变量并把它存储在VAO中,这个全局变量就是GL_ARRAY_BUFFER。当调用完glVertexAttribPointer后,顶点属性已经知道了数据来源就是buf1,它们之间就会直接联系,而不需要在通过GL_ARRAY_BUFFER。
使用VAO与VBO,将其关联,并将数据传递到shader,用法
/**
函数原型:void glVertexAttribPointer(GLuint index, GLint size, GLenum type,
GLboolean normalized, GLsizei stride, const GLvoid* pointer);
之前我们调用了glBindData所传递给缓存的只是数据,之后我们要使用它,还必须指定数据类型。
所以该函数完成的主要任务是:
1、告诉OpenGL,该存储数据的格式
2、因为我们使用着色器来编程,因此在顶点着色器阶段,我们会使用该函数来给着色器中的in类型的属性变量传递数据。
那么它们是怎么联系起来的呢?
便是通过第一个参数index,指明了着色器程序中变量的下标的作用。
例如:layout( location=index ) in vec4 position;
如果这个index和glVertexAttribPointer的第一个参数一样,那么相关缓存区的数据就会传递到这个position变量中去。
3、该函数执行之后,会影响改变VAO的状态,VBO会被复制保存到VAO中。之后如果改变了当前所绑定的缓存对象,也不会改变到VAO里的对象。
*/
glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
/**
因为默认情况下,顶点属性数组是不可访问的,所以我们需要调用以下函数激活它。
范围为0到GL_MAX_VERTEX_ATTRIBS-1
*/
glEnableVertexAttribArray(vPosition);
0 0
- 开始opengl第八版-1.VAO与VBO
- OpenGL中的VAO与VBO
- OpenGL中VBO与VAO
- OpenGL中的VAO与VBO
- OpenGL中的VBO与VAO的使用
- opengl VAO ,VBO
- opengl VAO and VBO
- opengl-vao-vbo
- VBO与VAO
- VAO与VBO
- VBO与VAO
- VAO与VBO
- VAO与VBO
- VAO与VBO
- OpenGL 4.0 VAO VBO 理解
- OpenGL ES VBO 和 VAO
- OpenGL 函数解析 VBO VAO
- OpenGL 4.0 VAO VBO 理解
- pycharm输出中文出现乱码的几种解决方法以及读取时打印出现乱码的解决
- F8APP(一)
- PHP 7 的五大新特性
- BZOJ 1043 [HAOI2008]下落的圆盘
- c99 可变参数宏 __VA_ARGS__
- 开始opengl第八版-1.VAO与VBO
- 2016 ACM/ICPC Dalian Online-1010 Weak Pair
- android 开发中遇到的混淆的问题
- Python爬虫_BeautifulSoup爬取百度百科
- 各大平台免费接借口
- jquery序列化serialize()方法时中文乱码及解决办法
- mybaits批量插入
- Linux下安装SVN客户端
- Project build error: Non-resolvable parent POM: Could not find artifact weixin:weixin:pom:0.0.1-SNAP