2DCanvas的webgl context提供了一组接口 texImage2D()用于将不同类型的源作为材质渲染到指定texture上。这些不同类型的源包括:
ArrayBufferView, ImageData,
HTMLImageElement,HTMLCanvasElement, HTMLVideoElement
这篇博客分析HTMLVideoElement作为源渲染到指定texture的实现过程。
也就是下面这个接口的具体实现,
WebGLRenderingContextBase::texImage2D(...,HTMLVideoElement,textureid,...)。
整个过程可以分成3个步骤:
步骤1.承载video内容的texture创建的过程;
步骤2:包含video内容的texture与video视频流关联的过程;
步骤3:包含video内容的texture被绘制到指定texture的过程;
下面分别看这三个步骤:
步骤1.承载video内容的texture创建的过程;
这个过程主要做三件事情:
1).创建承载video内容的texture,图中路径1标示的过程;
2).创建SurfaceTexture封装1)中的texture,图中路径2标示的过程,SurfaceTexture会在步骤2中关联到android mediaplayer上,这样mediaplayer的输出目标就变成了SurfaceTexture封装的texture;
3).将1)中创建的承载video内容的texture封装进mailbox.在另一个gl线程绘制video texture到指定texture时,会通过mailbox取得video texture,图中路径3标示的过程.
步骤2:包含video内容的texture与video视频流关联的过程
参照http://blog.csdn.net/jaylinzhou/article/details/51722363中关于surfacetexture类的说明,使用SurfaceTexture类就是为了改变MediaPlayer的输出目的地。封装了video texture的SurfaceTextrue与MediaPlayer绑定的过程如下图:
步骤3:包含video内容的texture被消费的过程
这个过程分三个小步骤完成:
1)在绘制线程根据命名的mailbox取出video texture;
2)更新video texture的内容为最新;
3)video texture绘制到指定的目标texture;
video texture绘制到指定目标texture的过程是通过如下三个gl指令完成的:
3.1)目标texture作为framebuffer的后端存储attach到framebuffer上;
glFramebufferTexture2DEXT();
3.2)绑定video texture;
glBindTexture(source_target, source_id);
3.3)绘制video texture到framebuffer上,由于framebuffer绑定了目标texture,这样,video texture就绘制到了目标textrure上;
glDrawArrays(GL_TRIANGLE_FAN,0, 4);