新闻中心

一看就懂的OpenGL ES教程——缓冲对象优化程序(一)

2024-03-12 13:25:15
浏览次数:
返回列表

本文为稀土掘金技术社区首发签约文章,14天内禁止转载,14天后未获授权禁止转载,侵权必究!

通过阅读本文,你将获得以下收获:
1.Opengl常见的缓冲对象
2.如何使用Vertex Buffer Objects(VBO)优化程序

上一篇博文一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(五) 已经完成了绘制渐变色三角形的任务,这条路虽然漫长(5篇博文)但也算是一马平川,浩浩荡荡。经过前面的洗礼,相信你一定已经可以理解如何使用OpenGL es绘制一个渐变色的三角形了吧,那么恭喜你,此时你已经翻过了入门的第一座大山。

本文就不继续翻山越岭了,而是讲一些优化性的内容,当然虽然不是什么大山,但也不代表内容就简单。

image.png

首先要谈的一个东西是OpenGL对象,这是一个怎样的对象呢? 官网# OpenGL Object 给出了定义:

An?OpenGL Object?is an OpenGL construct that contains some state. When they are bound to the context, the state that they contain is mapped into the context's state. Thus, changes to context state will be stored in this object, and functions that act on this context state will use the state stored in the object.

OpenGL is defined as a "state machine". The various API calls change the OpenGL state, query some part of that state, or cause OpenGL to use its current state to render something.

Objects are always containers for state. Each particular kind of object is defined by the particular state that it contains. An OpenGL object is a way to encapsulate a particular group of state and change all of it in one function call.

提取重点: 之前在一看就懂的OpenGL ES教程——再谈OpenGL工作机制我们讲过OpenGL是一个状态机,在这里。它是一个包含各种状态的结构体,它会与OpenGL的上下文(一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(一)已有提及过)进行绑定,并将。

怎么理解这句话呢,别急,后面等我献上代码之后,你们一定能理解~

OpenGL对象包含2类,一种是,一种是。

常规对象有:

容器对象有:

对于目前的我们来说也不需要这么多“对象”吧。

d39195ed273b9167d6044d9a0ed750f7.jpeg

下面挑来讲讲。

今天要聊的一种对象,叫做。缓冲对于大家应该都很熟悉了吧,我们做软件开发的经常说在内存汇总开辟一段缓冲区,那么。再通俗来讲,打个比方,比如我们要去用水冲洗楼梯,没有缓冲的时候,我们就要一次次跑到家里面舀一盆水再跑到楼梯去冲,但是有了大的木桶装水,我们只要装满木桶的水,再把大木桶带到楼梯去,再从大木桶中舀水去冲洗楼梯,那会省很多成本,那么。

一看就懂的OpenGL ES教程——再谈OpenGL工作机制一文中就说过,OpenGL的,而我们的,所以这里必然需要在。

首先要说的就是,虽然现在的cpu和gpu一般都是集成主板上,在宏观上它们之间的物理距离对于电子来说传输时间几乎可以忽略不计,但是当有,缓冲的出现就势在必行。

常大量的数据需要非常频繁地在cpu和gpu之间穿梭的场景,大家最熟悉的莫过于了。

具体例子,比如在绘制三角形的系列中,我们每次都是通过方法将顶点数据从cpu传输给gpu的,看起来9个浮点数也没什么,但是如果我们需要绘制一段视频,,那就有点刺激了。

b83b71a14cd3b00ccb7b92ead9f852bd.jpeg

对于高级程序员来说,看到这种情况都是条件反射地思考如何减少传输成本,那么第一个能想到的就是缓冲了。 所以。

一句话,就回答了上面和的问题。

24ea28a2e565c4ed50853f0e57794884.jpeg

在OpenGL的世界中,有几种常见缓冲也是起着类似的作用,它们分别是(Vertex Buffer Objects),Vertex Array Objects,(Element Buffer Object)以及(Framebuffer Objects)等等。

由于对于现在来说,所以留在后面讲完再讲,今天主要讲。

缓冲对象又各自缓冲不同的东西,上面已经有列举常见的缓冲种类了,有一类,比如,,它们属于- Buffer Objects。而有一类,比如,它就是上面说的Vertex Array Objects这种。那么接下来,就让我们来细细品味这三者的详情和用法。

先来看看Buffer Objects。

官网Buffer Object 中的定义是:

Buffer Objects?are?OpenGL Objects?that store an array of unformatted memory allocated by the OpenGL context (AKA the GPU). These can be used to store?vertex data,?pixel data retrieved from images or the framebuffer, and a?variety of other things.

最关键的就是它是。

这玩意儿玩起来有固定的套路:


反映到代码里就是:


关于代码,主要关注3点:
1.创建的时候通过,常见的有以下种类:

,,,等,其中,。

2.通过。这里涉及到的就是OpenGL状态机的概念,最重要的就是要知道,也是上面已经提及过的,,

3.通过将数据存储在缓冲区中,关于这个函数,还是需要啰嗦几句讲讲。

函数声明为(官网):


表示对应的具体的Buffer Objects种类,即上面列举的GL_ARRAY_BUFFER和GL_ELEMENT_ARRAY_BUFFER这些。

表示传入的数据长度。

就是具体的数据的指针。

指定数据的访问模式,模式可选值有,?,?,?,?,?,?,?, or?。

我们最常用的就是指定,即告诉OpenGL我们对数据的修改频率,目的是为了让。

访问频率模式有以下几个:

  • :数据几乎每次被访问都会被修改。

  • :数据只被修改一次。

  • :数据会被修改多次。

52cac471e20453d76ea471a5dfc406ca.jpeg

像上面的例子,一帧需要渲染假如1万个三角形,帧率为30,那么即一秒中要传输90万个浮点数。那么,按照上面缓冲对象的解释,?假如渲染的图形都是不动的话(实际上即使需要变动,顶点数据也可以是固定的),那么其实,即第一帧传递顶点数据即可,假如绘制每帧1万个三角形的话,那么。

那么,即,顾名思义,就是为了解决这种场景而诞生的。

VBO的使用代码:


很多人一开始看到类似glBindXX的代码会懵逼,这个方面主要要理解OpenGL状态机的概念,详细的已经在(一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(一)阐述过,总的来说,当调用了glBindXX指令之后,,直到调用了对应的解绑方法。在这中间的所有调用都是的(貌似已经说了很多遍了。。)。

那么在VBO的使用中,可以理解为执行了
之后,后面的glBufferData和glVertexAttribPointer等包括绘制都是,所以注意到方法最后一个参数传的是,而不是之前的数组。

这里可以这么理解:

之前是
cpu告诉gpu说:“哥们,物理内存中地址为xx的xx数组你拿去用”

现在是
cpu先把数组数据传送到gpu中的vbo缓冲区了,然后调用方法的时候对gpu说:“哥们,你要怎么怎么使用你里面的vbo中xx地址的数据……”

顶点着色器:


片段着色器:


那么如果顶点属性不止一个属性呢?比如还是增加一个颜色属性。

代码只要微调下即可:

顶点属性数组改为:


解析数据逻辑增加2行解析第二个属性:


这里要注意的就是解析第二个属性的时候,要,其实也是,因为第二个属性是从第4个元素开始的,即便偏移了3个浮点数元素,所以地址指针是

顶点着色器:


片段着色器:


在平时的使用中,其实一般只需要配置一次VBO,后面可以调用很多次绘制VBO里的顶点数据,那么可以将:

配置代码:


绘制代码:


想象在播放视频,后面的绘制代码可是一秒要绘制几十次的,这样就可以看出VBO是如何优化性能的,因为。

运行一看,又是熟悉的老朋友了,。

image.png

本文主要介绍了OpenGL对象以及其中的缓冲对象,重点介绍了其中的VBO的作用和使用方法。介于篇幅有限,剩下的缓冲对象内容就放在下一篇继续介绍,感谢大家的支持和关注。

a20241bc1722029d6929b0dd299e1731.jpeg

opengl-es-study-demo (不断更新中)

OpenGL Object
Buffer Object
应该怎么理解 OpenGL 的 VAO 与 VBO
熟悉 OpenGL VAO、VBO、FBO、PBO 等对象,看这一篇就够了

原创不易,如果觉得本文对自己有帮助,别忘了随手点赞和关注,这也是我创作的最大动力~

体系化学习系列博文,请看音视频系统学习的浪漫马车之总目录

实践项目: 介绍一个自己刚出炉的安卓音视频播放录制开源项目

C/C++基础与进阶之路

音视频理论基础系列专栏

音视频开发实战系列专栏

轻松入门OpenGL系列
一看就懂的OpenGL ES教程——图形渲染管线的那些事
一看就懂的OpenGL ES教程——再谈OpenGL工作机制
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(一)
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(二)
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(三)
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(四)
一看就懂的OpenGL ES教程——这或许是你遇过最难画的三角形(五)
一看就懂的OpenGL ES教程——缓冲对象优化程序(一)
一看就懂的OpenGL ES教程——缓冲对象优化程序(二)
一看就懂的OpenGL ES教程——临摹画手的浪漫之纹理映射(理论篇)

平台注册入口