LearnOpenGL学习笔记(三)——VBO,VAO,EBO理解

  在opengl中所有的数据都要放在显存中,我们通过一定的手段去管理它,既要提供地方存放它,还要提供方法去正确地提取它们,去使用它们,opengl通过VAO,VBO,EBO这些手段来解决这些问题。 (一)VBO(Vertex Buffer Objects,顶点缓冲对象)介绍: 首先我们要明白VBO是一种管理手段,它的中文名中“缓冲”,就决定了它是管理存储的一种手段(methon),总的来 说,为什么要设置这个VBO,是应该从着色器程序说起。 着色器的第一个顶点着色器接受到我们数据流传入的顶点数据后,它会把这些数据放到GPU的显存上面(等同内存) 接下来向OpenGL中配置如何去解释这些内存,未来如何发给显卡处理。接下来着色器才会按照我们编的代码做我们想做 事情。 我们设立VBO的原因就是要管理这些内存,这样做有很多好处比如:1.我们可以往一个VBO管理的内存中放很多顶点 的数据,这样我们就可以一下子把这些数据都从cpu的数据流上送到GPU(显卡)的显存上,这样节省时间,因为从CPU往 GPU的过程中,要经过很多“关卡”,送一“筐”和送一“卡车”是没有区别的。 (二)声明一个VBO如下:

unsigned int VBO;//声明一个句柄
glGenBuffers(1, &VBO);//1是一个缓冲ID,用Gen生成一个缓冲区。
glBindBuffer(GL_ARRAY_BUFFER, VBO);  //用这个函数将这个缓冲区变成一个GL_ARRAY_BUFFER,这是顶点缓冲类型的意思。
//注意这是一个绑定函数,现在所有输入GL_ARRAY_BUFFER的数据,都会直接被送入现在这个VBO,而不是其他的VBO2,VBO3之类的什么,如果
我们不要用这个VBO,想换一个VBO2,我们必须先解绑这个VBO。
//注意我们不会去直接用VBO,因为我们的数据必须全部输入到目标缓冲GL_ARRAY_BUFFER里,这样表明我们输入的是顶点属性,而不是别的
什么。
//这就相当于我们可以输入的缓冲对象类型,已经被设定好了,我们只能往这些地方输入数据,位于它们后面缓冲区,可以不断更换用来实现
不同目的。

(三)往VBO里面放入数据:

 接下来这个函数是很重要的,它是将数据从cpu的流中提取出来,放入显存中的VBO管理的区域里。
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//首先是缓冲类型声明,GL_ARRAY_BUFFER表明数据将被传入刚才绑定这个类型的缓冲区里,第二个是数据流的大小,第三个是数据流名字,
第四个是希望显卡如何管理给定的数据,要告诉显卡这些数据未来会不会被改变。要是希望经常改变的话,显卡会把数据放在能够高速写入
的内存部分,这样节省资源。
GL_STATIC_DRAW :数据不会或几乎不会改变。
GL_DYNAMIC_DRAW:数据会被改变很多。
GL_STREAM_DRAW :数据每次绘制时都会改变。


//到这一步,我们的数据流已经没有用了,放在内存上的缓冲区的坐标数据,将被传入显卡上的着色器,被用来使用。
接下来就是着色器的任务了。如何去解释数据流,将一条连续的float流数据解读为三维的顶点数据(就是将数字变成具有几何意义的坐标点)
这都是着色器的任务了。
    

       在解释什么是VAO之前,我们先要解释一下着色器的一个任务,正是着色器的这个任务,导致我们必须使用VAO这种方式来设置。

复制顶点数组到缓冲中供OpenGL使用
glBindBuffer(GL_ARRAY_BUFFER, VBO); 
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 
// 1. 设置顶点属性指针 
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); 
glEnableVertexAttribArray(0); 
// 2. 当我们渲染一个物体时要使用着色器程序 
glUseProgram(shaderProgram); 
// 3. 绘制物体 
someOpenGLFunctionThatDrawsOurTriangle();
//这就是我们渲染一个物体的步骤,其中最重要的就是1.将数据从cpu数据流传入CPU的VBO缓冲区管理的显存里2.将数据流正确的解释成三维
坐标。
//这里使用了一个属于叫做顶点属性指针,他就是用来解释该如何去解释数据流的,使用不同的属性指针可以得到不同的解释。

(四)设立VAO,顶点数组对象(Vertex Array Object):

   一个VAO中包含两个关键东西,glVertexAttribPointer函数绑定的VBO和顶点属性配置(也就是数据放在哪里
,和如何读取数据)。此外还有glEnableVertexAttribArray和glDisableVertexAttribArray这两个函数用来启
用顶点属性,和取消顶点属性链接。
   这样就造成了一个你绑定一个VAO就可以知道,去哪里读,用什么方式去解读。

这样你在绑定一个VAO的情况下,便可以绘制这个物体,只要它们的读取方式(顶点属性配置)一样。
注意把顶点数组复制到缓冲中供OpenGL使用,是在VBO里面布置的,
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
//举个例子,你想绘制一个边长3cm的立方体,就绑定这个VAO,OPENGL这个状态机下一刻就会绘制出来这个
//如果你想绘制一个长方体,就解绑之前哪个VAO,绑定VAO1,就下一刻绘制出长方体了。

  (五)设立EBO,索引缓冲对象(Element Buffer Object):

      索引缓冲对象EBO,不是我们必须设置的东西,我们必须设置VAO,来告诉OpenGL如何读取,将数据放入哪里。但我们不必一定
要有EBO。我们之所以发明EBO是用来简化我们的程序的渲染步骤的,它是用来告诉我们如何去绘制的。
      这要从我们3d世界说起,电脑里面的所有3d立体图形,无论是球形,还是不规则图形,它们都是由三角形构成的,也就是说
都是由三个点构成一个面,无数个面构成一个立体图形。这样在不规则立体图形里,必然由许多的点是共用的,我们为了能在输入
数据的时候少输入一些点(传输数据很花时间的),就要想办法将这些共用的点利用起来,只输入一次,这就是EBO的发明原因。
在操作时,我们先输入所有点的数据(VBO,和设置顶点属性指针),再设置将哪些点绘制成面(EBO),这就形成了正规的3d立体图形。

float vertices[] = { 
       0.5f, 0.5f, 0.0f, // 右上角 
       0.5f, -0.5f, 0.0f, // 右下角 
      -0.5f, -0.5f, 0.0f, // 左下角 
      -0.5f, 0.5f, 0.0f // 左上角 
}; 
unsigned int indices[] = { 
         // 注意索引从0开始!  
         0, 1, 3, // 第一个三角形 
         1, 2, 3 // 第二个三角形 
};

我们也是用数据流来表明,哪些点构成一个面。
接下来的操作似曾相识,将数据索引复制到缓冲里。

unsigned int EBO; 
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);


在渲染的时候,因为调用了EBO,所以不能用绘制VAO的函数glDrawArrays,要使用兼容glDrawElements,用法是类似的。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
//6的意思是一共绘制六个顶点。0是一个偏移量,这里填0就好了
在绘制的时候,EBO和VBO都可以看作缓存,它们都被VAO管理着,所以实际渲染中,我们只需要绑定VAO,就可以了。

                                          ,并且将一条连续的float流数据解读为三维的顶点数据 (就是将数字变成具有几何意义的坐标点)。    

 

### 回答1: OpenGL中的VAOVBOEBO种重要的缓存对象,用于存储和管理顶点数据和索引数据。 VAO(Vertex Array Object)是顶点数组对象,用于存储顶点数据的属性信息,如顶点坐标、颜色、法向量等。VAO可以将多个VBO绑定到同一个VAO中,方便管理和使用。 VBO(Vertex Buffer Object)是顶点缓存对象,用于存储顶点数据的实际数值,如顶点坐标、颜色、法向量等。使用VBO可以提高渲染效率,减少数据传输次数。 EBO(Element Buffer Object)是索引缓存对象,用于存储顶点索引数据,可以减少重复顶点的存储,提高渲染效率。 总之,VAOVBOEBOOpenGL中非常重要的缓存对象,可以提高渲染效率,减少数据传输次数,方便管理和使用。 ### 回答2: OpenGL是一款广泛应用于图形渲染的开源3D图形库。VAOVBOEBO个单词是OpenGL中的种不同类型的缓冲区对象。 VAO,即顶点属性对象,是一个OpenGL缓冲区对象,用于存储和管理顶点属性,即描述一个图元的顶点的各种属性,如顶点坐标、颜色、法线等。VAO可以容纳多个VBO,而且可以把VBO的数据分组合起来,VBO的顶点属性索引可以绑定到VAO中,这样一来,当我们要渲染一个物体时,只需绑定一个VAO对象,就可以一次性调用所有需要的VBOVBO,即顶点缓冲区对象,是一个OpenGL缓冲区对象,用于高效存储顶点数据,如顶点坐标、顶点颜色等。当需要渲染一个物体时,我们可以从VBO中读取需要的顶点信息,然后传递给渲染管线进行处理和渲染。使用VBO有一些显著的优势,比如,VBO能够提升渲染性能,减少CPU和GPU之间的数据传输,同时还可以减少内存占用。 EBO,即索引缓冲区对象,是一种存储一系列索引的OpenGL缓冲区对象。EBO中的索引是用于指定顶点顺序的,即用于描述角形顶点之间的关系。使用EBO可以大大减少需要传输给GPU的数据量,并且可以避免重复的顶点数据,提升渲染性能。 一般情况下,我们通过VAOVBOEBO来实现复杂图形的绘制。在渲染一个物体时,首先需要创建一个VAO对象,并绑定所有需要使用的VBOEBO。然后将这些缓冲区对象中的数据存储到GPU中,并在渲染时调用这些数据。最后,将VAO对象绑定到渲染管道中,执行图形渲染操作。 ### 回答3: OpenGL是一种图形库,它可以用来渲染维场景或者二维绘图。VAOVBOEBO都是OpenGL中的重要概念,用于优化渲染性能和提高代码可读性。 VAO(Vertex Array Object)是一个顶点数组对象,它保存了一组顶点数据的状态。每个顶点包含诸如位置、法向量、纹理坐标等属性。VAO可以将这些属性打包成一个容器,使得OpenGL可以更快地访问和处理数据。VAO通常包括各种属性缓冲对象(VBO),它们保存了不同类型的属性数据。 VBO(Vertex Buffer Object)是OpenGL中的缓冲对象,用于存储顶点数据。VBO可以存储各种顶点属性,如位置、法向量、颜色等。VBO可以在GPU内存中创建,并且可以被透明地映射到CPU内存。这意味着我们可以直接在CPU内存中修改VBO的数据,而不必将其复制到GPU中。 EBO(Element Buffer Object)是一个索引缓冲对象,它充当索引数组的角色。EBO中存储的是顶点的索引,这些索引对应于VBO中存储的实际顶点数据。使用EBO可以减少顶点数据的冗余性。例如,在多个角形之间共享相同的顶点数据时,可以使用EBO来避免重复数据的存储。 总之,VAOVBOEBOOpenGL中的重要工具,它们可以大大提高渲染性能和代码可读性。VAO提供了一种整理顶点属性的方法,VBO可以高效地管理顶点数据,而EBO可以减少数据冗余。对于OpenGL编程来说,深入了解VAOVBOEBO是非常重要的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值