大家好,今天来为大家解答深入浅出:EGL与OpenGL——连接设备与图形世界的桥梁这个问题的一些问题点,包括也一样很多人还不知道,因此呢,今天就来为大家分析分析,现在让我们一起来看看吧!如果解决了您的问题,还望您关注下本站哦,谢谢~
6、EGL
我们这里只讨论iOS/Android设备,所以这里的OpenGL也对应OpenGL ES。
如果我们了解OpenGL ES,我们就会知道,它虽然定义了一套针对移动设备的图像渲染API,但它并没有定义窗口系统。为了让GLES适应各种平台,GLES需要与一个知道如何通过操作系统创建和访问窗口的库结合使用。这是EGL。 EGL 是OpenGL ES 渲染API 和本机窗口系统之间的中间体。接口层,主要由系统厂商实现。 EGL 提供以下机制:
与设备原生窗口系统通信;查询可用的绘图层类型和配置;创建绘图层;同步OpenGL ES 和其他图形渲染API 之间的渲染;管理渲染资源,例如纹理贴图。EGL 是 OpenGL ES 与设备的桥梁,以实现让 OpenGL ES 能够在当前设备上进行绘制。EGL架构EGL架构
6.1、Android EGL
从Android平台2.0版本开始,图形系统的底层渲染已经由OpenGL ES处理。其EGL架构实现如下图所示:
Android EGL 架构Android EGL 架构
Display是实际显示设备的抽象。 Android上的实现类是EGLDisplay。Surface是FrameBuffer用于存储图像的内存区域的抽象,包括Color Buffer、Stencil Buffer、Depth Buffer。 Android上的实现类是EGLSurface。Context存储OpenGL ES绘图的一些状态信息。 Android上的实现类是EGLContext。本地窗口相关的API提供了访问本地窗口系统的接口,EGL可以创建渲染表面EGLSurface,同时还提供图形渲染上下文EGLContext用于状态管理。然后OpenGL ES就可以在这个渲染表面上进行绘制了。
使用EGL实现平台渲染的步骤大致如下:
1)调用eglGetDisplay获取EGLDisplay对象,因此建立与平台窗口系统的联系,这个EGLDisplay将作为OpenGL ES的渲染目标; 2)调用eglInitialize初始化 EGL; 3)调用eglChooseConfig获取EGLConfig对象,所以确定渲染表面的配置信息; 4)通过EGLDisplay和EGLConfig对象,调用eglCreateWindowSurface或eglCreatePbufferSurface方法获取EGLSurface,即创建渲染表面,其中eglCreateWindowSurface用于创建屏内渲染区域,eglCreatePbufferSurface用于创建离屏渲染区域; 5)通过EGLDisplay和EGLConfig,调用eglCreateContext获取EGLContext对象,因此创建渲染上下文,OpenGL的任何指令都必须在自己的OpenGL上下文中执行; 6) 调用eglMakeCurrent将EGLSurface、EGLContext和EGLDisplay绑定到完成了上下文绑定。绑定成功后,OpenGL ES环境就创建好了,可以开始渲染了;通过上面的步骤,你已经为EGL做好了准备:一方面,为OpenGL ES渲染提供了目标EGLDisplay和上下文环境EGLContext,可以接收OpenGL ES渲染的纹理;另一方面,为OpenGL ES渲染提供目标EGLDisplay和上下文环境EGLContext。一方面,我们连接了设备显示EGLSurface(这可能是SurfaceView或TextureView)。接下来,由于OpenGL ES渲染必须打开一个新的线程,并将显示设备和上下文(EGLContext)绑定到该线程,因此使用eglMakeCurrent()来绑定该线程的显示设备和上下文。
7)OpenGL ES完成绘制后,调用eglSwapBuffers方法交换前后缓冲,将绘制内容显示到屏幕上,但离屏渲染不需要调用该方法;这里需要注意的是,EGL的工作模式是双缓冲模式,其内部有两个FrameBuffer。BackFrameBuffer和FrontFrameBuffer,当EGL在屏幕上显示一个FrameBuffer时,另一个FrameBuffer在后台等待OpenGL ES渲染输出。
直到调用eglSwapBuffer()指令,前台FrameBuffer和后台FrameBuffer才进行交换。此时界面呈现的是OpenGL ES刚刚渲染的内容。
这样做的原因是,如果应用程序使用单缓冲区绘制,可能会出现图像闪烁的问题,因为图像生成不是一次绘制,而是从左到右、从上到下逐像素绘制。如果最终的图像没有瞬间完全显示给用户,但是也显示了绘制过程,这就会导致用户看到的渲染效果出现闪烁。为了避免这个问题,可以使用双缓冲渲染:前缓冲区存储最终输出图像,该图像将显示在屏幕上;所有渲染指令都会绘制在后台缓冲区上,从左到右、从上到下屏蔽用户。进行逐像素绘制的过程,这样就可以避免闪烁。
8)绘制完成后,当不再需要使用EGL时,需要调用eglMakeCurrent取消绑定,并调用eglDestroyContext、eglDestroySurface、eglTerminate等函数销毁EGLDisplay、EGLSurface、EGLContext这三个对象。您可以在《RenderDemo(1):用 OpenGL 画一个三角形》 Android Demo的KFGLContext类中看到上述过程。
不过,如果你觉得上面配置EGL的过程太麻烦,Android平台提供了GLSurfaceView类来实现对Display、Surface、Context的管理。即GLSurfaceView内部实现了对EGL的封装,可以方便的使用接口GLSurfaceView.Renderer。实现,使用OpenGL ES API进行渲染和绘图。 GLSurfaceView提高了OpenGL ES开发的便利性,但当然也失去了一些灵活性。
参考:
EGL的作用和使用[1]EGL[2]
6.2、iOS EAGL
EGL在iOS平台的实现是EAGL(Embedded Apple Graphics Library)。 OpenGL ES系统和原生窗口(UIKit)系统之间的桥梁是由EAGL上下文系统实现的。
与Android EGL不同,iOS EAGL不允许应用程序直接绘制到BackFrameBuffer和FrontFrameBuffer,也不允许应用程序直接控制双缓冲区的交换(swap)。系统保留这些操作权限,以便Core可以随时使用。动画合成器控制显示的最终外观。
Core Animation 是 iOS 上图形渲染和动画的核心基础架构。您可以使用托管各种iOS 系统内容(UIKit、Quartz 2D、OpenGL ES)的图层来组成应用程序的用户界面或其他视觉显示。
OpenGL ES 通过CAEAGLLayer 连接到Core Animation。 CAEAGLLayer 是一种特殊类型的核心动画层。其内容来自OpenGL ES的RenderBuffer。 Core Animation 将RenderBuffer 的内容与其他层合成,并将生成的图像显示在屏幕上。所以可以同时有任意数量的层。核心动画合成器组合这些层并在后帧缓冲区中生成最终像素颜色,然后切换缓冲区。
Core Animation 与OpenGL ES 共享RenderBufferCore Animation 与OpenGL ES 共享RenderBuffer
应用程序提供的图层与操作系统提供的图层混合以产生最终的显示外观。如下图所示,OpenGL ES层显示的是应用程序生成的旋转立方体,但显示器顶部的显示状态栏层是由操作系统生成和控制的。该图显示了两层合并以产生后置帧缓冲区中颜色数据的过程。交换之后,我们看到的是前端帧缓冲区上的内容。
iOS 多层合成iOS 多层合成
因此,iOS的EAGL配置过程实际上就是利用CoreAnimation的layer来支持OpenGL ES渲染的过程。步骤大致如下:
1)创建EAGL图层CAEAGLLayer对象并设置其属性; 2)创建OpenGL ES上下文EAGLContext并将其设置为当前上下文; 3)创建颜色渲染缓冲对象ColorRenderBuffer,并调用renderbufferStorage:fromDrawable:为其分配存储空间,这里实际上是共享CAEAGLLayer的绘图存储区域作为ColorRenderBuffer的绘图缓冲区。分配缓冲区所需的宽度、高度、像素格式等信息将从图层中获取;需要注意的是,如果CAEAGLLayer的bounds或者其他属性发生变化,则需要重新分配ColorRenderBuffer的存储空间,否则会出现ColorRenderBuffer和CAEAGLLayer的大小不一致的情况。不匹配。
4)创建帧缓冲区FrameBuffer对象,并绑定ColorRenderBuffer作为其附件; 5) 从颜色渲染缓冲区ColorRenderBuffer中获取宽度和高度信息; 6)根据需要创建深度渲染缓冲区DepthRenderBuffer对象,并将其绑定为FrameBuffer Attachment; 7)根据需要检测FrameBuffer的状态; 8)将CAEAGLLayer添加到Core Animation的图层树中; 9)绘制动作完成后,调用EAGLContext的presentRenderbuffer:方法将绘制结果显示在屏幕上。《RenderDemo(1):用 OpenGL 画一个三角形》 iOS Demo 的DMTriangleRenderView 类中也可以看到类似的过程,只不过在Demo 中我们创建了UIView 的子类,并重写了它的+layerClass 方法,返回CAEAGLLayer 类型,从而获得了用于OpenGL ES 渲染的CAEAGLLayer 对象。
同样,如果你觉得上面的过程太繁琐,iOS平台也提供了封装的GLKView来简化我们对OpenGL ES的使用。 GLKView是对CAEAGLLayer的封装,并嵌入了配置Core Animation以支持OpenGL ES的过程。
参考:
iOS OpenGL ES 应用开发实践指南[3] iOS OpenGL ES 编程指南[4] iOS 中OpenGL ES 上下文环境搭建[5]
参考资料
[1]
EGL:https://blog.csdn.net/u010281924/article/details/105296617的作用和使用
[2]
EGL:https://blog.csdn.net/Kennethdroid/article/details/99655635
[3]
iOS OpenGL ES应用开发实践指南:https://book.douban.com/subject/24849591/
[4]
iOS OpenGL ES 编程指南:https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/WorkingwithEAGLContexts/WorkingwithEAGLContexts.html
[5]
iOS中OpenGL ES上下文环境搭建:https://www.jianshu.com/p/c34c14589e0c
【深入浅出:EGL与OpenGL——连接设备与图形世界的桥梁】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
终于学习到 OpenGL 和 EGL 的关系了,之前一直感觉两者好像有点像亲兄弟一样,原来是相互连接!
有8位网友表示赞同!
做音视频开发的朋友应该都知道 EGL 的重要性吧!它就像手机里处理声音和画面的那一块大脑。
有15位网友表示赞同!
看来这篇博客要详细讲解 EGL 作为 OpenGL 和设备的桥梁的作用,真是期待!
有5位网友表示赞同!
对 OpenGL 不是很了解,这篇文章可以让我了解一下 EGL 在其中所扮演的角色?
有14位网友表示赞同!
我一直以为 OpenGL 就直接和硬件交互啊,没想到还有 EGL 这层连接!
有10位网友表示赞同!
要成为一个合格的音视频开发人员,掌握OpenGL 和 EGL 都是必不可少的技能。
有8位网友表示赞同!
看标题就知道这篇文章很适合我,以前一直想学习 OpenGL 基础概念。
有20位网友表示赞同!
最近在研究图形渲染技术,这篇文章刚好对目标!
有15位网友表示赞同!
感谢作者分享这段宝贵的知识!让我们更清楚地了解 OpenGL 和设备之间的连接。
有9位网友表示赞同!
这篇博客能帮助我们更快更有效率地学习 OpenGL 的基础概念。
有12位网友表示赞同!
我觉得 EGL 在计算机图形学领域非常重要,它让开发者与硬件更紧密地协作。
有9位网友表示赞同!
我已经很期待这篇文章深入讲解 EGL 的原理和使用方法了。
有17位网友表示赞同!
这篇博客文章的标题很有吸引力,我迫不及待想读下去!
有8位网友表示赞同!
OpenGL 和设备之间的桥梁,这真是一个很形象的比喻!
有5位网友表示赞同!
学习 OpenGL 不容易,但有了 EGL 这样强大的工具,相信更容易上手。
有20位网友表示赞同!
希望这篇博文能够详细解释 EGL 的各个功能和应用场景。
有18位网友表示赞同!
掌握了 OpenGL 和 EGL ,我们就能开发出更精彩的音视频作品!
有17位网友表示赞同!
感谢作者的贡献!期待看到更多关于 OpenGL 和 EGL 的精彩文章。
有10位网友表示赞同!
这篇文章将是学习 OpenGL 基础概念的重要参考!
有12位网友表示赞同!