概述
这是一个新的系列,学习OpengGl Es,其实是《OpenGl Es 应用开发实践指南 Android卷》的学习笔记,感兴趣的可以直接看这本书,当然这个会记录自己的理解,以下只作为笔记,以防以后忘记
之后会对本书的前九章依次分析记录
Android OpenGl Es 学习(一):创建一个OpenGl es程序
Android OpenGl Es 学习(二):定义顶点和着色器
Android OpenGl Es 学习(三):编译着色器
Android OpenGl Es 学习(四):增填颜色
Android OpenGl Es 学习(五):调整宽高比
Android OpenGl Es 学习(六):进入三维
Android OpenGl Es 学习(七):使用纹理
Android OpenGl Es 学习(八):构建简单物体
Android OpenGl Es 学习(九):增添触摸反馈
最终是要实现一个曲棍球的简单游戏,类似这样的
创建一个新项目
首先用Android Studio 创建一个新的项目
初始化OpenGl
我们使用GLSurfaceView
来初始化OpenGl
,GLSurfaceView
会处理OpenGl
初始化过程中比较基本的操作,比如配置显示设备(display)以及在后台线程中渲染,GLSurfaceView
可以更快的处理Activity的生命周期,GLSurfaceView
为此提供了很多辅助方法
在xml书写GLSurfaceView
<android.opengl.GLSurfaceView
android:id="@+id/glsurface"
android:layout_width="match_parent"
android:layout_height="match_parent" />
在Activity初始化GLSurfaceView
GLSurfaceView glSurfaceView = findViewById(R.id.glsurface);
判断支持OpenGl版本
我们用的是2.0版本,所以判断手机是否支持2.0版本
private boolean supportsEs2() {
ActivityManager activityManager =
(ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo configurationInfo = activityManager
.getDeviceConfigurationInfo();
final boolean supportsEs2 =
configurationInfo.reqGlEsVersion >= 0x20000
|| (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1
&& (Build.FINGERPRINT.startsWith("generic")
|| Build.FINGERPRINT.startsWith("unknown")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")));
return supportsEs2;
}
为OpenGl2.0配置渲染表面
private void initData() {
if (supportsEs2()) {
AirHockKeyRender myGlRender = new AirHockKeyRender(this);
//设置opengl版本
glSurfaceView.setEGLContextClientVersion(2);
glSurfaceView.setRenderer(myGlRender);
//RenderMode 有两种,RENDERMODE_WHEN_DIRTY 和 RENDERMODE_CONTINUOUSLY,前者是懒惰渲染,需要手动调用
// glSurfaceView.requestRender() 才会进行更新,而后者则是不停渲染。
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
} else {
Log.d("mmm", "不支持2.0版本");
}
}
如果支持2.0版本,就设置版本号,在设置渲染器
适配Activity的生命周期
@Override
protected void onResume() {
super.onResume();
glSurfaceView.onResume();
}
@Override
protected void onPause() {
super.onPause();
glSurfaceView.onPause();
}
创建Renderer类
class AirHockKeyRender implements GLSurfaceView.Renderer {
public AirHockKeyRender(Context context) {
}
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
//当surface被创建时,GlsurfaceView会调用这个方法,这个发生在应用程序
// 第一次运行的时候或者从其他Activity回来的时候也会调用
GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
//在Surface创建以后,每次surface尺寸大小发生变化,这个方法会被调用到,比如横竖屏切换
GLES20.glViewport(0, 0, width, height);
}
@Override
public void onDrawFrame(GL10 gl) {
//当绘制每一帧数据的时候,会调用这个放方法,这个方法一定要绘制一些东西,即使只是清空屏幕
//因为这个方法返回后,渲染区的数据会被交换并显示在屏幕上,如果什么都没有话,会看到闪烁效果
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
}
}
GlSurafceView
会在一个单独的线程调用渲染的方法,默认情况下会以设备屏幕刷新率不断的渲染,也可以按照请求选渲染,RenderMode
有两种,RENDERMODE_WHEN_DIRTY
和 RENDERMODE_CONTINUOUSLY
,前者是懒惰渲染,需要手动调用 glSurfaceView.requestRender() 才会进行更新,而后者则是不停渲染。
方法 | 描述 |
---|---|
GLES20.glClearColor | 设置清空屏幕用的颜色,前三个参数分别是 红 绿 蓝 最后一个参数成为阿尔发(alpha)代表透明度,上面我们把第一个设为1,其余为0,表示红色 |
GLES20.glViewport | 设置视口尺寸,告诉opengl迎来渲染的surface尺寸大小 |
GLES20.glClear | 清空屏幕,并用之前glClearColor定义的颜色填充 |
最后
现在我们第一个程序已经写出来的,运行后是这样的