美文网首页
(三)EGL简介

(三)EGL简介

作者: YongtaoHuang | 来源:发表于2019-10-10 17:17 被阅读0次

    上一篇:(二)你好,三角形: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

    相关文章

      网友评论

          本文标题:(三)EGL简介

          本文链接:https://www.haomeiwen.com/subject/ieagpctx.html