首页 > 其他分享 >【图像】【OpenGL】VAO和VBO的关系

【图像】【OpenGL】VAO和VBO的关系

时间:2023-03-12 22:48:16浏览次数:40  
标签:VAO OpenGL 0.0 VBO GPU sizeof GL

目录
一、VBO的作用
二、VAO的作用
三、一个VAO和多个VBO
注: VAO和VBO都是用来存储顶点信息的,并把这些信息送入顶点着色器。至于什么是顶点和顶点着色器,这里就不多说了,不了解的读者可自行CSDN。

VBO的B为Buffer之意,用来存储顶点数据;VAO的A为Array,但我认为理解为 Attribute(属性) 之意更好,意思是 Buffer(VBO)的属性。

即,我们用VBO来存储数据,而用VAO来告诉计算机这些数据分别有什么属性、起什么作用。

一、VBO的作用
VBO是 CPU 和 GPU 之间传递信息的桥梁,我们把数据存入VBO(这一步在CPU执行),然后VBO会自动把数据送入GPU。

送入GPU这一步,不需任何人为操作,用户只负责往VBO中存入数据就可以了。如下:


但是,对GPU来说,VBO中存的就只是一堆数字而已,要怎么解释它们呢?这就要用到VAO了。

二、VAO的作用
VBO是为了向GPU传递顶点数据,那么VAO就是为了向GPU解释顶点数据。有的读者会奇怪,顶点数据无非是一个个三维坐标,三个为一组,传就传了,为什么还需要解释呢?那么我们来看下面这个VBO中的数据:

float buffer = {
//顶点坐标(3个一组) //顶点颜色(3个一组) //纹理坐标(2个一组)
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
-0.5f, 0.5f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f
};
//以上数据仅为本博文编造,不具有实操意义
1
2
3
4
5
6
7
8
由以上数据可见,顶点数据并非只是三个为一组的三维坐标!

如果我们向VBO中传入了以上buffer,并且VBO把它们送入了GPU。

然而,顶点着色器不知道该如何解释这些数字,到底是把它们3个一组,还是先3个一组、后2个一组,或者是3个、2个、3个?

GPU并不知道。

这就需要VAO的参与了,它负责告诉GPU,VBO中的信息到底该以几个为一组。如下这一段程序,就是把对VBO中数据的描述存到了一个VAO中:

//vertex coord
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
// color attribute
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// texture coord attribute
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
1
2
3
4
5
6
7
8
9
上面程序看似有三段(glVertexAttribPointer() + glEnableVertexAttribArray()为一段),但它们都存在同一个VAO里。(这里就不介绍glVertexAttribPointer()和glEnableVertexAttribArray()函数的作用了,不懂的读者可以上网去查。)

在一些复杂的OpenGL程序中,VBO可能会有多个,但VAO只有一个。那么,如何用一个VAO来解释多个VBO呢?

三、一个VAO和多个VBO
在OpenGL程序中,VBO可能会有多个,但VAO只有一个。那么,如何用一个VAO来解释多个VBO呢?

这就涉及到OpenGL的上下文知识:一个完整的OpenGL程序相当于一个容器,我们在用到VAO、VBO时,需要先绑定(Bind操作)、再使用,没有经过绑定的VAO/VBO是不起作用的。

一个VAO和多个VBO之间的关系大致如下所示:


那么,根据一个VAO与多个VBO的关系,以及OpenGL上下文(绑定)的知识,用一个VAO来解释多个VBO的操作流程就如下:

首先,绑定VAO,以告知OpenGL程序该使用这个VAO来对VBO做出解释。

然后,绑定第一个VBO,向这个VBO中写入数据,告知VAO该如何解释这个VBO的信息;
然后,解绑这个VBO。

然后,绑定第二个VBO,向这个VBO中写入数据,并在VAO中保存该如何解释这个VBO的信息;
然后,解绑这个VBO。
……
1
2
3
4
5
6
7
8
如下一段程序:

unsigned int VBO[2], VAO;
glGenVertexArrays(1, &VAO);
glGenBuffers(2, VBO);

//=========================绑定VAO===============================
glBindVertexArray(VAO);
//===============================================================

//=======================绑定第一个VBO============================
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
//===============================================================

glBufferData(GL_ARRAY_BUFFER, sphereVertices.size() * sizeof(float), &sphereVertices[0], GL_STATIC_DRAW); //向第一个VBO中写入数据

//================告知VAO该如何解释第一个VBO的信息=================
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//===============================================================

//=======================解绑第一个VBO===========================
glBindBuffer(GL_ARRAY_BUFFER, 0);
//===============================================================

//=======================绑定第二个VBO============================
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);
//===============================================================

glBufferData(GL_ARRAY_BUFFER, sizeof(texVertrices), texVertrices, GL_STATIC_DRAW);//向第二个VBO中写入数据

//================告知VAO该如何解释第二个VBO的信息=================
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
glEnableVertexAttribArray(1);
//=============================================================
————————————————
原文链接:https://blog.csdn.net/qq_39642978/article/details/113082924

 

标签:VAO,OpenGL,0.0,VBO,GPU,sizeof,GL
From: https://www.cnblogs.com/im18620660608/p/17209434.html

相关文章

  • 实验2.2——VAO,VBO的总结
    这俩个O,前面搞了这么多链接,已经迷糊了,捋一捋吧。事物的发展都是一个过程,所以如果能按着这个技术发展的过程来学习,应该就能捋顺了。简单的说,如果能亲身经历一遍这个发展过......
  • OpenGL入门1.3:着色器 GLSL
     前言#经过之前一段时间的学习(渲染管线简介)我们已经知道了着色器(Shader)是运行在GPU上的程序,这些小程序为图形渲染管线的某个特定部分而运行,着色器只是一种把输入转化......
  • OpenGL-GLSL语言入门教程(1)
    目录GLSL简介GLSL的内建变量顶点着色器变量gl_PointSizegl_VertexID片段着色器变量gl_FragCoordgl_FragDepth参考网站:LearnOpenGL参考书籍:OpenGL编程指南第九版......
  • OpenGL学习(十)-- 着色语言 GLSL 语法介绍
    我的OpenGL专题学习目录,希望和大家一起学习交流进步!OpenGL学习(一)--术语了解OpenGL学习(二)--Xcode搭建OpenGL环境OpenGL学习(三)--OpenGL基础渲染OpenGL学习(......
  • OpenGL笔记十四:GLSL语法
    前言期待您移步上篇:OpenGL笔记十三:GLSL加载纹理颠倒六种方案概述GLSL全称OpenGLShadingLanguage,是用来在OpenGL中着色编程的语言,即开发人员写的自定义程序代码......
  • openGL之glsl入门1--基本概念
    从零开始学习openGL与GLSL(没有计算机图像学基础),开始确实挺费劲,网上的资料虽然多,但不系统,例子也不全,openGL还好(这里指的是v2.0之前的版本,使用glBegin(),glEnd()方式绘制),完......
  • 自定义控件 QOpenGLWidget并实现缩放(纯代码)
    QScrollArea+QOpenGLWidget实现缩放,用于显示QImage。先自定义QOpenGLWidget,然后自定义QWidget(上图)glwidget.h#ifndefGLWIDGET_H#defineGLWIDGET_H#include<QO......
  • Android 使用opengles部分记录
    关于旋转和旋转轴参考:Android使用OpenGLES3.0实现随手指旋转3D立方体glm库https://github.com/g-truc/glm下载https://github.com/g-truc/glm/releases/download/0.......
  • Opengl入门基础(七)-数学基础
    opengl除了基础的模型构建和贴图,还需要进行位置变换,缩放等功能,之前定义的顶点坐标(0,0.5,0),纹理坐标(0,0.5)实际上是一个向量,而对多个坐标构成的模型进行变换、缩放实际上是向量与......
  • QOpenGLWidget+ScrollArea显示图像,实现缩放
    原理参考博客Qt居中显示图片,图过大则出现滚动条(ui方式)的两种方法Label+ScrollArea、GraphicsView-夕西行-博客园(cnblogs.com)界面只添加布局控件,然后代码new QOpen......