本文主要说明GLTextureView,一个代替GLSurfaceView的自定义View。将会说明包括GLTextureView的优点,大致实现方式,以及使用。
一如既往地放项目地址:
android-openGL-canvas
本文相关的代码:
BaseGLTextureView
优点
其实Android官方在Android 4.0以后推出TextureView,本意就是想代替GLSurfaceView。可是TextureView在里面并没有像GLSurfaceView那样封装好一个绘制线程以及OpenGL的初始化。所以GLTextureView将会实现这些部分。
GLTextureView的优点其实也包括TextureView的优点,在官方文档里也有说明: TextureView 不会创建一个分离的window,而是像一个普通的view那样显示, 这样就不会像GLSurfaceView那样,要么在所有View上方,要么被其它View遮住(看 setZOrderOnTop(boolean) 的说明)。而且像myView.setAlpha(0.5f)这种方法调用后也会有效果了。
实现方式
实现需要使用GLThread,这是由GLSurfaceView.GLThread改造过来的类,关于这个类的说明请看
如何封装 opengl 流程 -- 以为android-opengl-canvas例
利用GLThread,实现过程就变得很简单了,以下是关键代码:
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
...
glThreadBuilder.setRenderMode(getRenderMode())
.setSurface(surface)
.setRenderer(renderer);
...
}
...
mGLThread = glThreadBuilder.createGLThread();
mGLThread.start();
...
mGLThread.surfaceCreated();
mGLThread.onWindowResize(w, h);
...
public void requestRender() {
if (mGLThread != null) {
mGLThread.requestRender();
}
}
可以看到,主要就是先实现TextureView.SurfaceTextureListener,然后在onSurfaceTextureAvailable时创建GLThread,传入自己的SurfaceTexture用于承载绘制的内容,就基本可以了。
以上代码里的setRenderer,就实现了像GLSurfaceView那样使用Renderer就可以实现绘制了。
剩下的就是流程控制的代码了。
public void onPause() {
if (mGLThread != null) {
mGLThread.onPause();
}
}
public void onResume() {
if (mGLThread != null) {
mGLThread.onResume();
}
}
protected void surfaceDestroyed() {
// Surface will be destroyed when we return
mGLThread.surfaceDestroyed();
}
public void requestRender() {
if (mGLThread != null) {
mGLThread.requestRender();
}
}
实现就是这么简单。
使用
那么看看使用:
public class GLTextureView extends BaseGLTextureView implements GLSurfaceView.Renderer
...
setRenderer(this);
...
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
mCanvas = new CanvasGL();
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
mCanvas.setSize(width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
mGL = gl;
mCanvas.clearBuffer(backgroundColor);
onGLDraw(mCanvas);
}
protected abstract void onGLDraw(ICanvasGL canvas);
这里使用了封装好的canvasgl。
只要继承以上代码所在的类就可以啦。
@Override
protected void onGLDraw(ICanvasGL canvas) {
canvas.drawBitmap(bitmap, 0, 0);
}
效果图
上图左边就是GLTextureView的效果,右图是GPUImage的效果,知道这个库的应该知道它的内部实现就是用GLSurfaceView的吧。那么,就可以看看TextureView和GLSurfaceView的表现有什么区别了。
详细的请进入github地址进行查阅。