OpenGL ES 自定义MyGlSurfaceView

一、自定义GLSurfaceView

  • 继成SurfaceView,并实现其CallBack回调
  • 自定义GLThread线程类,主要用于OpenGL的绘制操作
  • 添加设置Surface和EglContext的方法
  • 提供和系统GLSurfaceView相同的调用方法
    在这里插入图片描述
    二、代码使用
    1、自定义MyEGLSurfaceView
public class MyEGLSurfaceView extends SurfaceView implements SurfaceHolder.Callback{
    private Surface surface;
    private EGLContext eglContext;

    private MyEGLThread mEGLThread;
    private MyGLRender mGLRender;

    public final static int RENDERMODE_WHEN_DIRTY = 0;
    //自动模式:GL线程以一 定的时间间隔自动的循环调用用户实现的onDrawFrame()方法进行一帧一帧的绘制
    public final static int RENDERMODE_CONTINUOUSLY = 1;
    //"脏"模式 也就是说当用户需要重绘的时候,主动 “拉”这个重绘过程,有点类似于Canvas中的invalidate(),一般情况下使用脏模式,这样可以有效降低cpu负载
    private int mRenderMode = RENDERMODE_CONTINUOUSLY;


    public MyEGLSurfaceView(Context context) {
        this(context, null);
    }

    public MyEGLSurfaceView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyEGLSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        getHolder().addCallback(this);
    }

    public void setRender(MyGLRender mGLRender) {
        this.mGLRender = mGLRender;
    }
    //设置模式
    public void setRenderMode(int mRenderMode) {

        if(mGLRender == null)
        {
            throw  new RuntimeException("must set render before");
        }
        this.mRenderMode = mRenderMode;
    }

    public void setSurfaceAndEglContext(Surface surface, EGLContext eglContext)
    {
        this.surface = surface;
        this.eglContext = eglContext;
    }
    //获取EglContext上下文
    public EGLContext getEglContext()
    {
        if(mEGLThread != null)
        {
            return mEGLThread.getEglContext();
        }
        return null;
    }
    //当需要重绘时,调用requestRender()方法
    public void requestRender()
    {
        if(mEGLThread != null)
        {
            mEGLThread.requestRender();
        }
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if(surface == null)
        {
            surface = holder.getSurface();
        }
        //开启一个线程处理EGL
        mEGLThread = new MyEGLThread(new WeakReference<MyEGLSurfaceView>(this));
        mEGLThread.isCreate = true;
        mEGLThread.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        mEGLThread.width = width;
        mEGLThread.height = height;
        mEGLThread.isChange = true;

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mEGLThread.onDestory();
        mEGLThread = null;
        surface = null;
        eglContext = null;
    }

    public interface MyGLRender
    {
        void onSurfaceCreated();
        void onSurfaceChanged(int width, int height);
        void onDrawFrame();
    }

    //自定义MyEGLThread线程类,主要用于OpenGL的绘制操作
    static class MyEGLThread extends Thread{

        private WeakReference<MyEGLSurfaceView> meglSurfaceViewWeakReference;
        private EglHelper eglHelper = null;
        private Object object = null;

        private boolean isExit = false;
        private boolean isCreate = false;
        private boolean isChange = false;
        private boolean isStart = false;

        private int width;
        private int height;

        public MyEGLThread(WeakReference<MyEGLSurfaceView> meglSurfaceViewWeakReference) {
            this.meglSurfaceViewWeakReference = meglSurfaceViewWeakReference;
        }

        @Override
        public void run() {
            super.run();
            isExit = false;
            isStart = false;
            object = new Object();
            eglHelper = new EglHelper();
            eglHelper.initEgl(meglSurfaceViewWeakReference.get().surface, meglSurfaceViewWeakReference.get().eglContext);

            while (true)
            {
                if(isExit)
                {
                    //释放资源
                    release();
                    break;
                }

                if(isStart)
                {
                    if(meglSurfaceViewWeakReference.get().mRenderMode == RENDERMODE_WHEN_DIRTY)
                    {
                        synchronized (object)
                        {
                            try {
                                object.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    else if(meglSurfaceViewWeakReference.get().mRenderMode == RENDERMODE_CONTINUOUSLY)
                    {
                        try {
                            Thread.sleep(1000 / 60);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    else
                    {
                        throw  new RuntimeException("mRenderMode is wrong value");
                    }
                }


                onCreate();
                onChange(width, height);
                onDraw();

                isStart = true;


            }


        }

        private void onCreate()
        {
            if(isCreate && meglSurfaceViewWeakReference.get().mGLRender != null)
            {
                isCreate = false;
                meglSurfaceViewWeakReference.get().mGLRender.onSurfaceCreated();
            }
        }

        private void onChange(int width, int height)
        {
            if(isChange && meglSurfaceViewWeakReference.get().mGLRender != null)
            {
                isChange = false;
                meglSurfaceViewWeakReference.get().mGLRender.onSurfaceChanged(width, height);
            }
        }

        private void onDraw()
        {
            if(meglSurfaceViewWeakReference.get().mGLRender != null && eglHelper != null)
            {
                meglSurfaceViewWeakReference.get().mGLRender.onDrawFrame();
                if(!isStart)
                {
                    meglSurfaceViewWeakReference.get().mGLRender.onDrawFrame();
                }
                eglHelper.swapBuffers();

            }
        }

        private void requestRender()
        {
            if(object != null)
            {
                synchronized (object)
                {
                    object.notifyAll();
                }
            }
        }

        public void onDestory()
        {
            isExit = true;
            requestRender();
        }


        public void release()
        {
            if(eglHelper != null)
            {
                eglHelper.destoryEgl();
                eglHelper = null;
                object = null;
                meglSurfaceViewWeakReference = null;
            }
        }

        public EGLContext getEglContext()
        {
            if(eglHelper != null)
            {
                return eglHelper.getmEglContext();
            }
            return null;
        }

    }

}

2、创建一个MyRender类实现MyEGLSurfaceView.MyGLRender

public class MyRender  implements MyEGLSurfaceView.MyGLRender{

    private static final String TAG = "wq892373445";
    public MyRender(){}

    @Override
    public void onSurfaceCreated() {
        Log.d(TAG, "onSurfaceCreated");
    }

    @Override
    public void onSurfaceChanged(int width, int height) {
        GLES20.glViewport(0, 0, width, height);
        Log.d(TAG, "onSurfaceChanged");
    }

    @Override
    public void onDrawFrame() {
        Log.d(TAG, "onDrawFrame");
        GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
        GLES20.glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    }
}

3、继承MyGlSurfaceView

public class MyGlSurfaceView extends MyEGLSurfaceView{

    public MyGlSurfaceView(Context context) {
        this(context, null);
    }

    public MyGlSurfaceView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyGlSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setRender(new MyRender());
        setRenderMode(MyEGLSurfaceView.RENDERMODE_WHEN_DIRTY);
    }
}

4、布局文件中使用

 <com.wq.myglsurfaceview.MyGlSurfaceView
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

最后效果如下:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值