• EGL接口 简单介绍


    from http://lyodev.appspot.com

     

    第二章 EGL 接口

    EGL OpenGL ES 和底层 Native 平台视窗系统之间的接口。本章主要讲述 OpenGL ES EGL API ,以及怎样用它创建 Context 和绘制 Surface 等,并对用于 OpenGL 的其它视窗 API 做了比較分析,比方 WGL GLX 。本章中将涵盖例如以下几个方面:

    l          EGL 综述

    l          EGL 主要构成( Display Context Configuration

    l          Brew Windows CE 上使用 EGL

    l          EGL 和其它 OpenGL 视窗系统的比較

     

    EGL 介绍

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

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

    EGL 数据类型

    EGL 包括了自己的一组数据类型,同一时候也提供了对一组平台相关的本地数据类型的支持。这些 Native 数据类型定义在 EGL 系统的头文件里。一旦你了解这些数据类型之间的不同,使用它们将变得非常easy。多数情况下,为保证可移植性,开发者将尽可能使用抽象数据类型而避免直接使用系统数据类型。通过使用定义在 EGL Native 类型,能够让你写的 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 。函数返回时, major minor 将被赋予当前 EGL 版本。比方 EGL1.0 major 返回 1 minor 则返回 0 。给 major minor NULL 是有效的,假设你不关心版本。

           eglQueryString() 函数是另外一个获取版本号信息和其它信息的途径。通过 eglQueryString() 获取版本号信息须要解析版本号字符串,所以通过传递一个指针给 eglInitializ() 函数比較easy获得这个信息。注意在调用 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 Configurations

    EGLConfigs 是一个用来描写叙述 EGL surface 配置信息的数据类型。要获取正确的渲染结果, Surface 的格式是很重要的。依据平台的不同, surface 配置可能会有限制,比方某个设备仅仅支持 16 位色深显示,或是不支持 stencil buffer ,还有其它的功能限制或精度的差异。

           以下是获取系统可用的 EGL 配置信息的函数原型:

    EGLBoolean eglGetConfigs (EGLDisplay dpy, EGLConfig *configs,EGLint config_size, EGLint *num_config);

    參数 configs 将包括在你的平台上有效的全部 EGL framebuffer 配置列表。支持的配置总数将通过 num_config 返回。实际返回的 configs 的配置个数依赖于程序传入的 config_size 。假设 config_size < num_config ,则不是全部的配置信息都将被返回。假设想获取系统支持的全部配置信息,最好的办法就是先给 eglGetConfig 传一个 NULL configs 參数, num_config 将得到系统所支持的配置总数,然后用它来给 configs 分配合适的内存大小,再用得到的 configs 来调用 eglGetConfig

           以下是假设使用 eglGetConfig() 函数的样例:

    EGLConfig *configs_list;

    EGLint num_configs;

    // Main Display

    m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);

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

    return FALSE;

    if( eglInitialize( m_eglDisplay, NULL, NULL ) == EGL_FALSE || eglGetError() != EGL_SUCCESS )

    return FALSE;

    // find out how many configurations are supported

    if ( eglGetConfigs( m_eglDisplay, NULL, 0, &num_configs)

    == EGL_FALSE || eglGetError() != EGL_SUCCESS )

    return FALSE;

    configs_list = malloc(num_configs * sizeof(EGLConfig));

    if (configs_list == (EGLConfig *)0)

    return FALSE;

    // Get Configurations

    if( eglGetConfigs( m_eglDisplay, configs_list, num_configs, &num_configs)

    == EGL_FALSE || eglGetError() != EGL_SUCCESS )

    return FALSE;

    因为当前平台的限制,通常仅仅有非常少的配置可用。系统支持的配置一般是利用系统硬件提供最好的性能。当你移植游戏到多个平台,它们的 EGL 配置可能会有细微的区别,我们希望作为通用的移植问题来直接处理这些问题。

     

    选择一个 EGL Configuration

    基于 EGL 的属性,你能够定义一个希望从系统获得的配置,它将返回一个最接近你的需求的配置。选择一个你特有的配置是有点不合适的,由于仅仅是在你的平台上使用有效。 eglChooseConfig() 函数将适配一个你所期望的配置,而且尽可能接近一个有效的系统配置。

           以下是选择一个 EGL 配置的函数原型:

    EGLBoolean eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list,

    EGLConfig *configs, EGLint config_size, EGLint * num_config);

    參数 attrib_list 指定了选择配置时须要參照的属性。參数 configs 将返回一个依照 attrib_list 排序的平台有效的全部 EGL framebuffer 配置列表。參数 config_size 指定了能够返回到 configs 的总配置个数。參数 num_config 返回了实际匹配的配置总数。

           以下是假设使用 eglChoosetConfig() 函数的样例:

           EGLint attrs[3] = { EGL_DEPTH_SIZE, 16, EGL_NONE };

    EGLint num_configs;

    EGLConfigs *configs_list;

    // Get the display device

    if ((eglDisplay = eglGetDisplay(EGL_NO_DISPLAY)) == EGL_NO_DISPLAY)

    {

    return eglGetError();

    }

    // Initialize the display

    if (eglInitialize(eglDisplay, NULL, NULL) == EGL_FALSE)

    {

    return eglGetError();

    }

    // Obtain the total number of configurations that match

    if (eglChooseConfig(eglDisplay, attrs, NULL, 0, &num_configs) == EGL_FALSE)

    {

    return eglGetError();

    }

    configs_list = malloc(num_configs * sizeof(EGLConfig));

    if (configs_list == (EGLConfig *)0)

    return eglGetError();

    // Obtain the first configuration with a depth buffer of 16 bits

    if (!eglChooseConfig(eglDisplay, attrs, &configs_list, num_configs, &num_configs))

    {

    return eglGetError();

    }

    假设找到多个合适的配置,有一个简单的排序算法用来匹配最接近你所查询的配置。表 2-2 显示了基于属性值的用来选择和排序的顺序,也包含了 EGL 规范中全部 EGL 配置属性及其默认值。

    2.1 EGL 配置属性默认值和匹配法则

    属性

    数据类型

    默认值

    排序优先级

    选择顺序

    EGL_BUFFER_SIZE

    int

    0

    3

    Smaller value

    EGL_RED_SIZE

    int

    0

    2

    Larger value

    EGL_GREEN_SIZE

    int

    0

    2

    Larger value

    EGL_BLUE_SIZE

    int

    0

    2

    Larger value

    EGL_ALPHA_SIZE

    int

    0

    2

    Larger value

    EGL_CONFIG_CAVET

    enum

    EGL_DONT_CARE

    1(first)

    Exact value

    EGL_CONFIG_ID

    int

    EGL_DONT_CARE

    9

    Exact value

    EGL_DEPTH_SIZE

    int

    0

    6

    Smaller value

    EGL_LEVEL

    int

    0

    -

    Equal value

    EGL_NATIVE_RENDERABLE

    Boolean

    EGL_DONT_CARE

    -

    Exact value

    EGL_NATIVE_VISUAL_TYPE

    int

    EGL_DONT_CARE

    8

    Exact value

    EGL_SAMPLE_BUFFERS

    int

    0

    4

    Smaller value

    EGL_SAMPLES

    int

    0

    5

    Smaller value

    EGL_STENCIL_SIZE

    int

    0

    7

    Smaller value

    EGL_SURFACE_TYPE

    bitmask

    EGL_WINDOW_BIT

    -

    Mask value

    EGL_TRANSPARENT_TYPE

    enum

    EGL_NONE

    -

    Exact value

    EGL_TRANSPARENT_RED_VALUE

    int

    EGL_DONT_CARE

    -

    Exact value

    EGL_TRANSPARENT_GREEN_VALUE

    int

    EGL_DONT_CARE

    -

    Exact value

    EGL_TRANSPARENT_BLUE_VALUE

    int

    EGL_DONT_CARE

    -

    Exact value


  • 相关阅读:
    Swift学习-Property
    Swift学习-protocol
    Swift学习-Class
    Swift学习-Enumerate、Structure
    iOS“此时无法下载应用”解决办法
    iTunes Connect用户职能与权限
    TestFlight Beta Testing 开发指南中英对照
    梳理一下KVC
    mac下使用github 上传代码(转)
    运用Runtime全局修改UILabel的默认字体
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4074331.html
Copyright © 2020-2023  润新知