EGL 的使用

发表于2016-05-22
评论1 4.2k浏览
一、EGL使用:
  EGL 是为 OpenGL ES 提供平台独立性而设计。OpenGL ES 为附加功能和可能的平台特性开发提供了扩展机制,但仍然需要一个可以让 OpenGL ES 和本地视窗系统交互且平台无关的层。 OpenGL ES 本质上是一个图形渲染管线的状态机,而 EGL 则是用于监控这些状态以及维护 Frame buffer 和其他渲染 Surface 的外部层。
  EGL 视窗设计是基于人们熟悉的用于 Microsoft Windows ( WGL )和 UNIX ( GLX )上的 OpenGL 的 Native 接口,与后者比较接近。 OpenGL ES 图形管线的状态被存储于 EGL 管理的一个 Context 中。 Frame Buffers 和其他绘制 Surfaces 通过 EGL API 创建、管理和销毁。 EGL 同时也控制和提供了对设备显示和可能的设备渲染配置的访问。OpenGL ES的初始化过程如下图所示意:
  Display → Config → Surface ↑ Context ↑ Application → OpenGL Command

二、EGL 数据类型
  EGL 包含了自己的一组数据类型,同时也提供了对一组平台相关的本地数据类型的支持。这些 Native 数据类型定义在 EGL 系统的头文件中。一旦你了解这些数据类型之间的不同,使用它们将变得很简单。多数情况下,为保证可移植性,开发人员将尽可能使用抽象数据类型而避免直接使用系统数据类型。通过使用定义在 EGL 中 Native 类型,可以让你写的 EGL 代码运行在任意的 EGL 的实现上。 Native EGL 类型说明如下:
NativeDisplayType 平台显示数据类型,标识你所开发设备的物理屏幕
NativeWindowType 平台窗口数据类型,标识系统窗口
NativePixmapType 可以作为 Framebuffer 的系统图像(内存)数据类型,该类型只用于  离屏渲染
  下面的代码是一个 NativeWindowType 定义的例子。这只是一个例子,不同平台之间的实现千差万别。使用 native 类型的关键作用在于为开发者抽象化这些细节。 QUALCOMM 使用 IDIB 结构定义 native 类型,如下:
struct IDIB {
AEEVTBL(IBitmap) *pvt; // virtual table pointer
IQueryInterface * pPaletteMap; // cache for computed palette mapping info
byte * pBmp; // pointer to top row
uint32 * pRGB; // palette
NativeColor ncTransparent; // 32-bit native color value
uint16 cx; // number of pixels in width
uint16 cy; // number of pixels in height
int16 nPitch; // offset from one row to the next
uint16 cntRGB; // number of palette entries
uint8 nDepth; // size of pixel in bits
uint8 nColorScheme; // IDIB_COLORSCHEME_…(ie. 5-6-5)
uint8 reserved[6];
};

三、如何使用:
1、获取Display:
  Display代表显示器,在有些系统上可以有多个显示器,也就会有多个Display。(Sam觉得这个观点有点牵强,Sam觉得Display理解为显存Framebuffer比较合适一些)。获得Display要调用EGLboolean eglGetDisplay(NativeDisplay dpy),参数一般为 EGL_DEFAULT_DISPLAY 。该参数实际的意义是平台实现相关的,在X-Window下是XDisplay ID,在MS Windows下是Window DC。EGL(Boardcom)为NativeDisplayType。
  Sam: 所以在不同平台开发时,第一件需要确认的就是:这个平台上的display概念是的实现是什么?
2、初始化egl:
  调用 EGLboolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor),该函数会进行一些内部初始化工作,并传回EGL版本号(major.minor)。
3、Config的选择:
  Config指的是FrameBuffer的参数,在Windows下对应于PixelFormat,在X-Window下对应Visual。在EGL(Boardcom)下也指PixelFormat. 一般用
  EGLboolean eglChooseConfig(EGLDisplay dpy, const EGLint * attr_list, EGLConfig * config, EGLint config_size, EGLint *num_config);
  参数1:dpy: display.
  参数2:attr_list: 使用这个参数,来选中符合的config.
  参数3:config: 将符合的config,放到这里。
  参数4:想要选中符合的config的最大个数。
  参数5:真正选中的符合的config的个数。
  其中attr_list是以EGL_NONE结束的参数数组,通常以id,value依次存放,对于个别标识性的属性可以只有 id,没有value。
  另一个办法是用:
  EGLboolean eglGetConfigs(EGLDisplay dpy, EGLConfig * config, EGLint config_size, EGLint *num_config) 来获得所有config。
  参数1:dpy, display.
  参数2:输出参数,会在其中放置config.
  参数3:config_size: 取config的个数。
  参数4:num_config: 当参数2为空时,返回全部config个数。当参数2不为空时,返回读取config的个数。
  这两个函数都会返回不多于config_size个Config,结果保存在config[]中,系统的总Config个数保存在num_config中。可以利用eglGetConfig()中间两个参数为0来查询系统支持的Config总个数。
  Config有众多的Attribute,这些Attribute决定FrameBuffer的格式和能力,通过eglGetConfigAttrib ()来读取,但不能修改。
4、构造Surface:
  Surface实际上就是一个FrameBuffer,通过 EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig confg, NativeWindow win, EGLint *cfg_attr) 来创建一个可实际显示的Surface。系统通常还支持另外两种Surface:PixmapSurface和PBufferSurface,这两种都不是可显示的Surface,PixmapSurface是保存在系统内存中的位图,PBuffer则是保存在显存中的帧。
  Surface也有一些attribute,基本上都可以故名思意, EGL_HEIGHT EGL_WIDTH EGL_LARGEST_PBUFFER EGL_TEXTURE_FORMAT EGL_TEXTURE_TARGET EGL_MIPMAP_TEXTURE EGL_MIPMAP_LEVEL,通过eglSurfaceAttrib()设置、eglQuerySurface()读取。
5、创建Context:
  OpenGL的pipeline从程序的角度看就是一个状态机,有当前的颜色、纹理坐标、变换矩阵、绚染模式等一大堆状态,这些状态作用于程序提交的顶点坐标等图元从而形成帧缓冲内的像素。在OpenGL的编程接口中,Context就代表这个状态机,程序的主要工作就是向Context提供图元、设置状态,偶尔也从Context里获取一些信息。
  用EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write, EGLSurface read, EGLContext * share_list)来创建一个Context。
6、绘制:
  应用程序通过OpenGL API进行绘制,一帧完成之后,调用eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)来显示。
  参考:https://www.khronos.org/egl

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引