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
github源码地址,https://github.com/MrZhaozhirong/GPUImage
工程里面的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的主要内容,如果未能解决你的问题,请参考以下文章
IOS OpenGL ES GPUImage GPUImageWeakPixelInclusionFilter