【OpenGL】VAO与VBO

1、我们先了解什么是OpenGL对象(OpenGL Object)

根据OpenGL Wiki的定义:

An OpenGL Object is an OpenGL construct that contains some state. When they are bound to the context, the state that they contain is mapped into the context‘s state. Thus, changes to context state will be stored in this object, and functions that act on this context state will use the state stored in the object.

我们知道OpenGL对象就是一个包含某些状态的OpenGL结构。而当它们被绑定到上下文环境时,它们的所包含的状态会被映射到上下文的状态。也就是说,对上下文的状态更改会存储到该对象中,并且在这个上下文状态下的函数将使用存储在对象中的状态。

OpenGL被定义为状态机(state machine),大部分API的调用会引起OpenGL的状态发生变化,而OpenGL会使用当前的状态进行渲染。前面所说的上下文,也即是OpenGL的上下文状态。

事实上,OpenGL Object就是封装了一组特定的状态以及相关可以改变其状态的函数。

2、VAO是什么,以及它的作用?

VAO全称Vertext Array Object,意为顶点数组对象,也是一个OpenGL Obejct。它是一个存储了提供顶点数据所需要的所有状态的OpenGL Object。

VAO存储了顶点数据的格式,以及可以提供顶点数据数组的缓存对象VBO。(It stores the format of the vertex data as well as the Buffer Objects providing the vertex data arrays.)

注意VAO并不存储顶点数据,只是记录了顶点相关的状态(譬如顶点位置的格式以及顶点位置的数据、纹理坐标的格式以及纹理坐标的数据)。

作为一个OpenGL Object,VAO也同样有着对应的创建(glGenVertexArrays)、销毁(glDeleteVertexArrays)、以及绑定(glBindVertexArray)函数。

另外一个新创建的VAO默认对于所有属性数组的访问都是disable的,如果要启用需要调用glEnableVertexArribArray,相反则是glDisableVertexAttribArray

(A newly-created VAO has array access disabled for all attributes. Array access is enabled by binding the VAO in question and calling)

顶点属性的值在0到GL_MAX_VERTEX_ATTRIBS-1的范围内。

VAO可以想象为连接顶点属性数组以及VBO中的顶点数据的桥梁。

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3、我们先了解什么是Buffer对象(Buffer Object)

根据OpenGL Wiki的定义:

Buffer Objects are OpenGL Objects that store an array of unformatted memory allocated by the OpenGL context (aka: the GPU). These can be used to store vertex data, pixel data retrieved from images or the framebuffer, and a variety of other things.

由此我们可得知,Buffer Object也是一种OpenGL Object,但它是指由OpenGl分配的内存区域,用来存储顶点数据、从图像或者帧缓存(framebuffer)取得的像素数据以及其他数据。

4、VBO是什么,以及它的作用?

VBO全称是Vertext Buffer Object,是用来存储顶点数组数据的缓存对象。

-----------------------------------------------------------------------

注意:The GL_ARRAY_BUFFER binding is NOT part of the VAO‘s state! 也就是说绑定到GL_ARRAY_BUFFER的类型不会影响到VAO的状态,

之后需要调用glVertexAttribPointer才会真正影响到VAO的状态。

譬如下面代码:

glBindBuffer(GL_ARRAY_BUFFER, buf1);// buf1被绑定到GL_ARRAY_BUFFER类型的缓存
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);// 顶点属性索引0从buf1获得它的顶点数组?
glBindBuffer(GL_ARRAY_BUFFER, 0);// OpenGL不再绑定之前的GL_ARRAY_BUFFER类型缓存

那么这样之后,顶点属性索引0与buf1之间如何联系呢?

我们可以这么想,glBindBuffer设置了一个全局的变量,之后glVertexAttribPointer读取了该全局变量并且将它存入VAO中。

所以改变了绑定的缓存对象之后,并不会影响到VAO里的变量。事实上,OpenGL就是这么工作的。

把顶点属性索引index和缓存buffer联系起来的正是glVertexAttribPointer。这也是为什么GL_ARRAY_BUFFER不是VAO的状态的原因(This is also why GL_ARRAY_BUFFER is not VAO state)

但是注意如果当前是0绑定到GL_ARRAY_BUFFER时,调用glVertexAttribPointer会产生error。

 

2015.7.26

    广州

时间: 2024-10-11 19:52:55

【OpenGL】VAO与VBO的相关文章

opengl VAO and VBO

VBO用于存储顶点数据,包括顶点颜色.坐标.法线,以及顶点的indices. VAO则用于存储图形处理器将怎么使用VBO里面的数据,及顶点数据中哪些是坐标.哪些是颜色.哪些是法线等信息. 之前对于这些总是不是太明白,因此我猜测也有一部分跟我一样不明白,所以我准备通过Cocos2d-x的renderer代码来说明有VAO和没有VAO的时候的区别,来加深对VAO的理解. 首先我们来看初始化代码: void Renderer::setupBuffer() { if(Configuration::get

OpenGL 4.0 GLSL 基础教程概览——VAO和VBO常用操作接口

OpenGL  4.3 最新渲染管线图 从OpenGL 2.0 到 OpenGL 3.0变化非常大,但从OpenGL 3.0 到OpenGL 4.0 变化不是太大. 着色器程序直接运行在GPU上,并且是并行的,一个片元着色器可能一次执行所有象素. deprecation model, 在OpenGL3.0 提出,为了保持向后兼容,兼容模式compatibility profile.和核心模式core profile的概念在OpenGL 3.2 中提出. 在Qt 4.7以后版本,可以通过下列方式选

OpenGL下的VBO的图形绘制

为了避免反复向显卡传送相同的定点数据,绘制大量顶点数据时OpenGL下可以使用缓存对象(Buffer Object)来将数据上传到显卡. 准备数据 我们的显示数据为一正方体,如下所示 顶点数据结构为颜色(RGBA)法线(xyz)坐标(xyz) 顶点数据存储在vertices, 定点的索引数据存储在indices, 同时还需要缓存对象的句柄vertexBuffer和indexBuffer struct CUSTOM_VERTEX { float r, g, b, a; float nx, ny,

OpenGL中glVertex、显示列表(glCallList)、顶点数组(Vertex array)、VBO及VAO区别

OpenGL中glVertex.显示列表(glCallList).顶点数组(Vertex array).VBO及VAO区别 1.glVertex 最原始的设置顶点方法,在glBegin和glEnd之间使用.OpenGL3.0已经废弃此方法.每个glVertex与GPU进行一次通信,十分低效. glBegin(GL_TRIANGLES); glVertex(0, 0); glVertex(1, 1); glVertex(2, 2); glEnd(); 2.显示列表(glCallList) 每个gl

VAO VBO EBO(3)

本篇写一下EBO(element buffer object, 又称index buffer object IBO,索引缓冲对象). 在明白了VBO,VAO的相关概念之后,EBO理解起来就简单了很多. 假设现在我们需要绘制一个矩形,首先我们想到的是给出四个点,然后让OpenGL处理.但是限制出现了,OpenGL主要处理三角形,这个时候我们就会想着给出两个三角形来组成一个矩形(事实上OpenGL就是这么干的). 那么我们怎么处理呢?给出两个三角形的点 float vertices[] = { //

GLES2学习VBO和VAO的使用

在GLES2中使用VBO和VAO对象,已经简单vs,ps绘制一个三角形. 1. 初始化操作代码,创建VBO.VAO,编译和链接shader program. void DebugApplication::TestCreateVBO() { //顶点shader const GLchar* vertexShaderSrc = "#version 100\n" "attribute vec4 a_position; \n" // 输入顶点属性,从外部传入 "v

基于Cocos2d-x学习OpenGL ES 2.0系列——编写自己的shader(2)

在上篇文章中,我给大家介绍了如何在Cocos2d-x里面绘制一个三角形,当时我们使用的是Cocos2d-x引擎自带的shader和一些辅助函数.在本文中,我将演示一下如何编写自己的shader,同时,我们还会介绍VBO(顶点缓冲区对象)和VAO(顶点数组对象)的基本用法. 在编写自己的shader之前,我觉得有必要提一下OpenGL渲染管线. 理解OpenGL渲染管线,对于学习OpenGL非常重要.下面是OpenGL渲染管线的示意图:(图中淡蓝色区域是可以编程的阶段) 此图是从wiki中拿过来的

cocos2D-X源码分析之从cocos2D-X学习OpenGL(3)----BATCH_COMMAND

个人原创,欢迎转载,转载请注明原文地址http://blog.csdn.net/bill_man 上一篇介绍了QUAD_COMMAND渲染命令,顺带介绍了VAO和VBO,这一篇介绍批处理渲染命令BatchCommand,批处理命令的处理在Render中比较简单 else if(commandType == RenderCommand::Type:: BATCH_COMMAND) { //将之前缓存的绘制 flush(); auto cmd = static_cast<BatchCommand*>

OpenGL学习资料汇总

我学OpenGL的3D编程也有1.2个年头了,走了很多弯路,也算有点收获.现在整理出一些好用的资料如下. Structure (Foundemental) of 3Dhttps://code.msdn.microsoft.com/Structure-of-3D-3faf705a?SRC=VSIDE 评价:图文并茂地介绍了3D编程的最基本的起步知识.英文的. NeHe OpenGL教程中文版 地址(http://www.yakergong.net/nehe/) 评价:耐心耐心再耐心地从第一篇开始照