GPUImage源码解析 -- GLProgram

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GPUImage源码解析 -- GLProgram相关的知识,希望对你有一定的参考价值。

参考技术A GPUImage的核心是图片的处理和渲染,而这个过程主要是由OpenGL ES实现的。但是OpenGL ES是一个C API的集合,用起来非常不方便。GLProgram就提供了一个建立OpenGL ES program的面向对象封装。

一个OpenGL ES Program的创建过程主要分为以下步骤

在OpenGL中,对于同一个Program的渲染必须发生在同一个EGLContext上。所以在整个OpenGL渲染过程中,我们需要先创建一个EGLContext并设置为currentContext。

ios中,创建EGLContext相对比较容易,因为已经有一个系统自带的EAGLContext类将EGL都封装好了,只需要调用其initializer并且将这个Context设置成 currentContext 即可:

而在安卓中,则创建Context要麻烦许多。因为安卓要求所有的渲染必须发生在同一个Context以及同一个线程中。如果不使用默认的GLSurfaceView进行渲染的话,则需要更复杂的创建Context的过程:

创建 GLProgram 包括了上述的步骤2-步骤5。 GLProgram 的initializer有多个:

其实他们最终都是传入了两个参数,即Vertex Shader以及Fragment Shader。有了这两个Shader之后,我们就可以开始创建OpenGL ES的Program了。

创建并且compile shader的过程包括几步:

在GPUImage中,实际上attribute的index并不是真正从program中获取到的,而是直接通过默认的顺序进行排序的。因为我们可以真正通过使用 glBindAttribLocation 和 glEnableVertexAttribArray 来控制每个Attribute的位置。

因此,如果需要写一个Filter的子类,需要先调用父类中的addAttributes方法,才能够保证正确的Attribute index。

在GPUImageFilter中,有两个attributes的位置是固定的:

在OpenGL ES中,uniform的位置并不是固定的,必须在Program link完成之后才能够获得,因此,获取uniform的位置必须通过以下命令:

由于在渲染过程中,很可能添加了多个Program,因此,很可能出现的情况就是需要在不同的Program之间进行切换。切换的命令很简单:

一旦调用了这个方法,就会将当前的program设置为正在使用中的,然后进行渲染。

由于GPUImage默认是进行图片处理,其实它的VertexShader就相对简单很多,因此,GPUImage提供了一个默认的VertexShader:

同时,也提供了一个不进行任何像素操作的PassThrough FragmentShader:

GLProgram主要是提供了对OpenGL ES program创建以及使用的面向对象化封装。真正进行渲染的Shader都是由不同的Filter自己提供的。在了解了GLProgram之后,我们就可以开始正式进入主题GPUImageFilter了。

GPUImage学习笔记

不定期更新,详情请参阅云笔记

http://note.youdao.com/noteshare?id=d6562c5aa0741d2bb7436d7890d96ae2

 

 

2017.3.2
工程里面的app->GLCameraInstaller可以直接使用。欢迎大家学习。
初步认识GLSurfaceView预览摄像头。然后就出现很多问题:
第一个问题就是 setRotationCamera 接口的flipVertical, flipHorizontal两个方向的翻转标识,为什么要互换?即以下关键代码:
private void setRotation(Rotation rotation,
boolean flipVertical, boolean flipHorizontal) {
mRotation = rotation;
//mFlipHorizontal = flipHorizontal;
//mFlipVertical = flipVertical;
mFlipVertical = flipHorizontal;
mFlipHorizontal = flipVertical;
adjustImageScaling();
}
之前复刻的时候,是使用注释的那部分,这样在切换前置摄像头的时候就会上下颠倒。后置没有异常
 
慢慢回想起Camera的三个方向,摄像头预览观察方向,拍照成像的方向,还是就是预览接口onPreviewFrame的data方向,即原生的每一帧数据的方向
首先第一个摄像头预览方向是用Camera.setDisplayOrientation方法是设置摄像头预览的方向
第二个拍照成像的方向,使用的是Camera.Parameters类的setRotation方法
至于第三个方向,是没有方法设置的,只能是每帧自己处理。
 
通过以上关联,我查看了代码,发现GPUImage是没有调用以上所说的任何方向的方法。我觉得就是摄像头预览方向这个原因,致使flipVertical, flipHorizontal互换了。至于怎么工作,且听下回分解。

以上是关于GPUImage源码解析 -- GLProgram的主要内容,如果未能解决你的问题,请参考以下文章

GPUImage 源码分析

GPUImage 源码分析

GPUImage学习笔记

IOS OpenGL ES GPUImage GPUImageWeakPixelInclusionFilter

IOS OpenGL ES GPUImage 彩色模糊 GPUImageRGBOpeningFilter

IOS OpenGL ES GPUImage 图像叠加 GPUImageOverlayBlendFilter