OpenGL开发关于VAO和VBO的理解
文章目录
- OpenGL渲染时涉及到的数据传输
- 上述流程中涉及到的内存
- 一、VBO的相关API调用
- 二、渲染vbo内存中的数据需要调用的API
- 三、VAO的相关调用的API
- 四、VBO和VAO的解绑
OpenGL渲染时涉及到的数据传输
- 准备好需要绘制的顶点数据。(自己定义的或者是从某些模型文件中读取出来的)
- 在GPU中开辟一块内存。
- 将顶点数据传到上一步开辟的GPU的内存中。
- 将着色器代码转化为着色器程序,并链接到当前的执行程序中。
- GPU根据着色器的逻辑将这块内存的数据进行计算。(指定该如何将数据发送给显卡)
- 将这块已经计算完的数据一并发送给显卡进行渲染绘制。
上述流程中涉及到的内存
- 根据上面的流程,可知整个数据渲染的流程中,涉及到两个数据传输的流程,一个是将数据传输到GPU中的内存、另一个是将GPU中的数据传输给显卡。
- GPU的内存通过顶点缓冲对象(Vertex Buffer Objects),也就是VBO来管理这个内存,它会在GPU内存(通常被称为显存)中储存大量顶点。
- 使用这VBO的好处是我们可以一次性的发送一大批数据到显卡上,而不是每个顶点发送一次。
一、VBO的相关API调用
- 生成一个VBO对象:
int vboId = glGenBuffers();
- 设置顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER,将创建的vbo对象绑定到当前的执行程序上,也可以理解为激活。
glBindBuffer(GL_ARRAY_BUFFER, vboId);
- 将准备好的顶点数据复制到缓冲的内存中,posBuffer为顶点数据,GL_STATIC_DRAW表示数据不会改变和几乎不会改变。第三个参数一共有三个选择:
GL_STATIC_DRAW
表示数据不会或几乎不会改变、GL_DYNAMIC_DRAW
表示数据会被改变很多、GL_STREAM_DRAW
表示数据每次绘制时都会改变。
glBufferData(GL_ARRAY_BUFFER, posBuffer, GL_STATIC_DRAW);
比如说一个缓冲中的数据将频繁被改变,那么使用的类型就是GL_DYNAMIC_DRAW或GL_STREAM_DRAW,这样就能确保显卡把数据放在能够高速写入的内存部分。
指定输入数据的哪一个部分对应顶点着色器的哪一个顶点属性,也就是在渲染前指定OpenGL该如何解释VBO中的顶点数据。glVertexAttribPointer中的参数的意义分别是:
- 第一个参数为顶点着色器中
layout (location=0) in vec3 position;
中的location的值。
- 第二个参数为第二个参数指定顶点属性的维数,如果是
vec3,它由3个值组成,所以大小是3
。 - 第三个参数为
数据的类型
。 - 第四个参数为是否希望数据被标准化,如果我们设置为
GL_TRUE
,所有数据都会被映射到0(对于有符号型signed数据是-1)到1之间。 - 第五个参数叫做
步长(Stride)
,它告诉我们在连续的顶点属性组之间的间隔。设置为0的意思是让OpenGL自己去识别步长。 - 最后一个参数表示位置数据在缓冲中起始位置的
偏移量(Offset)
。由于位置数据在数组的开头,所以这里是0。
- 第一个参数为顶点着色器中
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
二、渲染vbo内存中的数据需要调用的API
进行完上面的步骤,准备工作已经做完,接下来就是要准备渲染了。
glEnableVertexAttribArray(0);//使vbo的内存变为可用状态。
glUseProgram(shaderProgram);//调用着色器程序。
glDrawElements(GL_TRIANGLES, getVertexCount(), GL_UNSIGNED_INT, 0);//绘制方法
当一个vbo中的数据准备完成以后,绘制的过程是需要执行以上三步,如果程序中只有一种顶点类型的vbo,那倒还好;如果有很多种vbo(在激活vbo时,调用glBindBuffer
时是可以选择很多种类型的),这样一来,在绘制这些vbo时,就需要重复调用很多次上面的三个步骤。为了简化这个流程,也减少GPU和显卡的交互次数。思考:有没有一些方法可以使我们把所有这些状态配置储存在一个对象中,并且可以通过绑定这个对象来恢复状态,此时就提出了VAO
的概念。
三、VAO的相关调用的API
顶点数组对象(Vertex Array Object )VAO
可以像VBO
顶点缓冲对象那样被创建和绑定。当一个VAO被创建绑定之后,任何随后的顶点属性调用都会储存在这个VAO
中。 这样一来如果有多个vbo对象,在渲染绘制时,就不用执行很多次前面提到的渲染程序,只需要执行一次绑定的VAO的渲染API即可。
- 创建VAO的流程与VBO类似。
int vaoId = glGenVertexArrays();//创建
glBindVertexArray(vaoId);//绑定,激活
- VAO渲染
glBindVertexArray(getVaoId());
glEnableVertexAttribArray(0);
glUseProgram(shaderProgram);
glDrawElements(GL_TRIANGLES, getVertexCount(), GL_UNSIGNED_INT, 0);
四、VBO和VAO的解绑
- VBO解绑
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
- VAO解绑
glDisableVertexAttribArray(0);
glBindVertexArray(0);
OpenGL开发关于VAO和VBO的理解相关推荐
- OpenGL中的VAO和VBO使用技巧
VBO:Vertex Buffer Object,顶点缓冲对象. 可以存储大量顶点,因而我们可以利用VBO一次性发送一大批数据到显卡上. VAO:Vertex Array Object,顶点数组对象. ...
- OpenGL学习笔记(八):进一步理解VAO、VBO和SHADER,并使用VAO、VBO和SHADER绘制一个三角形
原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7888 ...
- OpenGL - 如何理解 VAO 与 VBO 之间的关系
系列文章目录 LearnOpenGL 笔记 - 入门 01 OpenGL LearnOpenGL 笔记 - 入门 02 创建窗口 LearnOpenGL 笔记 - 入门 03 你好,窗口 LearnO ...
- openGL关于VAO和VBO和EBO的区分和理解
1.VBO VBO为顶点缓冲对象,是显卡存储空间中开辟出的一块内存缓存区,用于存储顶点的各类属性信息,如顶点坐标,顶点法向量,顶点颜色数据等.在渲染时,可以直接从VBO中取出顶点的各类属性数据. 所以 ...
- 关于VAO,VBO和EBO的理解-OpenGL学习笔记
本文章首发于我的个人博客,希望大家多多支持! Hi! This is Showhoop Studio! 如果要从代码层面去理解渲染管线的工作,学习使用OpenGL编程可以说是一个不错的选择.这里我将记 ...
- 【OpenGL】理解VAO、VBO、EBO和 shader中vertex、fragment交互。
1:首先了解GPU和渲染管道工作原理. 2:解释VAO.VBO.EBO 顶点数组对象:Vertex Array Object,VAO 顶点缓冲对象:Vertex Buffer Object,VBO 元 ...
- 【Opengl】 VAO与VBO的关系
转载 这里 目录 一.VBO的作用 二.VAO的作用 三.一个VAO和多个VBO 注: VAO和VBO都是用来存储顶点信息的,并把这些信息送入顶点着色器.至于什么是顶点和顶点着色器,这里就不多说了,不 ...
- QT OpenGL(一 VAO、VBO、EBO使用)
1.什么是OpenGL? Open Graphics Library,它是一个由Khronos组织制定并维护的规范 OpenGL核心是一个C库,同时也支持多种语言的派生 核心模式 也叫可编程管线,提供 ...
- Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序
OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...
最新文章
- Ios文件连接dlna服务器,iOS播放多种视频格式,实现DLNA|AirPlay投射盒子总结
- UnicodeEncodeError: 'ascii' codec can't encode character
- UA MATH567 高维统计专题1 稀疏信号及其恢复3 Coherence与RIP简介
- runtimeexception异常_应用系统的异常管理-持续更新
- C++ Primer 5th笔记(2)chapter 2变量和基本类型
- 开源一个ShellCode生成框架
- 记录一个AndroidX和Android support库不能共存的坑
- Java for LeetCode 042 Trapping Rain Water
- phpredis 报错 “Function Redis::setTimeout() is deprecated” 解决方法
- 磁盘一把锁一个感叹号_TBase中的一些锁
- Java并发编程实战之基于生产者消费者模式的日志服务读书笔记
- 为什么不算法?常用算法概要大纲!
- 夜,思考——我想要的到底是什么?
- 网络安全基础——NTFS安全权限
- 内网KMS服务器搭建分享
- 正则去除html标签和空字符,正则表达式清除空格和html标签中的 空格
- 电容基础知识 之 钽电解电容
- 2020-08-17:为什么HashMap中数组的容量为2的次幂?
- java中socket实现一对一聊天
- 1个人,100天业余时间,用Flutter开发完一个商业APP,手握5家大厂offer