大家好,接下来将为大家介绍GLSurfaceView 。
1、GLSurfaceView
上一节为大家介绍了SurfaceView 与 TextureView 。但是,在Android中使用OpenGL ES,不得不提到一个控件:GLSurfaceView。
而GLSurfaceView继承自SurfaceView,其实是对SurfaceView再做了一次封装,可以看作是SurfaceView的一种典型使用模式,方便我们在实际开发中方便的使用OpenGL。它在SurfaceView的基础上,实现了SurfaceHolder.Callback2接口,拥有SurfaceView的全部特性,也有view所有的功能和属性,特别是处理事件的能力,它主要是在SurfaceView的基础上它加入了EGL的管理,并自带了一个GLThread绘制线程(EGLContext创建GL环境所在线程即为GL线程),绘制的工作直接通过OpenGL在绘制线程进行,不会阻塞主线程,绘制的结果输出到SurfaceView所提供的Surface上,这使得GLSurfaceView也拥有了OpenGLES所提供的图形处理能力,通过它定义的Render接口,使更改具体的Render的行为非常灵活性,只需要将实现了渲染函数的Renderer的实现类设置给GLSurfaceView即可。
2、GLSurfaceView的一些特性:
a:提供并且管理一个独立的Surface。
b:提供并且管理一个EGL display,它能让opengl把内容渲染到上述的Surface上。
c:支持用户自定义渲染器(Render),通过setRenderer设置一个自定义的Renderer。
d:让渲染器在独立的GLThread线程里运作,和UI线程分离。
e:支持按需渲染(on-demand)和连续渲染(continuous)两种模式。
f:GPU加速:GLSurfaceView的效率是SurfaceView的30倍以上,SurfaceView使用画布进行绘制,GLSurfaceView利用GPU加速提高了绘制效率。
g:View的绘制onDraw(Canvas canvas)使用Skia渲染引擎渲染,而GLSurfaceView的渲染器Renderer,其渲染的onDrawFrame(GL10 gl)接口使用opengl绘制引擎进行渲染。
3、GLSurfaceView的使用
a:在AndroidManifest.xml中设置OpenGL ES的版本,这里我们使用的是OpenGL ES3.0,因此可进行如下声明。
<uses-feature android:glEsVersion="0x00030000" android:required="true" />
b:创建GLSurfaceView对象
1)通过布局的方式,在xml文件中配置:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.opengl.GLSurfaceView
android:id="@+id/gl_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
2)通过new的方法直接创建GLSurfaceView的实例:
import android.app.Activity;
import android.app.ActivityManager;
import android.content.pm.ConfigurationInfo;
import android.opengl.GLSurfaceView;
import android.os.Build;
import android.os.Bundle;
import android.widget.Toast;
public class MainActivity extends Activity {
private GLSurfaceView mGLSurfaceView;
private boolean mRendererSet = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGLSurfaceView = new GLSurfaceView(this);
final ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
final ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
final boolean supportsGLES3 = configurationInfo.reqGlEsVersion >= 0x30000
||(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
&&(Build.FINGERPRINT.startsWith("generic"))
|| Build.FINGERPRINT.startsWith("unknow")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86");
if (supportsGLES3){
mGLSurfaceView.setEGLContextClientVersion(3);
mGLSurfaceView.setRenderer(new SimpleRenderer(this));
mRendererSet = true;
}else {
Toast.makeText(this , "This device does not support OpenGL ES 3.0." ,
Toast.LENGTH_SHORT).show();
return;
}
setContentView(mGLSurfaceView);
}
@Override
protected void onPause() {
if (mRendererSet){
mGLSurfaceView.onPause();
}
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
if (mRendererSet){
mGLSurfaceView.onResume();
}
}
}
c:判断了当前设备是否支持OpenGL ES3 :
final boolean supportsGLES3 = configurationInfo.reqGlEsVersion >= 0x30000
||(Build.VERSION.SDK_INT >= ……
d:为GLSurfaceView设置渲染器(Render):
mGLSurfaceView.setEGLContextClientVersion(3);
//设置渲染器
mGLSurfaceView.setRenderer(new SimpleRenderer(this));
e:把我们GLSurfaceView的生命周期和Activity的生命周期绑定:
@Override
protected void onPause() {
if (mRendererSet){
mGLSurfaceView.onPause();
}
super.onPause();
}
@Override
protected void onResume() {
if (mRendererSet){
mGLSurfaceView.onResume();
}
super.onResume();
f:编写渲染器Render,实体类实现GLSurfaceView.Renderer接口,并实现onSurfaceCreated、onDrawFrame、onSurfaceChanged方法,GLSurfaceView的渲染工作主要由GLSurfaceView.Renderer完成。
public class SimpleRenderer implements GLSurfaceView.Renderer {
@Override
public void onSurfaceCreated(GL10 gl10, EGLConfig eglConfig) {
//surface被创建后需要做的处理
//如设置渲染窗口背景颜色
GLES30.glClearColor(0.0f,0.0f,0.0f,1.0f);
}
@Override
public void onSurfaceChanged(GL10 gl10, int width, int height) {
// 渲染窗口大小发生改变或者屏幕方法发生变化时候回调
GLES30.glViewport(0,0,width,height);
}
@Override
public void onDrawFrame(GL10 gl10) {
//执行渲染工作
//如清空颜色缓冲区
GLES30.glClearColor(GLES20.GL_COLOR_BUFFER_BIT,0f,0f,0f);
//TODO
…………
}
}
最后,欢迎大家一起交流学习:微信:liaosy666 ; QQ:2209115372 。