学习笔记-Android OpenGl ES2.0编程从0开始(一)

时间:2021-07-07 03:57:03

转载请标明出处:http://blog.csdn.net/donkor_/article/details/71807627

前言
最近找工作的朋友,可能在各大招聘网站上投递简历的时候,都会发现。招聘岗位的最下方,有一个加分项“熟悉OpenGl或者OpenCv优先”。而这个加分项其实就是目前互联网上特别流行的人脸识别技术编程。百度百科告诉我们“人脸识别,是基于人的脸部特征信息进行身份识别的一种生物识别技术。用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行脸部的一系列相关技术,通常也叫做人像识别、面部识别。”。本文主要通过学习《OpenGL ES应用开发实践指南(Android卷)》一书所做笔记,加上自己的理解编写,涉及的代码均出自原书。如有纰漏,还望指正。

▲概念要点
在开始编码之前,这里先介绍一下概念术语

  • OpenGl 被严格定义为“一种到图形硬件的软件接口”。不是一种编程语言,而是一种API(Application Programming Interface,应用程序编程接口)。作为一种用于实时3D图形的工业标准API,已经得到了广泛的认可和接受。
  • 术语“三维”,即3D,指的是被描述或显示的对象具有三个测量维度:宽度,高度和深度。
  • 渲染,渲染上获得对三维对象的几何描述并把它变成屏幕对象的一种行为。
  • 3D图形的常见用途:交互游戏,仿真到科学,医疗或商业用途的数据虚拟

▲新建第一个应用程序FirstOpenGlDemo
在MainActivity中创建GLSurfaceView实例,使用rendererSet记住GLSurfaceView是否处于有效的状态

private GLSurfaceView glSurfaceView;
private boolean rendererSet = false;

判断是否支持OpenGl 2.0。获取设备配置信息,取出reqGlEsVersion 变量检查OpenGL ES版本号。如果版本号为0x20000或后续版本,我们就可以使用OpenGl ES2.0的API

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo configurationInfo = activityManager.getDeviceConfigurationInfo();
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 build for x86")));

为OpenGL ES 2.0配置渲染表面

if (supportsEs2) {
//Request an OpenGl ES 2.0 compatible context
glSurfaceView.setEGLContextClientVersion(2);

//Assign our renderer
glSurfaceView.setRenderer(new FirstOpenGlProjectRenderer());
rendererSet = true;
} else {
Toast.makeText(this, "This device does not support OpenGl Es 2.0", Toast.LENGTH_SHORT).show();
}

使GLSurfaceView显示在屏幕上

setContentView(glSurfaceView);

▲处理好Android Activity生命周期
他们确保surface视图正确暂停并继续后台渲染线程,同时释放和续用OpenGl上下文

    @Override
protected void onPause() {
super.onPause();
if (rendererSet) {
glSurfaceView.onPause();
}
}

@Override
protected void onResume() {
super.onResume();
if (rendererSet) {
glSurfaceView.onResume();
}
}

在后台线程中渲染
GLSurfaceView会在一个单独的线程中调用渲染器的方法。默认情况下,GLSurfaceView会以显示设备的刷新频率不断地渲染,当然,它也可以配置为按请求渲染,只需要用GlSurfaceView.RENDERMODE_WHEN_DIRTY作为参数调用GLSurfaceView.setRenderMode()即可。
既然Android的GLSurfaceView在后台线程中执行渲染,就必须要小心,只能在这个渲染线程中调用OpenGl,在Android主线程中使用UI(用户界面你)相关的调用;两个线程之间的通信可以用如下方法:在主线程中的GLSurfaceView实例可以调用queueEvent ()方法传递一个Runnable给后台渲染线程,渲染线程可以调用Activity的runOnUIThread()来传递事件(event)给主线程

创建Renderer类
下面先看下渲染器接口定义的方法:

  • onSurfaceCreated(GL10 gl, EGLConfig config)当Surface被创建的时候,GLSurfaceView会调用这个方法;这发生在应用程序第一次运行的时候,并且,当设备被唤醒或者用户从其他activity切换回来时,这个方法可可能被调用。在实践中,这意味着,当应用程序运行时,本方法可能会被调用多次。

  • onSurfaceChanged(GL10 gl, int width, int height)在Surface被创建以后,每次Surface尺寸变化时,这个方法都会被GLSurfaceView调用到。在横屏,竖屏来回切换的时候,Surface尺寸会发生变化

  • onDrawFrame(GL10 gl)当绘制一帧时,这个方法会被GLSurfaceView调用。在这个方法中,我们一定要绘制一些东西,即使只是清空屏幕;因为,在这个方法返回后,渲染缓冲区会被交换并显示在屏幕上,如果什么都没画,可能会看到糟糕的闪烁效果。

为了实现清空屏幕,并调用自定义颜色(红色)显示在屏幕上。首先需要新建渲染器FirstOpenGlProjectRenderer类并实现GLSurfaceView.Renderer接口
在onSurfaceCreated()中调用glClearColor(1.0f,0.0f,0.0f,0.0f)设置清屏时屏幕用的颜色。前三个参数为红,绿,蓝,最后一个为半透明度或透明度

    @Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
gl.glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
}

在onSurfaceChanged()中调用glViewport(0, 0, width, height)设置视口(viewport)尺寸,告诉OpenGl可以用来渲染的surface的大小

    @Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
gl.glViewport(0, 0, width, height);
}

在onDrawFrame中调glClear(GL10.GL_COLOR_BUFFER_BIT)清空屏幕。这样会擦出屏幕上的所有颜色,并用之前glClearColor()调用自定义的颜色填充整个屏幕。

    @Override
public void onDrawFrame(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
}

运行之后会得到以下页面
学习笔记-Android OpenGl ES2.0编程从0开始(一)

▲这里需要注意的是,如果使用模拟器运行程序,屏幕无任何渲染效果。eclipse的话需要查看模拟器的配置选项“Use Host GPU”是否已经勾选上。android studio的话需要看下在创建模拟器时,以下选项是否勾选上
学习笔记-Android OpenGl ES2.0编程从0开始(一)

Demo_CSDN 下载地址:http://download.csdn.net/detail/donkor_/9841490

结尾:
希望这篇文章有帮助到您。欢迎关注我的微信公众号,扫一扫下方二维码,即可关注。有什么问题也可以直接留言,看到之后我会及时回复您。
学习笔记-Android OpenGl ES2.0编程从0开始(一)