参考:自定义GLSurfaceView
GLSurfaceView的简单分析及巧妙借用
书写本文的初衷是为了自我学习
GLSurfaceView继承了SurfaceView,实现了SurfaceHolder.Callback2接口。
SurfaceView在View的基础上是创建了独立的Surface,拥有SurfaceHolder来管理它的Surface,渲染的工作可以不再在主线程中做了。可以通过SurfaceHolder得到Canvas,在单独的线程中,利用Canvas绘制需要显示的内容,然后更新到Surface上。
而GLSurfaceView,它主要是在SurfaceView的基础上实现了一个GLThread(EGLContext创建GL环境所在线程即为GL线程),绘制的工作直接通过OpenGL来进行,绘制的内容默认情况下依旧是绘制到SurfaceView所提供的Surface上。
参照GLSurfaceView的实现,我们可以自行创建GL环境,来进行GL渲染。实现自行制定指定载体、后台渲染等功能。
因此我们只需要实现GLSurfaceView实现的功能就完成了自定义的GLSurfaceView.
1、继成SurfaceView,并实现其CallBack回调。
2、自定义GLThread线程类,主要用于OpenGL的绘制操作,调用Render渲染器。
3、添加设置Surface和EglContext的方法。
4、提供和系统GLSurfaceView相同的调用方法。
6、Render渲染器接口。
实现原理:
1.EglSurfaceView继承了SurfaceView,实现了SurfaceHolder.Callback,创建GLThread线程,Render接口
2.EGLRender实现了EglSurfaceView中的Render接口
3.EGLActivity入口activity
代码查看顺序:
EGLActivity->.EglSurfaceView->EGLRender
然后看一下该类的内容
可以看到,该类创建了EGLThread线程,Render接口,并持有一个Surface。
这是因为EGLThread线程调用实现了Render接口的渲染器对象,这个渲染器对象绘制的内容,通过Surface呈现出来。
以下展示代码:
public class EglSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
private Render mRenderer;
private EGLThread mEGLThread;
private Surface mSurface;
private EGLContext mEglContext;
public final static int RENDERMODE_WHEN_DIRTY = 0;
public final static int RENDERMODE_CONTINUOUSLY = 1;
private int mRenderMode = RENDERMODE_WHEN_DIRTY;
public EglSurfaceView(Context context) {
this(context, null);
}
public EglSurfaceView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public EglSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
SurfaceHolder holder = getHolder();
holder.addCallback(this);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (mSurface == null) {
mSurface = holder.getSurface();
}
mEGLThread = new EGLThread(new WeakReference<>(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.onDestroy();
mEGLThread = null;
mSurface = null;
mEglContext = null;
}
public void setRender(Render mRenderer) {
this.mRenderer = mRenderer;
}
public void setRenderMode(int renderMode) {
this.mRenderMode = renderMode;
}
public void requestRender() {
if (mEGLThread != null) {
mEGLThread.requestRender();
}
}
public void setSurfaceAndEglContext(Surface surface, EGLContext eglContext) {
this.mSurface = surface;
this.mEglContext = eglContext;
}
public EGLContext getEglContext() {
if (mEGLThread != null) {
return mEGLThread.getEglContext();
}
return null;
}
private static class EGLThread extends Thread {
EGLThread(WeakReference<EglSurfaceView> eGLSurfaceViewWeakRef) {
this.mEGLSurfaceViewWeakRef = eGLSurfaceViewWeakRef;
}
@Override
public void run() {
super.run();
try {
guardedRun();
} catch (Exception e) {
// fall thru and exit normally
}
}
private void guardedRun() throws InterruptedException {
isExit = false;
isStart = false;
object = new Object();
mEglHelper = new EglHelper();
mEglHelper.initEgl(mEGLSurfaceViewWeakRef.get().mSurface, mEGLSurfaceViewWeakRef.get().mEglContext);
while (true) {
if (isExit) {
//释放资源
release();
break;
}
if (isStart) {
if (mEGLSurfaceViewWeakRef.get().mRenderMode == RENDERMODE_WHEN_DIRTY) {
synchronized (object) {
object.wait();
}
} else if (mEGLSurfaceViewWeakRef.get().mRenderMode == RENDERMODE_CONTINUOUSLY) {
Thread.sleep(1000 / 60);
} else {
throw new IllegalArgumentException("renderMode");
}
}
onCreate();
onChange(width, height);
onDraw();
isStart = true;
}
}
private void onCreate() {
if (!isCreate || mEGLSurfaceViewWeakRef.get().mRenderer == null)
return;
isCreate = false;
mEGLSurfaceViewWeakRef.get().mRenderer.onSurfaceCreated();
}
private void onChange(int width, int height) {
if (!isChange || mEGLSurfaceViewWeakRef.get().mRenderer == null)
return;
isChange = false;
mEGLSurfaceViewWeakRef.get().mRenderer.onSurfaceChanged(width, height);
}
private void onDraw() {
if (mEGLSurfaceViewWeakRef.get().mRenderer == null)
return;
mEGLSurfaceViewWeakRef.get().mRenderer.onDrawFrame();
//第一次的时候手动调用一次 不然不会显示ui
if (!isStart) {
mEGLSurfaceViewWeakRef.get().mRenderer.onDrawFrame();
}
mEglHelper.swapBuffers();
}
void requestRender() {
if (object != null) {
synchronized (object) {
object.notifyAll();
}
}
}
void release() {
isExit = true;
//释放锁
requestRender();
}
void onDestroy() {
if (mEglHelper != null) {
mEglHelper.destoryEgl();
mEglHelper = null;
object = null;
mEGLSurfaceViewWeakRef = null;
}
}
EGLContext getEglContext() {
if (mEglHelper != null) {
return mEglHelper.getEglContext();
}
return null;
}
private WeakReference<EglSurfaceView> mEGLSurfaceViewWeakRef;
private EglHelper mEglHelper;
private int width;
private int height;
private boolean isCreate;
private boolean isChange;
private boolean isStart;
private boolean isExit;
private Object object;
}
public interface Render {
void onSurfaceCreated();
void onSurfaceChanged(int width, int height);
void onDrawFrame();
}
}
项目地址,欢迎点星