VAO VBO IBO的理解

VAO & VBO

 

  • VAO是一个对象,一个VAO可以包含都多个VBO,是一种关联关系
  • 顶点数组对象(Vertex Array Object, VAO)可以像顶点缓冲对象那样被绑定,任何随后的顶点属性调用都会储存在这个VAO中。
  • VBO可以有保存不同的类型,包括顶点坐标、UV、法线、颜色、索引等
  • 通过glBufferData给VBO可以指定相应的类型,再通过glVertexAttribPointer给VBO指定相应的数据格式
  • VBO归根到底是显卡存储空间里的一块缓存区(Buffer)而已

 

VAO 全称 Vertex Array Object,翻译过来叫顶点数组对象,但和Vertex Array(顶点数组)毫无联系!

 

VAO可以像顶点缓冲对象那样被绑定,任何随后的顶点属性调用都会储存在这个VAO中。这样的好处就是,当配置顶点属性指针时,你只需要将那些调用执行一次,之后再绘制物体的时候只需要绑定相应的VAO就行了。这使在不同顶点数据和属性配置之间切换变得非常简单,只需要绑定不同的VAO就行了。

 

glBindVertexArray可以设置当前绑定的VAO,然后glGenBuffers生成VBO后,通过glBindBuffer,就将VBO关联到当前的VAO了。VAO里的VBOs都设置好了以后,在绘制的地方只需要设置当前绑定的VAO是哪个,就能按照初始化的VAO来绘制,即调用glDrawArrays。也就是说在初始化的时候,事先确定VAO的格式,在需要的调用的时候,只需要绑定这个特定的VAO就好。

 

glBindVertexArray(0)表示当前不用VAO了,并不是VAO释放了,所以不是你说的那样要一直“bind,unbind,重新Gen”,而是在显存里专门开辟好了这种VAO对应的格式,只需要填数据就好了,而VAO对象是作为一个整体在合适的时候bind。但是看https://stackoverflow.com/questions/25412767/opengl-glbindbuffer0-outside-vao的解释,不需要对vao,vbo unbind,需要用的时候bind就够了。

 

总结VAO、VBO、EBO、纹理

方式

VAO

VBO

EBO

纹理

获取

getGenVertexArrays

getGenBuffers

getGenBuffers

glGenTextures

绑定

glBindBuffer

glBindBuffer

glBindBuffer

glBindTexture

属性定义

glVertexAttribPointer

glVertexAttribPointer

不需要

glTexImage2D

glGenerateMipmap

解绑

glBindVertexArray

glBindBuffer

glBindBuffer

不解绑

使用

glBindVertexArray

glDrawArrays

默认作用于绑定时的顶点

glBindBuffer

glDrawElements

默认使用

删除

glDeleteVertexArrays

glDeleteBuffers

glDeleteBuffers

 

 

当VAO处于活动状态时,不要解除绑定EBO,因为绑定元素缓冲对象存储在VAO中,但是可以解绑VBO,因为调用glvertexattributpointer,已将VBO注册为当前绑定的顶点缓冲区对象,所以可以安全的解除绑定。

 

 

OpenGL的核心模式要求我们使用VAO,所以它知道该如何处理我们的顶点输入。如果我们绑定VAO失败,OpenGL会拒绝绘制任何东西。

 

一个顶点数组对象会储存以下这些内容:

  • glEnableVertexAttribArray和glDisableVertexAttribArray的调用
  • 通过glVertexAttribPointer设置的顶点属性配置
  • 通过glVertexAttribPointer调用与顶点属性关联的顶点缓冲对象

 

IBO(Index Buffer Object)

 

VAO VBO IBO的全称:

  • 顶点数组对象:Vertex Array Object,VAO
  • 顶点缓冲对象:Vertex Buffer Object,VBO
  • 索引缓冲对象:Element Buffer Object,EBO或Index Buffer Object,IBO

 

EBO(比起EBO,我更喜欢用IBO)也是一个缓冲,它专门储存索引,OpenGL调用这些顶点的索引来决定该绘制哪个顶点。绑定EBO, 后用glBufferData把索引复制到缓冲里, 把缓冲的类型定义为GL_ELEMENT_ARRAY_BUFFER, 最后一件要做的事是用glDrawElements来替换glDrawArrays函数,来指明我们从索引缓冲渲染。glDrawElements函数从当前绑定到GL_ELEMENT_ARRAY_BUFFER目标的EBO中获取索引。

 

顶点数组对象同样可以保存索引缓冲对象的绑定状态。VAO绑定时正在绑定的索引缓冲对象会被保存为VAO的元素缓冲对象。绑定VAO的同时也会自动绑定EBO。

 

当目标是GL_ELEMENT_ARRAY_BUFFER的时候,VAO会储存glBindBuffer的函数调用。这也意味着它也会储存解绑调用,所以确保你没有在解绑VAO之前解绑索引数组缓冲,否则它就没有这个EBO配置了。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);


参考:

  • 你好,三角形:https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/
  • 如何正确理解 opengl 的 vao ?:https://www.zhihu.com/question/30095978/answer/57755570
  • VAO 与 VBO 的前世今生:https://www.photoneray.com/opengl-vao-vbo/

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Qt OpenGL提供了一种实现高效渲染的机制,它使用了VAOVertex Array Object)和VBOVertex Buffer Object)技术。 VAO是一种对象,用于存储顶点数据、顶点属性以及它们之间的关联关系。它可以理解为一个顶点属性的容器。通过使用VAO,我们可以将顶点数据存储在显存中,而不是每次渲染时都从CPU传输顶点数据到显存,从而提高渲染的效率。 VBO是一个存储顶点数据的缓冲区对象。通过将顶点数据存储在VBO中,我们可以将数据一次性地传输到显存中,并且可以高效地管理和使用这些数据。同时,VBO还可以提供顶点缓存和索引缓存功能,用于顶点的重用和图元的索引。 Qt OpenGL提供了许多方便的API来操作VAOVBO。我们可以使用QOpenGLVertexArrayObject类来创建和管理VAO,通过调用QOpenGLBuffer类的相关方法来创建和管理VBO。例如,我们可以使用QOpenGLVertexArrayObject::bind()和QOpenGLVertexArrayObject::release()方法来绑定和释放VAO,使用QOpenGLBuffer::bind()和QOpenGLBuffer::release()方法来绑定和释放VBO。 使用VAOVBO可以大大简化OpenGL代码的编写,并且能够有效提高渲染效率。我们可以将需要渲染的数据一次性地传输到显存中,并且设置好相应的渲染状态,然后每次渲染时只需要绑定VAO进行渲染即可,不需要重复的数据传输和状态设置操作。 综上所述,Qt OpenGLVAOVBO技术可以帮助我们实现高效渲染,提高应用程序的性能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值