OpenGL——VAO与VBO

转载自链接: 这里

目录

一、VBO的作用

二、VAO的作用

三、一个VAO和多个VBO

注: VAO和VBO都是用来存储顶点信息的,并把这些信息送入顶点着色器。至于什么是顶点和顶点着色器,这里就不多说了,不了解的读者可自行CSDN。

VBO的B为Buffer之意,用来存储顶点数据;VAO的A为Array,但我认为理解为 Attribute(属性) 之意更好,意思是 Buffer(VBO)的属性。

即,我们用VBO来存储数据,而用VAO来告诉计算机这些数据分别有什么属性、起什么作用。

一、VBO的作用

VBO是 CPU 和 GPU 之间传递信息的桥梁,我们把数据存入VBO(这一步在CPU执行),然后VBO会自动把数据送入GPU。

送入GPU这一步,不需任何人为操作,用户只负责往VBO中存入数据就可以了。如下:
在这里插入图片描述

但是,对GPU来说,VBO中存的就只是一堆数字而已,要怎么解释它们呢?这就要用到VAO了。

二、VAO的作用

VBO是为了向GPU传递顶点数据,那么VAO就是为了向GPU解释顶点数据。有的读者会奇怪,顶点数据无非是一个个三维坐标,三个为一组,传就传了,为什么还需要解释呢?那么我们来看下面这个VBO中的数据:

float buffer = {
   	//顶点坐标(3个一组)              //顶点颜色(3个一组)              //纹理坐标(2个一组)
    0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, -0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, -0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f }; //以上数据仅为本博文编造,不具有实操意义 

 

由以上数据可见,顶点数据并非只是三个为一组的三维坐标!

如果我们向VBO中传入了以上buffer,并且VBO把它们送入了GPU。

然而,顶点着色器不知道该如何解释这些数字,到底是把它们3个一组,还是先3个一组、后2个一组,或者是3个、2个、3个?

GPU并不知道。

这就需要VAO的参与了,它负责告诉GPU,VBO中的信息到底该以几个为一组。如下这一段程序,就是把对VBO中数据的描述存到了一个VAO中:

	//vertex coord
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0); glEnableVertexAttribArray(0); // color attribute glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float))); glEnableVertexAttribArray(1); // texture coord attribute glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float))); glEnableVertexAttribArray(2); 

 

上面程序看似有三段(glVertexAttribPointer() + glEnableVertexAttribArray()为一段),但它们都存在同一个VAO里。(这里就不介绍glVertexAttribPointer()和glEnableVertexAttribArray()函数的作用了,不懂的读者可以上网去查。)

在一些复杂的OpenGL程序中,VBO可能会有多个,但VAO只有一个。那么,如何用一个VAO来解释多个VBO呢?

三、一个VAO和多个VBO

OpenGL程序中,VBO可能会有多个,但VAO只有一个。那么,如何用一个VAO来解释多个VBO呢?

这就涉及到OpenGL的上下文知识:一个完整的OpenGL程序相当于一个容器,我们在用到VAO、VBO时,需要先绑定(Bind操作)、再使用,没有经过绑定的VAO/VBO是不起作用的。

一个VAO和多个VBO之间的关系大致如下所示:
在这里插入图片描述

那么,根据一个VAO与多个VBO的关系,以及OpenGL上下文(绑定)的知识,用一个VAO来解释多个VBO的操作流程就如下:

首先,绑定VAO,以告知OpenGL程序该使用这个VAO来对VBO做出解释。
1
然后,绑定第一个VBO,向这个VBO中写入数据,告知VAO该如何解释这个VBO的信息;
然后,解绑这个VBO。

然后,绑定第二个VBO,向这个VBO中写入数据,并在VAO中保存该如何解释这个VBO的信息;
然后,解绑这个VBO。
……

如下一段程序:

	unsigned int VBO[2], VAO; glGenVertexArrays(1, &VAO); glGenBuffers(2, VBO); 

 

/=绑定VAO=======

glBindVertexArray(VAO);
//===============================================================

//=绑定第一个VBO======
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
//===============================================================

<span class="token function">glBufferData</span><span class="token punctuation">(</span>GL_ARRAY_BUFFER<span class="token punctuation">,</span> sphereVertices<span class="token punctuation">.</span><span class="token function">size</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">*</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span><span class="token keyword">float</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token operator">&amp;</span>sphereVertices<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">]</span><span class="token punctuation">,</span> GL_STATIC_DRAW<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//向第一个VBO中写入数据</span> 

//告知VAO该如何解释第一个VBO的信息=
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 sizeof(float), (void)0);
glEnableVertexAttribArray(0);
//===============================================================

//=解绑第一个VBO=====
glBindBuffer(GL_ARRAY_BUFFER, 0);
//===============================================================

//=绑定第二个VBO======
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
//===============================================================

<span class="token function">glBufferData</span><span class="token punctuation">(</span>GL_ARRAY_BUFFER<span class="token punctuation">,</span> <span class="token keyword">sizeof</span><span class="token punctuation">(</span>texVertrices<span class="token punctuation">)</span><span class="token punctuation">,</span> texVertrices<span class="token punctuation">,</span> GL_STATIC_DRAW<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token comment">//向第二个VBO中写入数据</span>

//告知VAO该如何解释第二个VBO的信息=
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 sizeof(float), (void)0);
glEnableVertexAttribArray(1);
//=============================================================

原文地址:http://www.cnblogs.com/zxdplay/p/16821218.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性