Android-代替GLSurfaceView的GLTextureView

一如既往地放项目地址:
android-openGL-canvas

本文相关的代码:
BaseGLTextureView

本文主要说明GLTextureView,一个代替GLSurfaceView的自定义View。将会说明包括GLTextureView的优点,大致实现方式,以及使用。

优点

其实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地址进行查阅。

你可能感兴趣的:(Android)