一、自定义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" />
最后效果如下: