(三)EGL简介

2019-10-10  本文已影响0人  YongtaoHuang

上一篇:(二)你好,三角形:https://www.jianshu.com/p/4dfd7510178e
下一篇:(四)着色器和程序:https://www.jianshu.com/p/b1b4656cef9e

作为Khronos组织为开发内容所提供的API家族的一员,平台无关的API-EGL可以用于管理绘图表面。EGL提供以下机制:
1、与设备的原生窗口系统通信
2、查询绘图表面的可用类型和配置
3、创建绘图表面
4、在OpenGL ES 3.0和其他图形渲染API之间同步渲染
5、管理纹理贴图等渲染资源

与窗口系统通信

EGL提供了OpenGL ES 3.0和运行机器上的原生窗口系统之间的结合,两者之间有通信渠道。
EGLDisplay封装了所有系统相关性。

EGLDisplay eglGetDisplay(EGLNativeDisplayType displayId)
// displayId的默认值是EGL_DEFAULT_DISPLAY

初始化EGL的代码:

EGLint majorVersion;
EGLint minorVersion;
EGLDisplay display = eglGetDisplay ( EGL_DEFAULT_DISPLAY );
if ( display == EGL_NO_DISPLAY ) {
    // 连接不可用
}
if ( !eglInitialize ( display, &majorVersion, &minorVersion ) ) {
    // 初始化,若无法初始化,打log报错
}

检查错误

EGL中大部分函数执行成功时返回EGL_TRUE,失败时返回EGL_FALSE。eglGetError()函数可以指示故障原因。

EGLint eglGetError();

初始化EGL

成功打开连接后,需要初始化EGL:

EGLBoolean eglInitialize(EGLDisplay display, // 指定EGL显示连接
    EGLint *majorVersion, // 主版本号
    EGLint *minorVersion) // 次版本号

确定可用表面配置

初始化成功后,就可以确定可用渲染表面的类型和配置。指定一组需求,让EGL推荐最佳匹配:

EGLBoolean eglGetConfigs(EGLDisplay display, // 指定EGL显示连接
    EGLConfig *configs, // 指定configs列表
    EGLint maxReturnConfigs, // 指定configs大小
    EGLint *numConfigs) // 指定返回configs大小

查询EGLConfig属性

如何检索与EGLConfig相关的EGL值,包括可用颜色,相关缓冲区,表面类型和许多其他特性:

EGLBoolean eglGetConfigAttrib(EGLDisplay display, // 指定EGL显示连接
    EGLConfig config, // 指定需要查询的配置
    EGLint attribute, // 指定返回的特定属性
    EGLint *value) // 指定返回值

让EGL选择配置

让EGL选择匹配的EGLConfig:

EGLBoolean eglChooseConfig(EGLDisplay display, // 指定EGL显示连接 
    const EGLint *attribList,  // 指定configs匹配的属性列表
    EGLConfig *configs, // 指定配置列表
    EGLint maxReturnConfigs, // 指定配置的大小
    EGLint *numConfigs) // 指定返回的配置大小

创建屏幕上的渲染区域:EGL窗口

一旦我们有了符合渲染需求的EGLConfig,就为创建窗口做好了准备。创建窗口函数:

EGLSurface eglCreateWindowSurface(EGLDisplay display, // 指定EGL显示连接 
    EGLConfig config, // 指定配置
    EGLNativeWindowType window, // 指定原生窗口
    const EGLint *attribList) // 指定窗口属性列表

创建屏幕外的渲染区域:EGL Pbuffer

OpenGL ES 3.0不仅可以在屏幕上的窗口渲染,还可以渲染称作pbuffer的不可见屏幕外表面。

EGLSurface eglCreatePbufferSurface(EGLDisplay display, // 指定EGL显示连接
    EGLConfig config, // 指定配置
    const EGLint *attribList) // 指定像素缓冲区属性

创建一个渲染上下文

渲染上下文是OpenGL ES 3.0的内部数据结构,包含操作所需的所有状态信息。OpenGL ES 3.0必须拥有一个上下文才能绘图。

EGLContext eglCreateContext(EGLDisplay display, // 指定EGL显示连接
    EGLConfig config, // 指定配置
    EGLContext shareContext, // 允许多个EGL上下文共享特定类型的数据
    const EGLint *attribList) // 指定创建上下文使用的属性列表

指定某个EGLContext为当前上下文

因为一个应用程序可能创建多个EGLContext用于不同的用途,所以我们需要关联特定的EGLContext和渲染表面。

EGLBoolean eglMakeCurrent(EGLDisplay display, // 指定EGL显示连接
    EGLSurface draw, // 指定EGL绘图表面
    EGLSurface read, // 指定EGL读取表面
    EGLContext context) // 指定连接到该表面的渲染上下文

结合所有EGL知识

创建ECL窗口的完整例程:

EGLBoolean initializeWindow ( EGLNativeWindow nativeWindow ) {
    // 指定config匹配的属性列表
    const EGLint configAttribs[] = {
        EGL_RENDER_TYPE, EGL_WINDOW_BIT, 
        EGL_RED_SIZE, 8, // 颜色缓冲区中红色分量位数 8
        EGL_GREEN_SIZE, 8, // 颜色缓冲区中绿色分量位数 8
        EGL_BLUE_SIZE, 8, // 颜色缓冲区中蓝色分量位数 8
        EGL_DEPTH_SIZE, 24, // 深度缓冲区位数 24
        EGL_NONE
    };
    // 指定上下文匹配的属性列表
    const EGLint contextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 3, // 上下文客户端版本 3
        EGL_NONE
    };
    // 创建和初始化与本地EGL显示的连接
    EGLDisplay display = eglGetDisplay ( EGL_DEFAULT_DISPLAY );  
    if ( display == EGL_NO_DISPLAY ) { // 连接不可用
        return EGL_FALSE; 
    }
    // OpenGL ES 主次版本号
    EGLint major, minor;
    if ( !eglInitialize ( display, &major, &minor ) ) {
        return EGL_FALSE;
    }
    // 配置列表
    EGLConfig config;
    // 配置
    EGLint numConfigs;
    // 选择匹配的EGLConfig
    if ( !eglChooseConfig ( display, configAttribs, &config, 1, &numConfigs ) ) {
        return EGL_FALSE;
    }
    // 创建屏幕上的渲染区域 EGL窗口
    EGLSurface window = eglCreateWindowSurface ( display, config, nativeWindow, NULL );
    if (window == EGL_NO_SURFACE) {
        return EGL_FALSE;
    }
    // 创建一个渲染上下文
    EGLContext context = eglCreateContext ( display, config, EGL_NO_CONTEXT, contextAttribs);
    if ( context == EGL_NO_CONTEXT ) {
        return EGL_FALSE;
    }
    // 指定某个EGLContext为当前上下文
    if ( !eglMakeCurrent ( display, window, window, context ) ) {
        return EGL_FALSE;
    }
    return EGL_TRUE;
}

同步渲染

当需要协调多个图形API再单个窗口中渲染时,比如(OpenVG和OpenGL共享一个窗口)。常常需要一下两个函数来协调同步:

EGLBoolean eglWaitClient() // 延迟客户端执行
EGLBoolean eglWaitNative(EGLint engine) //指定渲染程序等待渲染完成

小结

本章所涉及到的EGL知识足够使用,重点看一下"结合所有EGL知识"部分。

上一篇:(二)你好,三角形:https://www.jianshu.com/p/4dfd7510178e
下一篇:(四)着色器和程序:https://www.jianshu.com/p/b1b4656cef9e

上一篇下一篇

猜你喜欢

热点阅读