-
EGL
- OpenGL ES是一个跨平台的图形库,在它能够工作之前,需要与一个实际的窗口系统关联起来,这与OpenGL是一样的。但不一样的是,这部份工作有标准,这个标 准就是EGL。而OpenGL时代在不同平台上有不同的机制以关联窗口系统,在Windows上是wgl,在X-Window上是xgl,在Apple OS上是agl等。
由上可以理解为,OpenGLES的使用,离不开EGL。而我们在使用GLSurfaceView时并不需要和EGL有所交集,是因为GLSurfaceView在内部做好了相关的工作,为我们使用OpenGLES创造好了环境。所以GLSurfaceView可以当做一个EGL使用的示例来看。
- OpenGL ES是一个跨平台的图形库,在它能够工作之前,需要与一个实际的窗口系统关联起来,这与OpenGL是一样的。但不一样的是,这部份工作有标准,这个标 准就是EGL。而OpenGL时代在不同平台上有不同的机制以关联窗口系统,在Windows上是wgl,在X-Window上是xgl,在Apple OS上是agl等。
- EGL的使用步骤
-
获取Display
Display代表显示器,在有些系统上可以有多个显示器,也就会有多个Display。获得Display要调用EGLboolean eglGetDisplay(NativeDisplay dpy),参数一般为 EGL_DEFAULT_DISPLAY 。该参数实际的意义是平台实现相关的 mEgl= (EGL10)EGLContext.getEGL(); mEglDisplay=mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
-
初始化egl
调用 EGLboolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor),该函数会进行一些内部初始化工作,并传回EGL版本号(major.minor)。int[] version=new int[2]; //主版本号和副版本号 mEgl.eglInitialize(mEglDisplay,version);
-
选择Config
所为Config实际指的是FrameBuffer的参数,
一般用EGLboolean eglChooseConfig(EGLDisplay dpy, const EGLint * attr_list, EGLConfig * config, EGLint config_size, EGLint *num_config),其中attr_list是以EGL_NONE结束的参数数组,通常以id,value依次存放,对于个别标识性的属性可以只有 id,没有value。
//选择Configint[] configNum=new int[1]; mEgl.eglChooseConfig(mEglDisplay,attributes,null,0,configNum); if(configNum[0]==0){ return GlError.ConfigErr; } EGLConfig[] c=new EGLConfig[configNum[0]]; mEgl.eglChooseConfig(mEglDisplay,attributes,c,configNum[0],configNum); mEglConfig=c[0];
-
构造Surface
Surface实际上就是一个FrameBuffer,通过 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig confg, NativeWindow win, EGLint *cfg_attr) 来创建一个可实际显示的Surface。系统通常还支持另外两种Surface:PixmapSurface和PBufferSurface,这两种都不 是可显示的Surface,PixmapSurface是保存在系统内存中的位图,PBuffer则是保存在显存中的帧。switch (surfaceType){ case SURFACE_WINDOW: return mEgl.eglCreateWindowSurface(mEglDisplay,mEglConfig,surface_native_obj,attr); case SURFACE_PIM: return mEgl.eglCreatePixmapSurface(mEglDisplay,mEglConfig,surface_native_obj,attr); default: return mEgl.eglCreatePbufferSurface(mEglDisplay,mEglConfig,attr); }
-
创建Context。
OpenGL的pipeline从程序的角度看就是一个状态机,有当前的颜色、纹理坐标、变换矩阵、绚染模式等一大堆状态,这些状态作用于程序提交的顶点 坐标等图元从而形成帧缓冲内的像素。在OpenGL的编程接口中,Context就代表这个状态机,程序的主要工作就是向Context提供图元、设置状 态,偶尔也从Context里获取一些信息。用EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write, EGLSurface read, EGLContext * share_list)来创建一个ContextEglContext=mEgl.eglCreateContext(mEglDisplay,mEglConfig,shareContext,contextAttr);
-
切换上下文
在完成EGL的初始化之后,需要通过eglMakeCurrent()函数来将当前的上下文切换,这样opengl的函数才能启动作用。
该接口将申请到的display,draw(surface)和 context进行了绑定。也就是说,在context下的OpenGLAPI指令将draw(surface)作为其渲染最终目的地。而display作为draw(surface)的前端显示。调用后,当前线程使用的EGLContex为context。boolean eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context)
-
绘制
应用程序通过OpenGL API进行绘制,一帧完成之后,调用eglSwapBuffers(EGLDisplay dpy, EGLContext ctx)来显示。 -
用完后释放资源
mEgl.eglMakeCurrent(mEglDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); mEgl.eglDestroySurface(mEglDisplay, mEglSurface); mEgl.eglDestroyContext(mEglDisplay, mEglContext); mEgl.eglTerminate(mEglDisplay);