Android中EGL的使用步骤

  • EGL
    • OpenGL ES是一个跨平台的图形库,在它能够工作之前,需要与一个实际的窗口系统关联起来,这与OpenGL是一样的。但不一样的是,这部份工作有标准,这个标 准就是EGL。而OpenGL时代在不同平台上有不同的机制以关联窗口系统,在Windows上是wgl,在X-Window上是xgl,在Apple OS上是agl等。
      由上可以理解为,OpenGLES的使用,离不开EGL。而我们在使用GLSurfaceView时并不需要和EGL有所交集,是因为GLSurfaceView在内部做好了相关的工作,为我们使用OpenGLES创造好了环境。所以GLSurfaceView可以当做一个EGL使用的示例来看。
  • EGL的使用步骤
  1. 获取Display
    Display代表显示器,在有些系统上可以有多个显示器,也就会有多个Display。

    获得Display要调用EGLboolean eglGetDisplay(NativeDisplay dpy),参数一般为 EGL_DEFAULT_DISPLAY 。该参数实际的意义是平台实现相关的
    mEgl= (EGL10)EGLContext.getEGL();
    mEglDisplay=mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
    
  2. 初始化egl
    调用 EGLboolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor),该函数会进行一些内部初始化工作,并传回EGL版本号(major.minor)。

    int[] version=new int[2]; //主版本号和副版本号
    mEgl.eglInitialize(mEglDisplay,version);
    
  3. 选择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。
    //选择Config

    int[] 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];
    
  4. 构造Surface
    Surface实际上就是一个FrameBuffer,通过 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig confg, NativeWindow win, EGLint *cfg_attr) 来创建一个可实际显示的Surface。系统通常还支持另外两种Surface:PixmapSurfacePBufferSurface,这两种都不 是可显示的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);
    }
    
  5. 创建Context。
    OpenGL的pipeline从程序的角度看就是一个状态机,有当前的颜色、纹理坐标、变换矩阵、绚染模式等一大堆状态,这些状态作用于程序提交的顶点 坐标等图元从而形成帧缓冲内的像素。在OpenGL的编程接口中,Context就代表这个状态机,程序的主要工作就是向Context提供图元、设置状 态,偶尔也从Context里获取一些信息。用EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write, EGLSurface read, EGLContext * share_list)来创建一个Context

    EglContext=mEgl.eglCreateContext(mEglDisplay,mEglConfig,shareContext,contextAttr);
    
  6. 切换上下文
    在完成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)
    
  7. 绘制
    应用程序通过OpenGL API进行绘制,一帧完成之后,调用eglSwapBuffers(EGLDisplay dpy, EGLContext ctx)来显示。

  8. 用完后释放资源

    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);
    

你可能感兴趣的:(OpenGL)