前言
这篇文章简单介绍一下在Android平台下的EGL
环境的相关内容,由于OpenGL ES
并不负责窗口管理以及上下文管理,该职责由各个平台自行完成;在Android平台下OpenGL ES
的上下文环境是依赖EGL
的API进行搭建的。
对于EGL
这个框架,谷歌已经提供了GLSurfaceView
,是一个已经封装EGL
相关处理的工具类,但是不够灵活;对于更加核心的OpengGL ES
的用法(例如多线程共享纹理)则需要开发者自行搭建EGL
开发环境。
按照惯例先上一份源码 AndroidVideo。
Java相关核心实现在 EglBase14.java 和 EglBase10.java。
Native相关实现,可以参考 egl_base.cpp。
前置知识
Java层实现
在Java层,EGL
封装了两套框架,分别是:
- 位于
javax.microedition.khronos.egl
包下的EGL10
。 - 位于
android.opengl
包下的EGL14
。
其主要区别是:
EGL14
是在Android 4.2(API 17)引入的,换言之API 17以下的版本不支持EGL14
。EGL10
不支持OpenGL ES 2.x
,因此在EGL10
中某些相关常量参数只能用手写硬编码代替,例如EGL14.EGL_CONTEXT_CLIENT_VERSION
以及EGL14.EGL_OPENGL_ES2_BIT
等等。
PS:由于主体流程基本一致,所以本篇以EGL14
的代码进行示例。
Native层实现
程序在Native层使用EGL
环境时。
需要引入EGL
的so库:
LOCAL_LDLIBS += -lEGL
CMake:
find_library( EGL-lib
EGL )
需要包含头文件:
#include <EGL/egl.h>
#include <EGL/eglext.h>
EGL环境配置整体流程
- 获取默认的
EGLDisplay
。 - 对
EGLDisplay
进行初始化。 - 输入预设置的参数获取
EGL
支持的EGLConfig
。 - 通过
EGLDisplay
和EGLConfig
创建一个EGLContext
上下文环境。 - 创建一个
EGLSurface
来连接EGL
和设备的屏幕。 - 在渲染线程绑定
EGLSurface
和EGLContext
。 - 【进行
OpenGL ES
的API渲染步骤】(与EGL
无关) - 调用
SwapBuffer
进行双缓冲切换显示渲染画面。 - 释放
EGL
相关资源EGLSurface
、EGLContext
、EGLDisplay
。
获取显示设备
首先,EGL
是需要知道绘制内容的目标在哪里,EGLDisplay
是一个封装了物理屏幕的数据类型,也可以理解为绘制目标的一个抽象。
通常通过eglGetDisplay()
方法返回EGLDisplay
来作为OpenGL ES
的渲染目标,在该方法中,一般来说都会将常量EGL_DEFAULT_DISPLAY
传进方法中,而各个手机厂商则会返回默认的显示设备。
java代码:
EGLDisplay eglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
//需判断是否成功获取EGLDisplay
if (eglDisplay == EGL14.EGL_NO_DISPLAY) {
throw new RuntimeException("Unable to get EGL14 display");
}
c代码:
EGLDisplay egl_display;
egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
//需判断是否成功获取EGLDisplay
if (egl_display == EGL_NO_DISPLAY)
return error;
一般来说,我们需要验证eglGetDisplay()
的返回值,如果是EGL_NO_DISPLAY
的话,那么就是没有获取默认显示设备,需要返回给客户端上层处理异常。
当我们获取到了EGLDisplay
,我们需要调用eglInitialize()
对其进行初始化,该方法会返回一个bool变量代表执行是否成功。
java代码:
int version[] = new int[2];
if (!EGL14.eglInitialize(eglDisplay, version, 0, version, 1