OpenGL ES:EGL环境创建

在Android平台上,虽说系统自带的GLSurfaceView这个控件中已经帮我们创建好EGL环境了,一般来说使用GLSurfaceView就可以满足我们的需求了。

而当我们用不着GLSurfaceView的时候,那又如何自己创建EGL环境呢?因此就来探究下 EGL环境的创建。

在Java层,EGL封装了两套框架

  1. 位于javax.microedition.khronos.egl包下的EGL10
  2. 位于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等等。

流程如下:

  • EGLDisplay,获取默认的显示设备(渲染的目标),并初始化
  • EGLConfig,配置参数来获取EGL支持的EGLConfig
  • EGLContext,创建上下文环境
  • EGLSurface,创建EGLSurface来连接EGL和设备的屏幕

获取并初始化EGLDisplay

所谓显示设备,也就是我们OpenGL渲染的目标,也可以说就是我们的屏幕,而EGLDisplay是一个封装了物理屏幕的数据类型。

一般来说我们都需要对获取的结果进行验证,如果没获取到抛出异常即可。

		//获取默认的显示设备,渲染的目标
        mEglDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY);
        if (mEglDisplay == EGL14.EGL_NO_DISPLAY) {
            throw new RuntimeException("egl no display!");
        }
        //初始化显示设备,主次版本号
        int[] version = new int[2];
        if (!EGL14.eglInitialize(mEglDisplay, version, 0, version, 1)){
            mEglDisplay = null;
            throw new RuntimeException("eglInitialize error");
        }

获取EGLConfig

当获取到EGLDisplay后,我们需要指定一些配置项,例如色彩格式、像素格式、RGBA的表示以及SurfaceType等,实际上也就是指FrameBuffer的配置参数。

EGL的参数配置在数组中以 id,value 依次存放,对于个别的属性可以只有 id 没有 value ,结尾需要用EGL_NONE标识。

eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size,EGLint *num_config)

attrib_list:配置参数列表
configs:返回输出的EGLConfigs数据,可能有多个;
config_size:表示最多需要输出多少个EGLConfig;
num_config:表示满足配置参数的EGLConfig的个数。

 //配置输出的格式 也就是制定FrameBuffer的配置参数
        int[] attrList = {
                EGL14.EGL_RED_SIZE,8,//颜色缓冲区中红色的位数
                EGL14.EGL_GREEN_SIZE,8,
                EGL14.EGL_BLUE_SIZE,8,
                EGL14.EGL_ALPHA_SIZE,8,
                EGL14.EGL_RENDERABLE_TYPE,EGL14.EGL_OPENGL_ES2_BIT,//渲染窗口支持的布局组成
                EGL14.EGL_SURFACE_TYPE,EGL14.EGL_PBUFFER_BIT, //egl支持的窗口类型
                EGL14.EGL_NONE
        };
	
	EGLConfig[] configs = new EGLConfig[1];
        int[] numConfigs = new int[1];
        if (!EGL14.eglChooseConfig(mEglDisplay, attrList, 0, configs, 0, configs.length, numConfigs, 0)) {
            throw new RuntimeException("unable to find RGB888 ES2 EGL config");
        }

创建EGLContext

一个线程对应一个EGLContext,如果需要共享资源,则可在创建的时候设置即可。

int[] attriList = {
                EGL14.EGL_CONTEXT_CLIENT_VERSION, 2,
                EGL14.EGL_NONE
        };
        //第三个参数即为需要共享的上下文对象,资源包括纹理、FrameBuffer以及其他的Buffer等资源。
        mEglContext = EGL14.eglCreateContext(mEglDisplay, configs[0], EGL14.EGL_NO_CONTEXT, attriList, 0);
        checkEglError("eglCreateContext");
        if (mEglContext == null) {
            throw new RuntimeException("context is null");
        }

创建EGLSurface

最后则需要创建一个GLSurface,它的作用就是把我们的EGL和我们渲染的目标连接起来。

而我们的 EGLSurface也就是要给FrameBuffer,可以通过如下俩种方式创建。
EGL14.eglCreatePbufferSurface:创建离屏的Surface
EGL14.eglCreateWindowSurface:创建可以实际显示的Surface

	 //创建surface 离屏
        int[] surfaceAttribs = {
                EGL14.EGL_WIDTH, mWidth,
                EGL14.EGL_HEIGHT, mHeight,
                EGL14.EGL_NONE
        };
        mEglSurface = EGL14.eglCreatePbufferSurface(mEglDisplay, configs[0], surfaceAttribs, 0);
        checkEglError("eglCreatePbufferSurface");
        if (mEglSurface == null) {
            throw new RuntimeException("surface is null");
        }

        //非离屏 需要surface承载
        mEglSurfaceEncoder = EGL14.eglCreateWindowSurface(mEglDisplay, configEncoder,surface,new int[]{EGL14.EGL_NONE}, 0);
        checkEglError("eglCreatePbufferSurface");
        if (mEglSurface == null) {
            throw new RuntimeException("surface is null");
        }

注意:

EGL在初始化时默认设置的是双缓冲模式,也就是两份FrameBuffer;
一个用于绘制图像,一个用于显示图像,每次绘制完一帧都需要交换一次缓冲。
因此我们需要在OpenGL ES绘制完毕后,调用如下进行交换。

EGL14.eglSwapBuffers(mEglDisplay, mEglSurfaceEncoder);
全部评论

相关推荐

头像
03-14 11:23
已编辑
北京邮电大学 管理咨询
211勇闯初创小公司头破血流系列3这件事不是发生在我身上的,但前同事们参与创作的积极性空前高涨,为了习惯,还是都采用第一人称的视角来看这出大戏。有一天老板在我们的眼皮底下接了一个电话,最终敲定了去北京出差的时间,下周一。他得意洋洋地说,这单下来保底五百万的流水,如果成了,我们都能得到五位数的提成。这对于一群刚上班的人来说是天大的诱惑,我们经历了周末的无偿加班,把他去北京所需要的文件都准备好了。只是在去北京的周一当天,老板睡过头了。整个上午都没见他的踪影,给他发文件也不会,打电话问问题也不接,直到中午才姗姗来迟。当然,这只是拉开了这场恐怖出差的序幕。只见他来了也不紧不慢的,手指在办公室转了一圈,...
姜大力:补充: 1.五百万的单子根本没有五百万,只是过去展示拼装的产品并简单考察。该项目只是竞标,项目内容是商业街区改造; 2.决策是当天上午10点半左右老板珊珊来迟后突发奇想去北京,中午1点在催促下着急出发,没有任何出差补助; 3.出发之前已经知道进京证不好使了,但还是执意要开车去; 4.实习生实打实连续开了***小事车,非常辛苦,工资在转正后只有两千五; (有疑问会继续补充)
点赞 评论 收藏
分享
1. 事件概述3月10日下午,华为在“心声社区”发布长达6500字通报,曝光72名正式员工及19名非雇员在非雇员招聘中存在徇私舞弊行为,多人出卖公司信息资产获利,引发热议。- “非雇员”一般指华为OD员工,与人力服务公司签劳动合同,以派遣方式到华为工作,薪资待遇与华为内部员工基本一致,可通过考核转正。2. 相关传言与真相华为相关人士称暂无官方回应,很多传言细节不准确。 华为成都研究所员工透露,此次通报主要涉及成都研究所的数据存储部门,整个数据存储业务约100余人,此次明文通报除名辞退或通报批评的有62名,“很多部门基本全开除” 。网传任正非亲赴成都、封楼抓人等消息不实。早在2024年年中,就有...
七安有出处嘛:省流:任正非亲赴成都等消息不实,2024 年年中就有人举报了;涉及36名违规当事人,其中有13人被除名;10人有主动申报情节或情节较严重的,予以辞退处理;另有13人被劝退、个人职级降3等。另外还有26名相关管理责任人作为直接或间接管理者,被处以个人职级降6等,冻结个人涨薪、职级晋升、干部向上任命,冻结期6—12个月不等;若下属违规偶发,则仅通报批评。并没有释放100HC😂😂😂
点赞 评论 收藏
分享
小覃1:硕士了还投助理岗位吗,一般不都直接干工程师了吗
点赞 评论 收藏
分享
01-16 18:34
四川大学 Java
欢迎加入AI:没有啥稳定不稳定,一切都源于业务快速发展还是收缩。我当年一开始去的央企,业务不赚钱,也贼卷,慢慢就开始优化了。。。
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务