文章目录

  • OpenGL渲染时涉及到的数据传输
    • 上述流程中涉及到的内存
    • 一、VBO的相关API调用
    • 二、渲染vbo内存中的数据需要调用的API
    • 三、VAO的相关调用的API
    • 四、VBO和VAO的解绑

OpenGL渲染时涉及到的数据传输

  • 准备好需要绘制的顶点数据。(自己定义的或者是从某些模型文件中读取出来的)
  • 在GPU中开辟一块内存。
  • 将顶点数据传到上一步开辟的GPU的内存中。
  • 将着色器代码转化为着色器程序,并链接到当前的执行程序中。
  • GPU根据着色器的逻辑将这块内存的数据进行计算。(指定该如何将数据发送给显卡)
  • 将这块已经计算完的数据一并发送给显卡进行渲染绘制。

上述流程中涉及到的内存

  1. 根据上面的流程,可知整个数据渲染的流程中,涉及到两个数据传输的流程,一个是将数据传输到GPU中的内存、另一个是将GPU中的数据传输给显卡
  2. GPU的内存通过顶点缓冲对象(Vertex Buffer Objects),也就是VBO来管理这个内存,它会在GPU内存(通常被称为显存)中储存大量顶点。
  3. 使用这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的理解相关推荐

  1. OpenGL中的VAO和VBO使用技巧

    VBO:Vertex Buffer Object,顶点缓冲对象. 可以存储大量顶点,因而我们可以利用VBO一次性发送一大批数据到显卡上. VAO:Vertex Array Object,顶点数组对象. ...

  2. OpenGL学习笔记(八):进一步理解VAO、VBO和SHADER,并使用VAO、VBO和SHADER绘制一个三角形

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7888 ...

  3. OpenGL - 如何理解 VAO 与 VBO 之间的关系

    系列文章目录 LearnOpenGL 笔记 - 入门 01 OpenGL LearnOpenGL 笔记 - 入门 02 创建窗口 LearnOpenGL 笔记 - 入门 03 你好,窗口 LearnO ...

  4. openGL关于VAO和VBO和EBO的区分和理解

    1.VBO VBO为顶点缓冲对象,是显卡存储空间中开辟出的一块内存缓存区,用于存储顶点的各类属性信息,如顶点坐标,顶点法向量,顶点颜色数据等.在渲染时,可以直接从VBO中取出顶点的各类属性数据. 所以 ...

  5. 关于VAO,VBO和EBO的理解-OpenGL学习笔记

    本文章首发于我的个人博客,希望大家多多支持! Hi! This is Showhoop Studio! 如果要从代码层面去理解渲染管线的工作,学习使用OpenGL编程可以说是一个不错的选择.这里我将记 ...

  6. 【OpenGL】理解VAO、VBO、EBO和 shader中vertex、fragment交互。

    1:首先了解GPU和渲染管道工作原理. 2:解释VAO.VBO.EBO 顶点数组对象:Vertex Array Object,VAO 顶点缓冲对象:Vertex Buffer Object,VBO 元 ...

  7. 【Opengl】 VAO与VBO的关系

    转载 这里 目录 一.VBO的作用 二.VAO的作用 三.一个VAO和多个VBO 注: VAO和VBO都是用来存储顶点信息的,并把这些信息送入顶点着色器.至于什么是顶点和顶点着色器,这里就不多说了,不 ...

  8. QT OpenGL(一 VAO、VBO、EBO使用)

    1.什么是OpenGL? Open Graphics Library,它是一个由Khronos组织制定并维护的规范 OpenGL核心是一个C库,同时也支持多种语言的派生 核心模式 也叫可编程管线,提供 ...

  9. Android OpenGL ES 学习(六) – 使用 VBO、VAO 和 EBO/IBO 优化程序

    OpenGL 学习教程 Android OpenGL ES 学习(一) – 基本概念 Android OpenGL ES 学习(二) – 图形渲染管线和GLSL Android OpenGL ES 学 ...

最新文章

  1. Ios文件连接dlna服务器,iOS播放多种视频格式,实现DLNA|AirPlay投射盒子总结
  2. UnicodeEncodeError: 'ascii' codec can't encode character
  3. UA MATH567 高维统计专题1 稀疏信号及其恢复3 Coherence与RIP简介
  4. runtimeexception异常_应用系统的异常管理-持续更新
  5. C++ Primer 5th笔记(2)chapter 2变量和基本类型
  6. 开源一个ShellCode生成框架
  7. 记录一个AndroidX和Android support库不能共存的坑
  8. Java for LeetCode 042 Trapping Rain Water
  9. phpredis 报错 “Function Redis::setTimeout() is deprecated” 解决方法
  10. 磁盘一把锁一个感叹号_TBase中的一些锁
  11. Java并发编程实战之基于生产者消费者模式的日志服务读书笔记
  12. 为什么不算法?常用算法概要大纲!
  13. 夜,思考——我想要的到底是什么?
  14. 网络安全基础——NTFS安全权限
  15. 内网KMS服务器搭建分享
  16. 正则去除html标签和空字符,正则表达式清除空格和html标签中的 空格
  17. 电容基础知识 之 钽电解电容
  18. 2020-08-17:为什么HashMap中数组的容量为2的次幂?
  19. java中socket实现一对一聊天
  20. 1个人,100天业余时间,用Flutter开发完一个商业APP,手握5家大厂offer

热门文章

  1. 炉石传说:魔兽英雄传
  2. 【C#基础】初识编程语言C#
  3. 【Bioconda】Can‘t locate Bio/SeqIO.pm in @INC
  4. 操作系统笔记(II:从进程同步到文件管理)
  5. linux系统下编译运行C++程序
  6. 微信群发自动添加称呼前缀,让你的节日祝福不再千篇一律!
  7. Vue路由传参和接收参数
  8. 【手游】有杀气童话 美术资源加密分析
  9. 攻防世界 app-4 base64的理解
  10. ajax beforesend 不执行,ajaxSetup(beforeSend不工作