关于OpenGL利用VBO绘制以及VBO和VAO的关系

  • 前言
  • VBO
  • VAO
  • 整合
    • 顶点数据
  • 特别注意!

前言

VBOVAO是OpenGL中非常重要的概念,这里先解释一下是什么意思:

顶点数组对象:Vertex Array Object,VAO
顶点缓冲对象:Vertex Buffer Object,VBO

初学者很容易弄错两者的关系 刚开始我也弄错了QAQ,这里就来详细解释一下:

VBO

  全称Vertex Buffer Object,是用来储存顶点数据的,我们知道:将数据从CPU发送到显卡是非常慢的,所以,就需要这样一个东西,将顶点数据一次性发送到显卡,提高渲染的效率,创建VBO的流程大概是这样的:

glGenBuffers(1, &VBO); // 创建一个VBO
glBindBuffer(GL_ARRAY_BUFFER, VBO); // 绑定顶点数据缓存空间
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 发送数据

  这里简单说一下:GL_ARRAY_BUFFER 指的是OpenGL提供的几种缓冲区中的一种,类似比较常用的还有:GL_ELEMENT_ARRAY_BUFFER ,这些缓冲区是用来缓存待发送的数据的,当数据全部复制到缓冲区GL_ARRAY_BUFFER ~(即 glBindBuffer(GL_ARRAY_BUFFER, VBO); )~ 之后,再通过 glBufferData 发送数据到显卡上,这样就完成了一次高效的数据传输。

VAO

  接着就是 Vertex Array Object ,我们用VBO向显卡发送了数据,但是显卡并不知道这些数据是干嘛的,以及怎么使用这些数据,这时候就需要VAO来描述这些数据了,VAO还有一个好处,一个VAO可以对应多个VBO,这样绘制起来就很方便。

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

同样,创建一个VAO也很简单:

glGenVertexArrays(1, &VAO); // 创建一个VAO
glBindVertexArray(VAO); // 绑定VAO
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); // 利用VAO描述顶点属性
glEnableVertexAttribArray(0);   // 启用着色器中的顶点属性

整合

  将上面所说的整合成一个类就是这样的:

注:BasicShader是用来编译着色器的。

class BasicDraw
{public:~BasicDraw() {glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO_Vertex);glDeleteBuffers(1, &VBO_color);}// 初始化绘图==>创建VAOunsigned int Get_STATIC_VAO(float vertices[],int size_vertices, float color[], int size_color) {// 创建VBO和VAOglGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO_Vertex); // 创建顶点和颜色的VBOglGenBuffers(1, &VBO_color);// 绑定VAO,这代表解绑这钱所有数据都会存到这个VAO中glBindVertexArray(VAO);// 提交数据/* 顶点VBO */glBindBuffer(GL_ARRAY_BUFFER, VBO_Vertex); // 绑定顶点数据缓存空间glBufferData(GL_ARRAY_BUFFER, size_vertices, vertices, GL_STATIC_DRAW);// 解析VBO中的数据glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);// 启用顶点属性==>即着色器中(location=0)的顶点属性glEnableVertexAttribArray(0);/* 颜色VBO */glBindBuffer(GL_ARRAY_BUFFER, VBO_color);glBufferData(GL_ARRAY_BUFFER, size_color, color, GL_STATIC_DRAW);glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (void*)0);glEnableVertexAttribArray(1);// 解绑VBO==>因为已经将数据发送到显卡了,所以可以安全的解绑glBindBuffer(GL_ARRAY_BUFFER, 0);// 解绑VAOglBindVertexArray(0);return VAO;}
private:unsigned int VBO_Vertex, VBO_color, VAO;
};

顶点数据

 float vertices[] = {-0.5f, -0.5f, 0.0f, // left  0.5f, -0.5f, 0.0f, // right 0.0f,  0.5f, 0.0f  // top   };GLfloat colors[] = {1.0f, 0.0f, 0.0f, 1.0f,0.0f, 1.0f, 0.0f, 1.0f,0.0f, 0.0f, 1.0f, 1.0f};

特别注意!

  如果是通过类来实现绘制功能,需要在参数里加上数组的大小,不然就会找俩小时错误都不知道错在哪QAQ,因为sizeof(ptr)一定是8字节,所以一定会出错!!!学的教训啊QAQ

关于OpenGL利用VBO绘制以及VBO和VAO的关系相关推荐

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

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

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

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

  3. 多个着色器与多个VAO,VBO绘制三角形

    多个着色器与多个VAO,VBO绘制三角形 设置不同片段着色器绘制两个三角形 设置多个不同片段着色器绘制三个三角形 写在最前面: 如果对一个三角形的绘制过程还不明白建议先去看看

  4. opengl学习2 绘制三角形和矩形

    在OpenGL中,任何事物都在3D空间中,而屏幕和窗口却是2D像素数组,这导致OpenGL的大部分工作都是关于把3D坐标转变为适应你屏幕的2D像素.3D坐标转为2D坐标的处理过程是由OpenGL的图形 ...

  5. android命令行 gles,Android利用OpenGLES绘制天空盒实例教程

    前言 天空盒这个效果最早是在腾讯的实景地图里看到的,当时觉得很牛逼,但是没有想过自己去实现以下.最近这段时间对opengl很有兴趣,顺便就搞了这个天空盒,话不多说,先上效果. 天空盒的原理就是在三维空 ...

  6. OpenGL学习脚印: 绘制一个三角形

    写在前面 接着上一节内容,开发环境搭建好后,我们当然想立即编写3D应用程序了.不过我们还需要些耐心,因为OpenGL是一套底层的API,因而我们要掌握的基本知识稍微多一点,在开始绘制3D图形之前,本节 ...

  7. 【EBO】使用OpenGL通过EBO绘制简单五角星

    参考:LearnOpenGL CN:https://learnopengl-cn.github.io/01%20Getting%20started/04%20Hello%20Triangle/ 使用O ...

  8. 【OpenGL学习】绘制三角形

    绘制三角形 上节中完成了窗口的绘制,这节我们主要实现在窗口中完成一个最简单的三角形的绘制,同样,要完成一个三角形的绘制,需要以下内容: Vertex Array 存放顶点数据的数组(实际上存放的是顶点 ...

  9. OpenGL几种绘制方式

    OpenGL几种绘制方式 OpenGL 绘制 本文介绍了OpenGL的几种绘制方式及各自特点.绘制方式如下: 立即模式 显示列表 顶点数组 VBO 1.立即模式 最直接的方式,传统的使用glBegin ...

最新文章

  1. python读取配置文件存在某配置_Python读取配置文件(config.ini)以及写入配置文件
  2. [PHP] PHP与Apache的模块配合说明
  3. php代码怎么复制_PHP_PHP网站备份程序代码分享,效果图:PHP代码 复制代码 代码 - phpStudy...
  4. eclipse中java文件报错:The type java.lang.Object cannot be resolved. It is indirectly referenced from r
  5. 【Vegas原创】终端服务器超出了最大允许连接数 解决方法
  6. 【Linux学习】Linux的文件权限(一)
  7. linux下的open的注意事项
  8. android输入时背景颜色,Button根据EditText输入状态改变背景颜色
  9. php bloginfo templatedirectory,WordPress函数:bloginfo(显示博客信息)
  10. Apache Hudi 在 B 站构建实时数据湖的实践
  11. django-模型类管理器
  12. 读懂AIMS 2013中的性能分析报告
  13. 那些让人惊叹的命令执行效果
  14. NetBeans修改字体中文乱码问题
  15. JavaScript 【99乘法表】【案例】
  16. 帝国CMS教程,使用灵动标签调用上一篇下一篇的文章标题图片的方法
  17. 头脑王者类似源码研究
  18. Variant 用法详解
  19. linux中ls命令查看文件大小与时间
  20. Multimedia Timers

热门文章

  1. 微信仿朋友圈添加图片
  2. 【新书推荐】【2009.11】伟大的思想(第一辑)论自然
  3. 如何下载谷歌浏览器历史版本及chromedriver驱动
  4. Ubuntu 安装WPS
  5. PHP实现think-queue介绍
  6. 3D游戏开发基础-姜雪伟-专题视频课程
  7. 任奎:人工智能算法安全浅析——深度学习中的对抗攻击与防御
  8. 微信小程序自制轮播图(仿京粉轮播)
  9. 学习 Python 的 12 个方式
  10. Prometheus===》普罗米修斯容器化监控、PromQL的使用、Grafana添加普罗米修斯数据源模板