说明:Khronos 是 OpenGL/ OpenGL ES/ OpenVG 和 EGL 等规范的定义者。以下的代码主要是用 Android 书写,但规范是 EGL 规范。
EGL 是 Khronos ***定义的用于管理绘图表面(窗口只是绘图表面的一种类型,还有其他的类型)的 API,EGL 提供了 OpenGL ES(以及其他 Khronos 图形 API(如 OpenVG))和不同操作系统(Android、Windows 等)之间的一个 “结合层次”。即 EGL 定义了 Khronos API 如何与底层窗口系统交流,是 Khronos 定义的规范,相当于一个框架,具体的实现由各个操作系统确定。它是在 OpenGL ES 等规范中讨论的概念,故应和这些规范的文档结合起来阅读,且其 API 的说明文档也应在 Khronos 网站上寻找。注意:IOS 提供了自己的 EGL API 实现,称为 EAGL。
通常,在 Android 中,EGL14 实现的是 EGL 1/4 规范。其相当于 Google 官方对 JAVA 的 EGL10(EGL 1/0 规范)的一次重新设计。通常,我们使用 EGL14 中的函数。而 EGL15 是 EGL 1/5 规范,其在设计时,仅仅是做了规范的补充,并未重新设计。通常 EGL14、EGL15 与 GLES20 等一起使用。GLES20 是 OpenGL ES 2/0 规范的实现。OpenGL ES 1/x 规范因为是早期版本,受限于机器性能和架构设计等,基本可以不再使用。而 OpenGL ES 2/x 规范从 Android 2/3 版本后开始支持,目前市面上的所有手机都支持。相比于 1/0,OpenGL ES 2/0 引入了可编程图形管线,具体的渲染相关使用专门的着色语言来表达。
下面,介绍一下 EGL 的使用流程。
在 EGL 能够确定可用的绘制表面类型之前,它必须打开和窗口系统的通信渠道。因为每个窗口系统都有不同的语义,所以 EGL 提供了基本的不对操作系统透明的类型---EGLDisplay。该类型封装了所有系统相关性,用于和原生窗口系统交流。任何使用 EGL 的应用程序,第一个操作必须是创建和初始化与本地 EGL 显示的连接。以下代码展示如何创建连接:
privatevoidinitEGLDisplay(){//获取本地默认的显示EGLDisplaydisplay=EGL14/eglGetDisplay(EGL14/EGL_DEFAULT_DISPLAY)/if(display==EGL14/EGL_NO_DISPLAY){//具体的错误查询方法下面讲述Log/e("/NO"//"/LinkError"/)/return/}//做接下来的操作}上面的代码中,我们已经知道 EGL 会发生错误,也可以获取错误。
EGL 中的大部分函数,在成功时会返回 EGL_TRUE,否则返回 EGL_FALSE。但是,EGL 所做的不仅是告诉我们调用是否失败,它还将记录错误,指示故障原因。不过,这个错误代码并不会直接告诉我们,我们需要查询规范,才能知道每个的含义。可以调用 eglGetError() 函数获取错误,以下是错误的说明:
privatevoidgetError(){interrorCode=EGL14/eglGetError()/switch(errorCode){caseEGL14/EGL_SUCCESS/println("/函数执行成功,无错误---没有错误"/)/break/caseEGL14/EGL_NOT_INITIALIZED/println("/对于特定的Display/EGL未初始化,或者不能初始化---没有初始化"/)/break/caseEGL14/EGL_BAD_ACCESS/println("/EGL无法访问资源(如Context绑定在了其他线程)---访问失败"/)/break/caseEGL14/EGL_BAD_ALLOC/println("/对于请求的操作,EGL分配资源失败---分配失败"/)/break/caseEGL14/EGL_BAD_ATTRIBUTE/println("/未知的属性,或者属性已失效---错误的属性"/)/break/caseEGL14/EGL_BAD_CONTEXT/println("/EGLContext(上下文)错误或无效---错误的上下文"/)/break/caseEGL14/EGL_BAD_CONFIG/println("/EGLConfig(配置)错误或无效---错误的配置"/)/break/caseEGL14/EGL_BAD_DISPLAY/println("/EGLDisplay(显示)错误或无效---错误的显示设备对象"/)/break/caseEGL14/EGL_BAD_SURFACE/println("/未知的属性,或者属性已失效---错误的Surface对象"/)/break/caseEGL14/EGL_BAD_CURRENT_SURFACE/println("/窗口,缓冲和像素图(三种Surface)的调用线程的Surface错误或无效---当前Surface对象错误"/)/break/caseEGL14/EGL_BAD_MATCH/println("/参数不符(如有效的Context申请缓冲,但缓冲不是有效的Surface提供)---无法匹配"/)/break/caseEGL14/EGL_BAD_PARAMETER/println("/错误的参数"/)/break/caseEGL14/EGL_BAD_NATIVE_PIXMAP/println("/NativePixmapType对象未指向有效的本地像素图对象---错误的像素图"/)/break/caseEGL14/EGL_BAD_NATIVE_WINDOW/println("/NativeWindowType对象未指向有效的本地窗口对象---错误的本地窗口对象"/)/break/caseEGL14/EGL_CONTEXT_LOST/println("/电源错误事件发生,OpenGL重新初始化,上下文等状态重置---上下文丢失"/)/break/default/break/}}privatevoidprintln(Strings){System/out/println(s)/}成功打开连接之后,需要初始化 EGL。可以调用如下函数完成:
//标准的EGL定义EGLBooleaneglInitialize(EGLDisplaydisplay/EGLint*majorVersion/EGLint*minorVersion)///display/指定EGL的显示连接//majorVersion/存储指定EGL实现,返回的主版本号,可能为NULL//minorVersion/存储指定EGL实现,返回的次版本号,可能为NULL在 Android 中,其具体实现如下:
//定义一个2维数组,用于存放获取到的版本号,主版本号放在version[0],次版本号放在version[1]int[]version=newint[2]///初始化EGL/eglDisplay的获取在上面讲述了booleanisSuccess=EGL14/eglInitialize(eglDisplay/version/0/version/1)/if(!isSuccess){switch(EGL14/eglGetError()){caseEGL14/EGL_BAD_DISPLAY/println("/无效的EGLDisplay参数"/)/break/caseEGL14/EGL_NOT_INITIALIZED/println("/EGL不能初始化"/)/break/default/println("/发生错误:"/+EGL14/eglGetError())/break/}return/}//初始化成功,往下走////////这个函数初始化 EGL 内部数据结构,返回 EGL 实现的主版本号和次版本号。如果 EGL 无法初始化,函数会返回 EGL_FALSE,并将 EGL 错误代码设置为:
EGL_BAD_DISPLAY --- 如果 display 不是有效的 EGLDisplay
EGL_NOT_INITIALIZED --- 如果 EGL 不能初始化
一旦初始化了 EGL,就可以确定可用渲染表面的类型和配置,这有两种方法:
查询每个表面配置,找出最好的选择
指定一组需求,让 EGL 推荐最佳匹配
在许多情况下,使用第二种方法更简单,而且最有可能得到用第一种方法找到的匹配。
在任何一种情况下,EGL 都将返回一个 EGLConfig,这是包含有关特定表面及其特征(如每个颜色分量的位数、与 EGLConfig 相关的深度缓冲区(如果有的话))的 EGL 内部数据结构的标识符。可以用 eglGetConfigAttrib 函数查询 EGLConfig 的任何属性。后面会讲。
调用以下函数,可以查询系统支持的所有 EGL 表面配置:
booleaneglGetConfigs(EGLDisplaydisplay/EGLConfig[]configs/intconfigsOffset/intconfig_size/int[]num_config/intnum_configOffset)///display/EGL连接的显示//configs/指定的configs列表(第2个参数)//configsOffset/列表取值的起始偏移值//config_size/指定的configs列表的尺寸//num_config/存放获取到的配置数量。一般来说,此列表仅存放大小,列表长度设置为1即可(第5个参数)//num_configOffset/存值时的起始偏移值(第6个参数)函数在调用成功时,会返回 EGL_TRUE。失败时,会返回 EGL_FALSE,并将 EGL 错误代码设置为:
EGL_NOT_INITIALIZED --- 如果 display 不能初始化
EGL_BAD_PARAMETER --- 如果 num_config(用于存放 返回结果的大小 的列表(上述说明中的第 5 个参数))为空
调用 eglGetConfigs 有两种方法。
如果指定的入参 configs 为 NULL,则将返回 EGL_TRUE,并将返回可用的 EGLConfig 的数量。在足够谨慎的情况下,当没有返回任何 EGLConfig 的信息,但是知道了可用配置的数量时,我们可以分配足够的内存,来获得完成的 EGLConfig ***
在更普遍的情况下,我们一般会分配一个未初始化的 EGLConfig 值的数组((上述说明中的第 2 个参数)),并作为参数传递给 eglGetConfigs 函数。函数调用完成时,会获取到配置列表((上述说明中的第 2 个参数,此参数被修改过,存放了结果)),并根据上述说明中的第 5 和第 6 个参数来确定列表中可用的配置数量和位置(即根据 5、6 确定结果在 2 中的位置)。当然,获取到的配置结果的大小不会超过传入的未初始化的 EGLConfig 值的数组的大小。
此处,说明一下与 EGLConfig 相关的 EGL 值,并说明如果检索这些值。
EGLConfig 包含关于 EGL 启用的表面的所有信息。其包括关于可用颜色、与配置相关的其他缓冲区(深度和模板缓冲区)、表面类型等等。可以用下面的函数查询与 EGLConfig 相关的特定属性:
booleaneglGetConfigAttrib(EGLDisplaydisplay/EGLConfigconfig/intattribute/int[]value/intoffset)///display/EGL的显示连接//config/待查询的配置//attribute/指定返回的特定属性//value/指定的返回值//offset/结果放入数组时的偏移值,一般为0上述函数在调用成功时返回 EGL_TRUE,失败时返回 EGL_FALSE,并将 EGL 错误代码设置为:
EGL_BAD_DISPLAY: 显示无效
EGL_NOT_INITIALIZED/ 显示未初始化
EGL_BAD_CONFIG: 配置无效
EGL_BAD_ATTRIBUTE: 属性无效
下面是在 eglGetConfigAttrib 函数中所有的可用的 EGLConfig 属性列表:
EGL_ALPHA_SIZE 1. WEO啦仅提供《Android OpenGL 开发---EGL 的使用》全文中的部分公开内容,版权归原著者或相关公司所有。 2. 以上信息来源于互联网免费公开的渠道,若文章所含内容侵犯了您的版权或隐私,请通知我们立即删除。 3. 当前页面地址:https://www.weo.la/doc/8864e49c1f861d28.html 复制内容请保留相关链接。 最近收录
热文排行
随机推荐
|