OpenGL ES之二——Android中的OpenGL ES概述

概述

这是一个系列的Android平台下OpenGl ES介绍,从最基本的使用最终到VR图的展示的实现,属于基础篇。(后面针对VR视频会再有几篇文章,属于进阶篇)

OpenGL ES之一——概念扫盲
OpenGL ES之二——Android中的OpenGL ES概述
OpenGL ES之三——绘制纯色背景
OpenGL ES之四——绘制点,线,三角形
OpenGL ES之五——相机和投影,绘制等腰三角形
OpenGL ES之六——绘制矩形和圆形
OpenGL ES之七——着色器语言GLSL
OpenGL ES之八——GLES20类和Matrix类
OpenGL ES之九——相机和投影
OpenGL ES之十——纹理贴图(展示一张图片)
OpenGL ES之十一——绘制3D图形
OpenGL ES之十二——地球仪和VR图

本篇概述

上一篇主要想要脱离Android平台介绍一下OpenGL和OpenGL ES到底是什么,从本篇起开始从零开始搭建自己的Android平台下OpenGL ES知识体系。本篇的内容是Android平台中的OpenGL ES

一.Android基本架构中OpenGL ES

1.1 OpenGL ES在Android的基本架构中位置

如下图,我们从Android的基本架构中找到OpenGL ES的位置。
OpenGL ES之二——Android中的OpenGL ES概述_第1张图片
OpenGL ES就在Libraries里面,从中我们可知Android中自身是支持OpenGL ES的。下面看一下OpenGL ES各个版本在Android各个版本中的支持情况。

1.2 OpenGL ES各个版本在Android各个版本中的支持情况

  1. OpenGL ES1.0是基于OpenGL 1.3的,OpenGL ES1.1是基于OpenGL 1.5的。Android1.0和更高的版本支持这个API规范。OpenGL ES 1.x是针对固定硬件管线的。

  2. OpenGL ES2.0是基于OpenGL 2.0的,不兼容OpenGL ES 1.x。Android 2.2(API 8)和更高的版本支持这个API规范。OpenGL ES 2.x是针对可编程硬件管线的。

  3. OpenGL ES3.0的技术特性几乎完全来自OpenGL 3.x的,向下兼容OpenGL ES 2.x。Android 4.3(API 18)及更高的版本支持这个API规范。

  4. OpenGL ES3.1基本上可以属于OpenGL 4.x的子集,向下兼容OpenGL ES3.0/2.0。Android 5.0(API 21)和更高的版本支持这个API规范。
    Android通过其框架API和Native Development Kit(NDK)支持OpenGL。

二.OpenGL ES在Android中涉及的关键类

Android框架中有两个基础类,可让您使用OpenGL ES API创建和操作图形:GLSurfaceView和 GLSurfaceView.Renderer。下面我们就来了解一下这俩类的用法。

2.1 GLSurfaceView

我们想在Android中使用OpenGL ES 的最简单的方法就是将我们要显示的图像渲染到GLSurfaceView上。但是它只是一个展示类,至于怎么渲染到上面我们就要自己实现GLSurfaceView.Renderer来生成我们自己的渲染器从而完成渲染操作。

2.2 GLSurfaceView.Renderer

它是一个接口,里面定义了我们需要实现的方法,如下面代码,里面各个要实现的方法已经注释的很清楚了。

public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback2 {
		//-----------省略代码------------
		public interface Renderer {
				//创建时,系统调用此方法一次,且仅一次,我们将初始化工作在这里完成。例如设置OpenGL环境参数或初始化OpenGL图形对象。
				void onSurfaceCreated(GL10 gl, EGLConfig config);
				//系统在GLSurfaceView中几何图形更改时调用此方法,例如视频第一帧图像创建或者横竖屏切换。
				void onSurfaceChanged(GL10 gl, int width, int height);
				//完成绘制工作,每一帧图像的渲染都要在此处完成。
				void onDrawFrame(GL10 gl);
		}

		//-----------省略代码------------
}

三.OpenGL ES使用环境配置

3.1 声明OpenGL要求

第一:AndroidManifest.xml 清单文件中我们添加如下的代码,告诉系统我要使用OpenGL ES 2.0版本。



注意:如果我们想要使用更高版本的OpenGL ES以带来更好更高效的运行,那么我们可以将上面的版本号提高如下:



或者更高如下:



直到最高版本。
第二:如果你的应用程序需要使用纹理压缩,你还需要声明你的应用程序需要支持哪种压缩格式,以便他们安装在兼容的设备上。实例代码如下:



更多关于纹理压缩的知识请参看官网关于纹理压缩的介绍,这里不展开说明。

3.2 版本声明之后的结果:

  1. 我们可以使用OpenGL ES的api了;
  2. 添加了上面的声明之后,我们的应用可以安装到不支持OpenGL ES 2.0更低系统版本的手机上,这样一来在运行的时候就有可能崩溃掉。这就是兼容性问题,那么如何解决这个兼容性问题呢?如下:
我们知道OpenGL ES 3.0 API向后兼容2.0 API,那么我们在清单文件中设置OpenGL ES 2.0 API作为默认版本,在运行时检查3.0 API的可用性,然后在设备支持时使用OpenGL ES 3.0功能

同时这里我们也要同时考虑到我们的应用支持的最小系统版本(也就是minSdkVersion),如果我们的最小安装版本都大于等于18(也就是OpenGL ES 3.0对应的最小Android系统版本)了,那么我们也就可以放心的将OpenGL ES 版本设置为3.0了(例如我司的App就因必须引入网信办的统计SDK只能将最小版本提升到19)。

3.3 OpenGL ES版本和Android系统版本兼容性处理

例如我们想检测手机系统版本是否支持OpenGL ES 3.0,我们可以采用下面的两种方式。
1.确定目标版本,尝试创建更高级别的OpenGL ES上下文(EGLContext),创建成功了则表示支持,负责不支持;
2.直接创建OpenGL ES上下文(EGLContext),然后获取支持的最低版本。

使用第一种方法的代码如下

//设定目标版本
private static double glVersion = 3.0;

private static class ContextFactory implements GLSurfaceView.EGLContextFactory {

  private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;

  public EGLContext createContext(
          EGL10 egl, EGLDisplay display, EGLConfig eglConfig) {
      int[] attrib_list = {EGL_CONTEXT_CLIENT_VERSION, (int) glVersion,
              EGL10.EGL_NONE };
      //尝试创建OpenGL ES 3.0的上下文(EGLContext)
      EGLContext context = egl.eglCreateContext(
              display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list);
      //创建成功了则支持3.0版本,没成功则不支持
      return context; 
  }
}

使用第二种方法

//简单粗暴,直接得出最小支持版本
String version = gl.glGetString(GL10.GL_VERSION);

四 OpenGL ES 数据存储

目的:之所以要在这里介绍OpenGL ES 数据存储,是为了后面做准备。后面每次操作着色器的时候都要自己手动调用ByteBuffer相关操作来为数组分配本地内存。(好这里看不懂没关系后面遇到,想起来这里提过就好了)

android中的程序运行在虚拟机中的,OpenGL ES作为本地系统库是运行在硬件上的,虚拟机与OpenGL ES数据传输的方式有两种,如下:

1.使用Java调用本地接口JNI的方式,当我们使用GLES20包里的方法时,内部实现其实就是调用本地方法(这不用我们管)。
2…改变内存的分配方式,Java当中有个特殊的类(如ByteBuffer)集合,可以直接分配本地内存块,并把Java的数据复制到本地内存,本地内存可以被本地环境存取,而不受垃圾回收器管控(后面我们会遇到,到时候可以回来看一下)。

你可能感兴趣的:(OpenGL,ES)