OpenGL 4.0中数据缓冲VBO,VAO,EBO的使用总结
Opengl是大家常用的一个API,我们用它绘制数据的时候需要使用vao,vbo,ebo等对象,绘制方式分为 vao绘制,ebo绘制等。使用不同api还能分为普通调用以及Instance绘制。
首先申请vao,vbo和以及他们两者的绑定:
这里注意的是,百度百科上说的最多支持四个位置,我测试了一下,7到8个顶点属性都没问题,比如Position,Texcoord,Color,Normal等等,需要排列好。
其实他们的绑定有两种方式,第一种是vao搭配多个vbo,每一个vbo代表顶点的一种属性,比如vbo[0] 代表位置,vbo[1]代表纹理坐标。。代码如下:

//位置
glGenBuffers(1, &vbo0);
glBindBuffer(GL_ARRAY_BUFFER, vbo0);
glBufferData(GL_ARRAY_BUFFER, 3 * 4 * sizeof(GLfloat), posCube, GL_STATIC_DRAW); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), nullptr);
//纹理
glGenBuffers(1, &vbo1);
glBindBuffer(GL_ARRAY_BUFFER, vbo1);
glBufferData(GL_ARRAY_BUFFER, 2 * 4 * sizeof(GLfloat), texCube, GL_STATIC_DRAW); glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr); //法线
glGenBuffers(1, &vbo2);
glBindBuffer(GL_ARRAY_BUFFER, vbo2);
glBufferData(GL_ARRAY_BUFFER, 3 * 4 * sizeof(GLfloat), normalCube, GL_STATIC_DRAW); glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_TRUE, 3 * sizeof(GLfloat), nullptr); //法线
glGenBuffers(1, &vbo3);
glBindBuffer(GL_ARRAY_BUFFER, vbo3);
glBufferData(GL_ARRAY_BUFFER, 3 * 4 * sizeof(GLfloat), normalCube2, GL_STATIC_DRAW); glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_TRUE, 3 * sizeof(GLfloat), nullptr); //法线
glGenBuffers(1, &vbo4);
glBindBuffer(GL_ARRAY_BUFFER, vbo4);
glBufferData(GL_ARRAY_BUFFER, 3 * 4 * sizeof(GLfloat), normalCube3, GL_STATIC_DRAW); glEnableVertexAttribArray(4);
glVertexAttribPointer(4, 3, GL_FLOAT, GL_TRUE, 3 * sizeof(GLfloat), nullptr); //法线
glGenBuffers(1, &vbo5);
glBindBuffer(GL_ARRAY_BUFFER, vbo5);
glBufferData(GL_ARRAY_BUFFER, 3 * 4 * sizeof(GLfloat), normalCube4, GL_STATIC_DRAW); glEnableVertexAttribArray(5);
glVertexAttribPointer(5, 3, GL_FLOAT, GL_TRUE, 3 * sizeof(GLfloat), nullptr);
第二种关联方式:则一个vao搭配一个vbo,这种传递方式类似于把结构体数组或者内存的数据传递给vbo。 内存排布 是这样的:位置纹理法线位置纹理法线 。位置是float x3,纹理floatx2,法线float x3,
解析的时候就是 顶点1: 位置纹理法线 顶点2位置纹理法线,他们会有间隔
struct MyVertex
{
vec3 pos;
vec2 tex;
vec3 normal;
}; //顶点定义
for (int i = 0; i < 4; i++)
{
MyVertex v;
v.pos.x = posCube[i * 3 + 0];
v.pos.y = posCube[i * 3 + 1];
v.pos.z = posCube[i * 3 + 2]; v.tex.s = texCube[i * 2 + 0];
v.tex.t = texCube[i * 2 + 1]; v.normal.x = normalCube2[i * 3 + 0];
v.normal.y = normalCube2[i * 3 + 1];
v.normal.z = normalCube2[i * 3 + 2];
eboBuffers.push_back(v);
} glGenVertexArrays(1, &vao);
glBindVertexArray(vao); glGenBuffers(1, &vbo0);
glBindBuffer(GL_ARRAY_BUFFER, vbo0); glBufferData(GL_ARRAY_BUFFER, eboBuffers.size()* sizeof(MyVertex), eboBuffers.data(), GL_STATIC_DRAW);
int stride = sizeof(MyVertex);
glEnableVertexAttribArray(0); //根据属性数量来顶,这里开启三个 0 1 2
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (GLvoid*)offsetof(MyVertex, pos));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, stride, (GLvoid*)offsetof(MyVertex, tex));
glVertexAttribPointer(2, 3, GL_FLOAT, GL_TRUE, stride, (GLvoid*)offsetof(MyVertex, normal));
VAO绘制:
glBindVertexArray(vao);
glDrawArrays(GL_QUADS, first, count); //第一个是起始位置,第二个是顶点数量
EBO的绘制:
ebo的好处是可以省大量的内存,只需要调用顶点所在的索引(id)即可完成绘制,因为
在有了vao,vbo的申请以及他们的内存关联之后,ebo开始工作。
ebo绘制有两种方式
1)先申请在绘制
//申请:
glGenBuffers(1, &eboId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eboId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(GLubyte), vIdx, GL_STATIC_DRAW); //vidx 即绘制索引数组 GLubyte vIdx[] = { 0,1,2,1,2,3 }; //绘制:
glBindVertexArray(vao);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, eboId);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_BYTE, 0); //最后一个参数是0,因为已经绑定了vao,ebo
2. 直接使用数组
//清除已绑定的ebo
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, count, GL_UNSIGNED_BYTE, vIdx); //传入索引数组内存以及顶点数量
最后绘制在Shader中的展示(ebo,vbo调用均一样): Normal2,Normal3,Normal4 是用来测试顶点属性数量用的,支持6个属性没问题
uniform mat4 proj;
uniform mat4 view;
uniform mat4 model; layout (location = 0) in vec3 Position; //layout (locatiopn=0)一定要写,否则识别会出问题
layout (location = 1) in vec2 Texcoord;
layout (location = 2) in vec3 Normal;
layout (location = 3) in vec3 Normal2;
layout (location = 4) in vec3 Normal3;
layout (location = 5) in vec3 Normal4; out vec3 Color; void main()
{ Color = Normal4;
gl_Position = proj * view *model* vec4(Position,1);
}
OpenGL 4.0中数据缓冲VBO,VAO,EBO的使用总结的更多相关文章
- OpenGL 4.0 GLSL 基础教程概览——VAO和VBO常用操作接口
(一) OpenGL 4.3 最新渲染管线图 从OpenGL 2.0 到 OpenGL 3.0变化非常大,但从OpenGL 3.0 到OpenGL 4.0 变化不是太大. 着色器程序直接运行在GPU ...
- LearnOpenGL学习笔记(三)——VBO,VAO,EBO理解
在opengl中所有的数据都要放在显存中,我们通过一定的手段去管理它,既要提供地方存放它,还要提供方法去正确地提取它们,去使用它们,opengl通过VAO,VBO,EBO这些手段来解决这些问题. (一 ...
- yii2.0中数据缓存之增删改查
public function actionSss(){ /* * 获取到缓存 * 这里是获取的是根目录下 的common/main.php中的缓存类组件 * */ $cache=\Yii::$app ...
- 解决EF 4.0 中数据缓存机制
EF4.0默认开启缓存机制,如果想要禁用缓存机制的话,则须加上一句话:_db.CreateObjectSet().MergeOption = MergeOption.OverwriteChanges; ...
- yii2.0 中数据查询中 or、in、between 及session的使用
1 HTML: 2 3 <div> 4 <form class="form-inline " method="get" action=&quo ...
- libevent中数据缓冲区buffer分析
很多时候为了应对数据IO的"慢"或者其他原因都需要使用数据缓冲区.对于数据缓冲,我们不陌生,但是对于如何实现这个缓冲区,相信很多时候大家都没有考虑过.今天就通过分析libevent ...
- OpenGL中VA,VAO,VBO和EBO的区别
1,顶点数组(Vertex Array) VA,顶点数组也是收集好所有的顶点,一次性发送给GPU.不过数据不是存储于GPU中的,绘制速度上没有显示列表快,优点是可以修改数据. 4.VBO(Vertex ...
- Cocos2d-x中使用OpenGL ES2.0编写shader
这几天在看子龙山人的关于OpenGL的文章,先依葫芦画瓢,能看到些东西,才能慢慢深入了解,当入门文章不错,但是其中遇到的一些问题,折腾了一些时间,为了方便和我一样的小白们,在这篇文章中进行写补充. O ...
- OpenGL ES 2: debugging, and improvements to VAO, VBO
OpenGL ES 2: debugging, and improvements to VAO, VBO http://www.altdevblogaday.com/2013/10/12/opengl ...
- unix中数据缓冲区高速缓冲的设计
目录 1. 概述 2. 缓冲区的设计 2.1 缓冲区头部 2.2 缓冲区的结构 2.3 缓冲区的检索算法 2.3. 申请一个缓冲区算法 getblk 2.3.2 释放一个缓冲区算法 brelse 2. ...
随机推荐
- Android 12(S) Binder(三)
学以致用,这一节来native binder实战! android 12中的service用到的Bp.Bn文件多由aidl生成,所以实战中也用aidl来生成. 1.文件目录结构 文件目录结构如上,偷懒 ...
- NOIP模拟96
T1 树上排列 解题思路 是一个一眼切的题目... 看到题目第一眼就是 Deepinc 学长讲的可重集,无序 Hash . 直接套上一颗线段树再加上树剖, \(nlog^2n\) 直接过,好像也可以树 ...
- chrome edge CORS 允许跨域
edge: edge://flags/#block-insecure-private-network-requests chrome: 在谷歌浏览器地址栏输入"chrome://flags/ ...
- C#.NET Framework 使用BC库(BouncyCastle) RSA 私钥签名 公钥验签(验证签名) ver:20230704
C#.NET Framework 使用BC库(BouncyCastle) RSA 私钥签名 公钥验签(验证签名) ver:20230704 环境说明: .NET Framework 4.6 的控制台程 ...
- C#中路径说明
路径中一个点和两个点的区别 ./ 表示当前目录,如"./jquery-1.3.2.min.js",也可以去掉"./",如"jquery-1.3. ...
- zabbix-agent修改主动模式
1.zabbix-agent工作模式 zabbix-agent进程,有两种工作模式,主动模式,被动视频 1.1 被动模式 被动模式是指 zabbix-server 将需要请求的数据,发给zabbix- ...
- 增补博客 第六篇 python 电子算盘
珠算测试器 题目描述]设计一个珠算测试器,要求能够完成珠算加减法的测试.具体的要求功能如下:(1)用户启动测试,输入用户名后系统随机生成特定数目的加减法测试题:(2) 要求测试使用表盘式或数字时秒表进 ...
- python globals()[]将字符串转化类,并通过反射执行方法
背景: 通过关键字设计ui自动化框架,将测试用例及其步骤存放到excel文件:其中步骤中包含了封装好的关键字方法,如打开浏览器.输入页面操作等,关键字保存的内容:具体类实例.方法 通过excel获取到 ...
- Linux中的inode
inode是什么 一个文件由两部分组成:元信息和数据. 在Linux中,inode包含文件的元信息,具体来说有以下内容: Size 文件的字节数 Uid 文件拥有者的User ID Gid 文件的Gr ...
- ClickHouse介绍(二)MergeTree引擎
MergeTree引擎 ClickHouse中有多种表引擎,包括MergeTree.外部存储.内存.文件.接口等,6大类,20多种表引擎.其中最强大的当属MergeTree(及其同一家族中)引擎.我们 ...