原文:http://www.cnblogs.com/kiffa/archive/2013/02/21/2921123.html

1, 前言

在前文(学习OpenGL-ES: 1 - 像素、颜色、显存、环境初始化和EGL)中提到EGL是本地平台和OpenGL ES之间的抽象层,其完成了本地相关的环境初始化和上下文控制工作,以保证OpenGL ES的平台无关性。主要包含如下工作:

a,选择显示设备

b, 选择像素格式。

c, 选择某些特性,比如如果你打算画中国水墨画,你需要额外指定宣纸和毛笔。

d, 申请显存。

e, 创建上下文(Context),上下文本质上是一组状态的集合,描述了在某个特定时刻系统的状态, 用于处理暂停、恢复、销毁、重建等情况;

f, 指定当前的环境为绘制环境 。

总体流程上,EGL按顺序分为若干步骤:

1, 选择显示设备display,即上述的a.

2,指定特性,包括上述的像素格式(b)和特定特性(c),根据指定的特性来获取多个满足这些特性的config(比如你指定RGB中的R为5bits,那么可能会有RGB_565和RGB_555两种像素格式均满足此特性),用户从这些可用的configs中选择一个,根据display和config获取绘制用的buffer(一般为显存),即上述的d。

3,使用display、config、buffer来创建context,及即上述的e.

4, 使用display、buffer、context 设置当前的渲染环境,即上述的f.

本文将以Android下EGL的使用为例逐一进行讲解。

2,选择显示设备及确认EGL版本

EGL有1.0、1.1、1.2、1.3、1.4这几个版本,Android中使用的是1.4,EGL提供了查询版本的API,以下为Android中例子:

    EGL10 egl = (EGL10) EGLContext.getEGL();EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); //获取显示设备// Initint[] version = new int[2];egl.eglInitialize(display, version); //version中存放EGL 版本号,int[0]为主版本号,int[1]为子版本号
String vendor = egl.eglQueryString(display, EGL10.EGL_VENDOR);WLog.d("egl vendor: " + vendor); // 打印此版本EGL的实现厂商
String version = egl.eglQueryString(display, EGL10.EGL_VERSION);WLog.d("egl version: " + version);// 打印EGL版本号
String extension = egl.eglQueryString(display, EGL10.EGL_EXTENSIONS);WLog.d("egl extension: " + extension); //打印支持的EGL扩展

说明:

1,虽然Android使用(实现)的是EGL 1.4(从打印的版本号中可见), 但在Android 4.2(API 17)以前的版本没有EGL14,只有EGL10和EGL11,而这两个版本是不支持OpengGL ES 2.x的,因此在老版本中某些ES 2.x相关的常量参数只能用手写的硬编码代替,典型的如设定EGL渲染类型API的参数EGL10.EGL_RENDERABLE_TYPE,这个属性用不同的赋值指定的不同的渲染API,包括OpenGL,OpenGL ES 1.x, OpenGL ES 2.x,OpenVG等,如果采用ES 2.0,应该设置此值为: EGL14.EGL_OPENGL_ES2_BIT,但是在Android 4.2之前,没有EGL14接口,只能采取手写的硬编码来指定,类似: EGL_RENDERABLE_TYPE = 4;

2,egl.eglQueryString()用来查询EGL的相关信息,详见这里:http://www.khronos.org/registry/egl/sdk/docs/man/xhtml/

3,EGL10.EGL_DEFAULT_DISPLAY 默认对应手机主屏幕。

3,指定(buffer)特性,获取config

1,构造需要的特性列表

int[] attributes = new int[] { EGL10.EGL_RED_SIZE, 8,  //指定RGB中的R大小(bits)EGL10.EGL_GREEN_SIZE, 8, //指定G大小EGL10.EGL_BLUE_SIZE, 8,  //指定B大小EGL10.EGL_ALPHA_SIZE, 8, //指定Alpha大小,以上四项实际上指定了像素格式EGL10.EGL_DEPTH_SIZE, 16, //指定深度缓存(Z Buffer)大小EGL10.EGL_RENDERABLE_TYPE, 4, //指定渲染api类别, 如上一小节描述,这里或者是硬编码的4,或者是EGL14.EGL_OPENGL_ES2_BIT EGL10.EGL_NONE };  //总是以EGL10.EGL_NONE结尾

2, 获取所有可用的configs,每个config都是EGL系统根据特定规则选择出来的最符合特性列表要求的一组特性。

    EGLConfig config = null;
int[] configNum = new int[1];//获取满足attributes的config个数。egl.eglChooseConfig(display, attributes, null, 0, configNum);int num = configNum[0];if(num != 0){EGLConfig[] configs = new EGLConfig[num];//获取所有满足attributes的configs
        egl.eglChooseConfig(display, attributes, configs, num, configNum);config = configs[0]; //以某种规则选择一个config,这里使用了最简单的规则。      }

说明:

1,display和attributes都来自之前的步骤。

2,eglChooseConfig(display, attributes, configs, num, configNum); 用于获取满足attributes的所有config,参数1、2其意明显,参数3用于存放输出的configs,参数4指定最多输出多少个config,参数5由EGL系统写入,表明满足attributes的config一共有多少个。如果使用eglChooseConfig(display, attributes, null, 0, configNum)这种形式调用,则会在configNum中输出所有满足条件的config个数。

3,一般习惯是获取所有满足attributes的config个数,再据此分配存放config的数组,获取所有config,根据某种特定规则,从中选择其一。

4,API详细说明和所有可指定的attributes见这里:http://www.khronos.org/registry/egl/sdk/docs/man/xhtml/

5,打印config中的常用attributes:

  /*** 打印EGLConfig信息* * @param egl* @param display* @param config*          : 指定的EGLConfig*/public static void printEGLConfigAttribs(EGL10 egl, EGLDisplay display, EGLConfig config) {int value = findConfigAttrib(egl, display, config, EGL10.EGL_RED_SIZE, -1);WLog.d("eglconfig: EGL_RED_SIZE: " + value);value = findConfigAttrib(egl, display, config, EGL10.EGL_GREEN_SIZE, -1);WLog.d("eglconfig: EGL_GREEN_SIZE: " + value);value = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, -1);WLog.d("eglconfig: EGL_BLUE_SIZE: " + value);value = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, -1);WLog.d("eglconfig: EGL_ALPHA_SIZE: " + value);value = findConfigAttrib(egl, display, config, EGL10.EGL_DEPTH_SIZE, -1);WLog.d("eglconfig: EGL_DEPTH_SIZE: " + value);value = findConfigAttrib(egl, display, config, EGL10.EGL_RENDERABLE_TYPE, -1);WLog.d("eglconfig: EGL_RENDERABL_TYPE: " + value);value = findConfigAttrib(egl, display, config, EGL10.EGL_SAMPLE_BUFFERS, -1);WLog.d("eglconfig: EGL_SAMPLE_BUFFERS: " + value);value = findConfigAttrib(egl, display, config, EGL10.EGL_SAMPLES, -1);WLog.d("eglconfig: EGL_SAMPLES: " + value);value = findConfigAttrib(egl, display, config, EGL10.EGL_STENCIL_SIZE, -1);WLog.d("eglconfig: EGL_STENCIL_SIZE: " + value);}/*** 在指定EGLConfig中查找指定attrib的值,如果没有此属性,返回指定的默认值* * @param egl* @param display* @param config*          : 指定的EGLConfig* @param attribute*          : 指定的attrib* @param defaultValue*          : 查找失败时返回的默认值* @return: 查找成功,返回查找值;查找失败,返回参数中指定的默认值*/static public int findConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config,int attribute, int defaultValue) {int[] val = new int[1];if (egl.eglGetConfigAttrib(display, config, attribute, val)) {return val[0];}return defaultValue;}

4, 获取显存

EGLSurface surface = egl.eglCreateWindowSurface(display, config, surfaceHolder, null);

说明:

1,详细的参数说明见这里:http://www.khronos.org/registry/egl/sdk/docs/man/xhtml/

2,参数surfaceHolder是android.view.SurfaceHolder类型,负责对Android Surface的管理,后续将对此进行较详细说明,参看第8小节。

3,参数4用于描述WindowSurface类型,初始化方式如同前面小节的egl attributes, 其中一个attribute是EGL_RENDER_BUFFER, 用于描述渲染buffer(所有的绘制在此buffer中进行)类别,取值为EGL_SINGLE_BUFFER以及默认的EGL_BACK_BUFFER,前者属于单缓冲,绘制的同时用户即可见;后者属于双缓冲,前端缓冲用于显示,OpenGL ES 在后端缓冲中进行绘制,绘制完毕后使用eglSwapBuffers()交换前后缓冲,用户即看到在后缓冲中的内容,如此反复。其他attributes见官方文档。

5, 创建context

 int attrs[] = { EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE, };EGLContext context = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, attrs);

说明:

函数原型     EGLContext  eglCreateContext(EGLDisplay display, EGLConfig config, EGLContext share_context, int[] attrib_list);

share_context: 是否有context共享,共享的contxt之间亦共享所有数据。EGL_NO_CONTEXT代表不共享。

attrib_list: 目前可用属性只有EGL_CONTEXT_CLIENT_VERSION, 1代表OpenGL ES 1.x, 2代表2.0。同样在Android4.2之前,没有EGL_CONTEXT_CLIENT_VERSION这个属性,只能使用硬编码0x3098代替。

函数详细描述:http://www.khronos.org/registry/egl/sdk/docs/man/xhtml/

6, 设置为当前的渲染环境

egl.eglMakeCurrent(display, surface, surface, contxt);

比较简单,不做赘述,详细描述:http://www.khronos.org/registry/egl/sdk/docs/man/xhtml/

7,环境初始化完毕,开始使用OpenGL ES 2.0 API 进行绘制。

// 开始使用OpenGL ES 2.0 API 进行绘制。
GLES20.glClearColor(0, 0, 0, 1);
GLES20.clear(GL_COLOR_BUFFER_BIT);

8,关于SurfaceHolder

一般在Android中使用OpenGL ES,总是会从GLSurfaceView和Renderer开始,但是由上面描述的过程可知,只需要提供一个合适的SurfaceHolder,就可以完成整个环境初始化,并进行绘制。GLSurfaceView和Renderer事实上只是在本文描述的基础上封装了一些便利的功能,便于开发者开发,比如渲染同步、状态控制、主(渲染)循环等。那么,如何提供一个SurfaceHolder,具体的Surface分配过程又是怎样的呢,这涉及到Android窗口机制,属于比较大的话题,将在下一节进行描述。

学习OpenGL-ES: 2 - EGL解析相关推荐

  1. 从零开始学习OpenGL ES之五 – 材质

    从零开始学习OpenGL ES之五 – 材质 作者: iPhoneGeek 爱疯极客 09-Jan-10 iPhone Development 浏览次数: 411 |  评论 ↓ Tweet Shar ...

  2. 从显示一张图片开始学习OpenGL ES

    前言 网上很多介绍OpenGL ES的文章,但由于OpenGL ES内容太多,所以这些文章难免过于臃肿杂乱,很难抓住重点,对于初学者来说最后还是云里雾里.很多人(包括笔者本人)开始深入了解OpenGL ...

  3. 与context的关系_你还不知道 OpenGL ES 和 EGL 的关系?

    什么是 EGL EGL 是 OpenGL ES 和本地窗口系统(Native Window System)之间的通信接口,它的主要作用: 与设备的原生窗口系统通信: 查询绘图表面的可用类型和配置: 创 ...

  4. OpenGL ES和EGL关系(二十五)

    什么是 EGL EGL 是 OpenGL ES 和本地窗口系统(Native Window System)之间的通信接口,它的主要作用: 与设备的原生窗口系统通信: 查询绘图表面的可用类型和配置: 创 ...

  5. OpenGL ES与EGL的关系(二十一)

    什么是OpenGL? Open Graphics Library (OpenGL) is a cross-language, cross-platform application programmin ...

  6. [转载]从零开始学习OpenGL ES之八 – 交叉存取顶点数据

    Technote 2230提出了很多用OpenGL ES来提升iphone程序性能的建议.我们现在远远不能深刻理解OpenGL ES所以你需要学习以下内容.不信?是真的,试试看,我等着你的读后感. 好 ...

  7. 【Android OpenGL开发】OpenGL ES与EGL介绍

    什么是OpenGL ES OpenGL(Open Graphics Library)是一个跨编程语言.跨平台的编程图形程序接口,主要用于图像的渲染. Android提供了简化版的OpenGL接口,即O ...

  8. OpenGL ES: (3) EGL、EGL绘图的基本步骤、EGLSurface、ANativeWindow

    1. EGL概述 EGL 是 OpenGL ES 渲染 API 和本地窗口系统(native platform window system)之间的一个中间接口层,它主要由系统制造商实现. EGL提供如 ...

  9. opengl,opengl es,egl,glfw,glew

    OpenGL ES之GLFW窗口搭建 - Plato - 博客园概述 本章节主要总结如何使用GLFW来创建Opengl窗口.主要包括如下内容: OpenGl窗口创建介绍 GLFW Window版编译 ...

  10. 学习OpenGL ES之透明和混合

    获取示例代码 本文主要讲解OpenGL ES对于透明颜色的处理,在例子中我绘制了三个平面,分别赋予绿色半透明纹理,红色半透明纹理,和不透明纹理. 首先为这三张图生成纹理. - (void)genTex ...

最新文章

  1. Qt Designer下的一些基础操作
  2. Delphi APP 開發入門(五)GPS 定位功能
  3. 中小型研发团队架构实践:电商如何做企业总体架构?
  4. 以前,第二周周考总结
  5. base64还原 java_base64字符串还原成原图片
  6. 【单词】常见单词含义的辨异(emulator/simulator、hardware/firmware)
  7. date_default_timezone_set()问题解决方案(PHP5.3以上的)
  8. 从一个小场景学会使用 apply方法
  9. 编写安全的驱动程序之验证驱动的调用者
  10. eWebEditor浏览器兼容 ie8 ie7
  11. java文字版格斗游戏
  12. HTML5期末大作业:我的家乡网站设计——我的家乡
  13. Windows打开dcm文件、dcm文件批量转其它图片文件格式
  14. java zipentry 压缩率_java – ZipEntry.STORED用于已经压缩的文件?
  15. 【中英】【吴恩达课后编程作业】Course 4 -卷积神经网络 - 第四周作业
  16. 【Python爬虫实战】【天天基金网】想要低风险+心动收益?5分钟学会筛选优质债券基金
  17. 获取UNIX主机当前时间的函数
  18. 安卓多渠道打包(三)360加固多渠道打包
  19. ZigBee 3.0实战教程-Silicon Labs EFR32+EmberZnet-3-01:BootLoader+Application的开发模式
  20. 放大招!百味勺子硬件设计篇

热门文章

  1. 开源大数据:MLSQL
  2. python读取文本数据--完善中
  3. python logging打印终端_python中那些小众但有用的自带标准库
  4. Vue学习笔记之18-网络请求模块的封装
  5. 大学c语言python_C语言和Python爬虫哪个好?老男孩IT教育
  6. zookeeper安装_Centos7安装配置Zookeeper
  7. ccf会议等级划分_Python计算山东新高考选考科目卷面原始成绩为等级成绩
  8. 在 ASP.NET 2.0 中创建 Web 应用程序主题(一)
  9. Redis sorted set(有序集合)
  10. 基于iOS用CoreImage实现人脸识别