EGL接口介绍

来源:互联网 发布:网络贷款受法律保护吗 编辑:程序博客网 时间:2024/05/25 05:35
EGLOpenGL ES 和底层 Native 平台视窗系统之间的接口。本章主要讲述OpenGL ESEGL API ,以及如何用它创建 Context 和绘制Surface 等,并对用于 OpenGL 的其他视窗 API 做了比较分析,比如WGLGLX 。本章中将涵盖如下几个方面:

        EGL 综述

        EGL 主要构成( DisplayContextConfiguration

        BrewWindows CE 上使用 EGL

        EGL 和其他 OpenGL 视窗系统的比较

 

EGL 介绍

EGL 是为 OpenGL ES 提供平台独立性而设计。在本章中,你将详细地学习每个 EGL API ,并了解使用 EGL 时候需要注意的平台特性和限制。OpenGL ES 为附加功能和可能的平台特性开发提供了扩展机制,但仍然需要一个可以让OpenGL ES 和本地视窗系统交互且平台无关的层。 OpenGL ES 本质上是一个图形渲染管线的状态机,而 EGL 则是用于监控这些状态以及维护Frame buffer 和其他渲染 Surface 的外部层。图 2-1 是一个典型的EGL 系统布局图。

EGL 视窗设计是基于人们熟悉的用于 Microsoft WindowsWGL )和UNIXGLX )上的 OpenGLNative 接口,与后者比较接近。 OpenGL ES 图形管线的状态被存储于EGL 管理的一个 Context 中。 Frame Buffers 和其他绘制Surfaces 通过 EGL API 创建、管理和销毁。 EGL 同时也控制和提供了对设备显示和可能的设备渲染配置的访问。

EGL 数据类型

 

EGL包含了自己的一组数据类型,同时也提供了对一组平台相关的本地数据类型的支持。这些Native数据类型定义在EGL系统的头文件中。一旦你了解这些数据类型之间的不同,使用它们将变得很简单。多数情况下,为保证可移植性,开发人员将尽可能使用抽象数据类型而避免直接使用系统数据类型。通过使用定义在EGLNative类型,可以让你写的EGL代码运行在任意的EGL的实现上。Native EGL类型说明如下:

l        NativeDisplayType 平台显示数据类型,标识你所开发设备的物理屏幕

l        NativeWindowType 平台窗口数据类型,标识系统窗口

l        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];

};

接下来的小节中,我们将深入更多EGL数据类型细节。标准EGL数据类型如表2.1所示。

2.1 EGL数据类型

 

数据类型

EGLBoolean

EGL_TRUE =1, EGL_FALSE=0

EGLint

int 数据类型

EGLDisplay

系统显示 ID 或句柄

EGLConfig

Surface 的 EGL 配置

EGLSurface

系统窗口或 frame buffer 句柄

EGLContext

OpenGL ES 图形上下文

NativeDisplayType

Native 系统显示类型

NativeWindowType

Native 系统窗口缓存类型

NativePixmapType

Native 系统 frame buffer

EGL Displays

 

EGLDisplay 是一个关联系统物理屏幕的通用数据类型。对于PC 来说, Display 就是显示器的句柄。不管是嵌入式系统或 PC ,都可能有多个物理显示设备。为了使用系统的显示设备,EGL 提供了 EGLDisplay 数据类型,以及一组操作设备显示的 API

       下面的函数原型用于获取 Native Display

EGLDisplay eglGetDisplay (NativeDisplayType display);

其中 display 参数是 native 系统的窗口显示 ID 值。如果你只是想得到一个系统默认的Display ,你可以使用 EGL_DEFAULT_DISPLAY参数。如果系统中没有一个可用的native display ID 与给定的 display 参数匹配,函数将返回 EGL_NO_DISPLAY ,而没有任何Error 状态被设置。

由于设置无效的 display 值不会有任何错误状态,在你继续操作前请检测返回值。

下面是一个使用 EGL API 获取系统 Display 的例子:

m_eglDisplay = eglGetDisplay( system.display);

if (m_eglDisplay == EGL_NO_DISPLAY || eglGetError() != EGL_SUCCESS))

throw error_egl_display;

 

Initialization 初始化


    和很多视窗 API 类似, EGL 在使用前需要初始化,因此每个 EGLDisplay 在使用前都需要初始化。初始化EGLDisplay 的同时,你可以得到系统中 EGL 的实现版本号。了解当前的版本号在向后兼容性方面是非常有价值的。嵌入式和移动设备通常是持续的投放到市场上,所以你需要考虑到你的代码将被运行在形形色色的实现上。通过动态查询EGL 版本号,你可以为新旧版本的 EGL 附加额外的特性或运行环境。基于平台配置,软件开发可用清楚知道哪些 API 可用访问,这将会为你的代码提供最大限度的可移植性。

       下面是初始化 EGL 的函数原型:

              EGLBoolean eglInitialize (EGLDisplay dpy, EGLint *major, EGLint *minor);

其中 dpy 应该是一个有效的 EGLDisplay 。函数返回时, majorminor 将被赋予当前 EGL 版本号。比如 EGL1.0major 返回 1minor 则返回 0 。给 majorminorNULL 是有效的,如果你不关心版本号。

       eglQueryString() 函数是另外一个获取版本信息和其他信息的途径。通过eglQueryString() 获取版本信息需要解析版本字符串,所以通过传递一个指针给eglInitializ() 函数比较容易获得这个信息。注意在调用eglQueryString() 必须先使用 eglInitialize() 初始化 EGLDisplay ,否则将得到EGL_NOT_INITIALIZED 错误信息。

       下面是获取 EGL 版本字符串信息的函数原型:

const char * eglQueryString (EGLDisplay dpy, EGLint name);

参数name可以是EGL_VENDOR, EGL_VERSION,或者EGL_EXTENSIONS。这个函数最常用来查询有哪些EGL扩展被实现。所有EGL扩展都是可选的,如果你想使用某个扩展特性,请检查该扩展是否被实现了,而不要想当然假定已经实现了。如果没有扩展被实现,将返回一个Null字符串,如果给定的name参数无效,则会得到EGL_BAD_PARAMETER.错误信息。

 

初始化EGL

OpenGL ES是一个平台中立的图形库,在它能够工作之前,需要与一个实际的窗口系统关联起来,这与OpenGL是一样的。但不一样的是,这部份工作有标准,这个标 准就是EGL。而OpenGL时代在不同平台上有不同的机制以关联窗口系统,在Windows上是wgl,在X-Window上是xgl,在Apple OS上是agl等。EGL的工作方式和部份术语都接近于xgl。

OpenGL ES的初始化过程如下图所示意:

 

Display → Config → Surface

 

 

 

 

                      Context

 

 

 

 

Application → OpenGL Command

 


1. 获取Display。
Display代表显示器,在有些系统上可以有多个显示器,也就会有多个Display。获得Display要调用EGLboolean eglGetDisplay(NativeDisplay dpy),参数一般为 EGL_DEFAULT_DISPLAY 。该参数实际的意义是平台实现相关的,在X-Window下是XDisplay ID,在MS Windows下是Window DC。

2. 初始化egl。
调用 EGLboolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor),该函数会进行一些内部初始化工作,并传回EGL版本号(major.minor)。

3. 选择Config。
所为Config实际指的是FrameBuffer的参数,在MS Windows下对应于PixelFormat,在X-Window下对应Visual。一般用EGLboolean eglChooseConfig(EGLDisplay dpy, const EGLint * attr_list, EGLConfig * config, EGLint config_size, EGLint *num_config),其中attr_list是以EGL_NONE结束的参数数组,通常以id,value依次存放,对于个别标识性的属性可以只有 id,没有value。另一个办法是用EGLboolean eglGetConfigs(EGLDisplay dpy, EGLConfig * config, EGLint config_size, EGLint *num_config) 来获得所有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, EGLContext ctx)来显示。

0 0
原创粉丝点击