Skip to content

Commit 6825cb1

Browse files
committed
update OpenGL
1 parent df6b256 commit 6825cb1

File tree

5 files changed

+133
-0
lines changed

5 files changed

+133
-0
lines changed

VideoDevelopment/.DS_Store

6 KB
Binary file not shown.

VideoDevelopment/Android音视频开发/1.音视频基础知识.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,19 @@ U和V不是基础信号,他俩都是被正交调制的。早期的电视都是
266266

267267
YUV和RGB视频信号相比,最大的优点在于只需要占用极少的带宽,YUV只需要占用RGB一般的带宽。
268268

269+
270+
YUV 色彩编码模型,其设计初衷为了解决彩色电视机与黑白电视的兼容问题,利用了人类眼睛的生理特性(对亮度敏感,对色度不敏感),允许降低色度的带宽,降低了传输带宽。
271+
272+
在计算机系统中应用尤为广泛,利用 YUV 色彩编码模型可以降低图片数据的内存占用,YUV只需要占用RGB一般的带宽,从而提高数据处理效率。
273+
274+
另外,YUV 编码模型的图像数据一般不能直接用于显示,还需要将其转换为 RGB(RGBA) 编码模型,才能够正常显示图像。
275+
276+
277+
————————————————
278+
版权声明:本文为CSDN博主「字节流动」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
279+
原文链接:https://blog.csdn.net/Kennethdroid/article/details/94031821
280+
281+
269282
YUV码流的存储格式其实与其采样的方式密切相关,主流的采样方式有四种,
270283
- YUV 4:4:4
271284
YUV三个信道的抽样率相同,因此在生成的图像里,每个象素的三个分量信息完整(每个分量通常8比特),经过8比特量化之后,未经压缩的每个像素占用3个字节。

VideoDevelopment/OpenGL/1.OpenGL简介.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,13 @@ OpenGL ES 3.0实现了具有可编程着色功能的图形管线,有两个规
8888
顶点着色器会在GPU上创建内存用于存储我们的顶点数据,还要配置OpenGL如何解释这些内存,并且指定其如何发送给显卡。顶点着色器接着会处理我们在内存中指定数量的顶点。
8989
我们通过顶点缓冲对象(Vertex Buffer Object, VBO)管理这个内存,它会在GPU内存(通常被称为显存)中储存大量顶点。使用这些缓冲对象的好处是我们可以一次性的发送一大批数据到显卡上,而不是每个顶点发送一次。从CPU把数据发送到显卡相对较慢,所以只要可能我们都尝试尽量一次性发送尽可能多的数据。当数据发送至显卡的内存中后,顶点着色器几乎能立即访问顶点,这个是非常快的过程。
9090

91+
OpenGLES2.0 编程中,用于绘制的顶点数组数据首先保存在 CPU 内存,在调用 glDrawArrays 或者 glDrawElements 等进行绘制时,需要将顶点数组数据从 CPU 内存拷贝到显存。
92+
93+
但是很多时候我们没必要每次绘制的时候都去进行内存拷贝,如果可以在显存中缓存这些数据,就可以在很大程度上降低内存拷贝带来的开销。
94+
95+
OpenGLES3.0 VBO 和 EBO 的出现就是为了解决这个问题。 VBO 和 EBO 的作用是在显存中提前开辟好一块内存,用于缓存顶点数据或者图元索引数据,从而避免每次绘制时的 CPU 与 GPU 之间的内存拷贝,可以提升渲染性能,降低内存带宽和功耗。
96+
97+
9198
顶点缓冲对象是OpenGL中的一个对象,就像OpenGL中的其它对象一样,这个缓冲有一个独一无二的ID,所以我们可以使用glGenBuffers()函数和一个缓冲ID生成一个VBO对象:
9299
```java
93100
// 下面只生成一个vbo对象,所以vbo的容量设置为1即可
@@ -256,6 +263,27 @@ EGL提供了OpenGL ES和运行于计算机上的原生窗口系统(如Windows、
256263
EGL能够确定可用的绘制表面类型(或者底层系统的其他特性)之前,它必须打开和窗口系统的通信渠道。注意。Apple提供自己的EGL API的iOS实现,成为EAGL
257264
因为每个窗口系统都有不同的语言,所以EGL提供基本的不透明类型--EGLDisplay,该类型封装了所有系统相关性,用于和原生窗口系统接口。任何使用EGL的应用程序必须执行的第一个操作就是创建和初始化与本地EGL显示的连接。
258265

266+
EGLOpenGL ES 和本地窗口系统(Native Window System)之间的通信接口,它的主要作用:
267+
268+
- 与设备的原生窗口系统通信;
269+
- 查询绘图表面的可用类型和配置;
270+
- 创建绘图表面;
271+
-OpenGL ES 和其他图形渲染API之间同步渲染;
272+
- 管理纹理贴图等渲染资源。
273+
OpenGL ES 的平台无关性正是借助 EGL 实现的,EGL 屏蔽了不同平台的差异(Apple 提供了自己的 EGL API 的 iOS 实现,自称 EAGL)。
274+
275+
![image](https://raw.githubusercontent.com/CharonChui/Pictures/master/egl_interface_1.png?raw=true)
276+
上图中:
277+
- Display(EGLDisplay) 是对实际显示设备的抽象;
278+
- SurfaceEGLSurface)是对用来存储图像的内存区域 FrameBuffer 的抽象,包括 Color Buffer(颜色缓冲区), Stencil Buffer(模板缓冲区) ,Depth Buffer(深度缓冲区);
279+
- Context (EGLContext) 存储 OpenGL ES 绘图的一些状态信息;
280+
Android 平台上开发 OpenGL ES 应用时,类 GLSurfaceView 已经为我们提供了对 Display , Surface , Context 的管理,即 GLSurfaceView 内部实现了对 EGL 的封装,可以很方便地利用接口 GLSurfaceView.Renderer 的实现,使用 OpenGL ES API 进行渲染绘制,很大程度上提升了 OpenGLES 开发的便利性。
281+
282+
283+
284+
285+
本地窗口相关的 API 提供了访问本地窗口系统的接口,而 EGL 可以创建渲染表面 EGLSurface ,同时提供了图形渲染上下文 EGLContext,用来进行状态管理,接下来 OpenGL ES 就可以在这个渲染表面上绘制。
286+
259287

260288
EGL为双缓冲工作模式(Double Buffer),既有一个Back Frame Buffer和一个Front Frame Buffer,正常绘制的目标都是Back Frame Buffer,绘制完成后再调用eglSwapBuffer API,将绘制完毕的FrameBuffer交换到Front Frame Buffer并显示出来。
261289

VideoDevelopment/OpenGL/12.FBO.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
## 12.FBO
2+
3+
FBO(Frame Buffer Object)即帧缓冲区对象,实际上是一个可添加缓冲区的容器,可以为其添加纹理或渲染缓冲区对象(RBO)。
4+
5+
FBO 本身不能用于渲染,只有添加了纹理或者渲染缓冲区之后才能作为渲染目标,它仅且提供了 3 种附着(Attachment),分别是颜色附着、深度附着和模板附着。
6+
7+
RBO(Render Buffer Object)即渲染缓冲区对象,是一个由应用程序分配的 2D 图像缓冲区。渲染缓冲区可以用于分配和存储颜色、深度或者模板值,可以用作 FBO 中的颜色、深度或者模板附着。
8+
9+
使用 FBO 作为渲染目标时,首先需要为 FBO 的附着添加连接对象,如颜色附着需要连接纹理或者渲染缓冲区对象的颜色缓冲区。
10+
11+
12+
#### 为什么用 FBO
13+
14+
默认情况下,OpenGL ES 通过绘制到窗口系统提供的帧缓冲区,然后将帧缓冲区的对应区域复制到纹理来实现渲染到纹理,但是此方法只有在纹理尺寸小于或等于帧缓冲区尺寸才有效。
15+
16+
另一种方式是通过使用连接到纹理的 pbuffer 来实现渲染到纹理,但是与上下文和窗口系统提供的可绘制表面切换开销也很大。因此,引入了帧缓冲区对象 FBO 来解决这个问题。
17+
18+
Android OpenGL ES 开发中,一般使用 GLSurfaceView 将绘制结果显示到屏幕上,然而在实际应用中,也有许多场景不需要渲染到屏幕上,如利用 GPU 在后台完成一些图像转换、缩放等耗时操作,这个时候利用 FBO 可以方便实现类似需求。
19+
20+
使用 FBO 可以让渲染操作不用再渲染到屏幕上,而是渲染到离屏 Buffer 中,然后可以使用 glReadPixels 或者 HardwareBuffer 将渲染后的图像数据读出来,从而实现在后台利用 GPU 完成对图像的处理。
21+
22+
23+
24+
25+
[上一篇: 10.GLSurfaceView+MediaPlayer播放视频](https://github.com/CharonChui/AndroidNote/blob/master/VideoDevelopment/OpenGL/10.GLSurfaceView%2BMediaPlayer%E6%92%AD%E6%94%BE%E8%A7%86%E9%A2%91.md)
26+
27+
---
28+
29+
- 邮箱 :charon.chui@gmail.com
30+
- Good Luck!
31+
32+
33+
34+
35+
36+
37+
38+
39+
40+
41+
42+
43+
44+
45+
46+
47+
48+
49+
50+
51+
52+
53+
54+
55+
56+
57+
58+
59+
60+
61+

VideoDevelopment/OpenGL/9.OpenGL ES纹理.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,37 @@ OpenGL中,2D纹理也有自己的坐标体系,取值范围在(0,0)到(1,1)
3030

3131
![](https://raw.githubusercontent.com/CharonChui/Pictures/master/opengl_es_texture_position.jpg)
3232

33+
34+
在 OpenGL 中,纹理实际上是一个可以被采样的复杂数据集合,是 GPU 使用的图像数据结构,纹理分为 2D 纹理、 立方图纹理和 3D 纹理。
35+
36+
2D 纹理是 OpenGLES 中最常用和最常见的纹理形式,是一个图像数据的二维数组。纹理中的一个单独数据元素称为纹素或纹理像素。
37+
38+
立方图纹理是一个由 6 个单独的纹理面组成的纹理。立方图纹理像素的读取通过使用一个三维坐标(s,t,r)作为纹理坐标。
39+
40+
3D 纹理可以看作 2D 纹理作为切面的一个数组,类似于立方图纹理,使用三维坐标对其进行访问。
41+
42+
43+
在 OpenGLES 中,纹理映射就是通过为图元的顶点坐标指定恰当的纹理坐标,通过纹理坐标在纹理图中选定特定的纹理区域,最后通过纹理坐标与顶点的映射关系,将选定的纹理区域映射到指定图元上。
44+
45+
纹理映射也称为纹理贴图,简单地说就是将纹理坐标(纹理坐标系)所指定的纹理区域,映射到顶点坐标(渲染坐标系或OpenGLES 坐标系)对应的区域。
46+
47+
纹理坐标系:
48+
![](https://raw.githubusercontent.com/CharonChui/Pictures/master/texture_st_1.png)
49+
渲染坐标系或OpenGLES 坐标系:
50+
![](https://raw.githubusercontent.com/CharonChui/Pictures/master/texture_st_2.png)
51+
4 个纹理坐标分别为
52+
T0(0,0),T1(0,1),T2(1,1),T3(1,0)。
53+
4 个纹理坐标对于的顶点坐标分别为
54+
V0(-1,0.5),V1(-1, -0.5),V2(1,-0.5),V3(1,0.5)
55+
由于 OpenGLES 绘制是以三角形为单位的,设置绘制的 2 个三角形为 V0V1V2 和 V0V2V3 。
56+
当我们调整纹理坐标的顺序顶点坐标顺序不变,如 T0T1T2T3 -> T1T2T3T0 ,绘制后将得到一个顺时针旋转 90 度的纹理贴图。所以调整纹理坐标和顶点坐标的对应关系可以实现纹理图简单的旋转。
57+
58+
59+
60+
61+
62+
63+
3364
### 文件读取
3465

3566
OpenGL不能直接加载jpg或者png这类被编码的压缩格式,需要加载原始数据,也就是bitmap。我们在内置图片到工程中,应该将图片放到drawable-nodpi中,避免读取时被压缩,通过BitmapFactory解码读取图片时,要设置为非缩放的方式,即options.isScaled=false。

0 commit comments

Comments
 (0)