思路
可以观察到灵魂出窍的效果,其实其主图像本没有什么变化,只是新增了一张进行缩放的纹理,跟主图像的alpha进行线性融合的。
怎么去取灵魂呢,灵魂是跟着视频所播放的内容不断更新的,不可能一直只是同一个图像。所以这里的思路是每X帧拷贝一帧作为灵魂,然后将灵魂按比例放大,最后将灵魂与主图像进行混合。
实现
因为视频录制出来的是YUV格式的数据,但是在OpenGL中是需要的RGB颜色,所以需要将YUV格式的数据转化成RGB格式的,这里需要将YUV格式的数据进行分离之后,再转换。转换是有公式的,用公式进行计算就好啦。

渲染主图像
首先就是获取索引,然后创建Y、U、V三个纹理,分别进行传值,然后先画主图像,不进行任何的缩放平移。

上面代码就是首先将主图像的YUV数据进行分离,分离YUV就不介绍了,比较简单,然后设置setIdentityM设置一个单位矩阵,这个矩阵是没有任何缩放平移效果的。这个方法的源码是

这个矩阵需要个传入的4个顶点坐标进行运算,为什么这样的单位矩阵就是没有任何效果的呢,可以来进行矩阵运算一下,输入顶点坐标为(1,1,0,0)的话,与矩阵运算之后的结果还是(1,1,0,0)

设置完需要的矩阵,YUV三个纹理,就需要将这些顶点,YUV纹理传递给着色器就可以了。这个里就看一下Y数据的传递,UV数据传递也是一样的。

渲染灵魂
因为灵魂出窍这个效果,灵魂是不断的更新放大,所以我们这里是采用了间隔X帧拷贝一帧作为灵魂。

网友评论