OpenGL ES (二)EGL介绍和使用
OpenGL ES学习系列文章:
上一篇:OpenGL ES (一)EGL介绍和使用
下一篇:OpenGL ES (三)着色器和程序
EGL介绍和使用
- 一、EGL简介
- 二、EGL的功能
- 三、EGL使用
- 1、创建OpenGL ES与原生窗口系统的连接
- 2、初始化EGL连接
- 3.选择Surface配置
- 4. 创建渲染区域Surface
- 4.1 创建屏幕上的渲染区域:EGL窗口
- 4.2 其他操作surface方法
- 5. 创建渲染上下文
一、EGL简介
与OpenGl ES一样,EGL同样是由Khronos Group所提供的一个与平台无关的API。
OpenGL作为一个图形化API,允许我们操作GPU以绘制图形,但是当涉及到本地的窗口时,就需要一个与平台无关的API来与之进行交互,EGL应运而生,承担起OpenGl和原生窗口系统之间桥梁的作用。
二、EGL的功能
EGL API作为一套与OpenGL ES各个版本相互独立的API,其作用主要是管理绘图表面。EGL提供以下机制:
- 与设备的原生窗口系统通信
- 查询绘图表面的可用类型和配置
- 创建绘图表面
- 在OpenGL ES3.0或其他渲染API之间同步渲染
- 管理纹理贴图等渲染资源
三、EGL使用
1、创建OpenGL ES与原生窗口系统的连接
EGLDisplay eglGetDisplay(EGLNativeDisplayType displayId);
eglGetDisplay为原生窗口系统displayId获取一个EGL display连接,
在OpenGL ES与本地窗口系统之间架起了一座沟通的桥梁
2、初始化EGL连接
与窗口系统的连接建立以后,随后要进行EGL的初始化
EGLBoolean eglInitialize(EGLDisplay display, // 要进行初始化的EGL连接,即上一部中的返回值EGLint *majorVersion, // 主版本号EGLint *minorVersion) // 次版本号
- display默认为EGL_DEFAULT_DISPLAY,即返回与默认原生窗口的连接
- majorVersion 和minorVersion 会在调用后返回版本号,例如EGL1.0, majorVersion返回1, minorVersion返回0
注:eglInitialize会初始化EGL内部数据,比如分配显存等;如果初始化失败,可以用eglGetError()
函数获取具体的错误类型,其他EGL相关的函数,也都可以使用eglGetError()来获取错误的类型。
EGL中大部分函数执行成功时返回EGL_TRUE,失败时返回EGL_FALSE。eglGetError()函数可以指示故障原因
常见错误返回值(使用eglGetError获取):
- EGL_BAD_DISPLAY :表示参数display不是一个EGL diaplay 连接
- EGL_NOT_INITIALIZED :表示传入的display不可以被初始化
创建连接与初始化实例:
EGLint majorVersion;
EGLint minorVersion;
EGLDisplay display;
display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (display == EGL_NO_DISPLAY) {// 与本地窗口系统创建连接失败
}
if (!eglInitialize(display, &majorVersion, &minorVersion)) {// 初始化EGL连接失败
}
3.选择Surface配置
EGL初始化成功之后,就需要确定可用渲染表面的类型和配置。
一般来说,选择配置的方法有两种:
方法一:查询所有可行的配置(eglGetConfigs),再让EGL从中找出最优选择(eglGetConfigAttrib)
方法二:指定一组需求,然后再让EGL推荐(eglChooseChofig)最佳配置。
下面分写介绍这两种方法的使用。
方法一:从所有可行配置中找到最优配置
EGLBoolean eglGetConfigs(EGLDisplay display, //指定EGL显示连接EGLConfig * configs, //指定一组configEGLint config_size, //指定配置列表的大小EGLint * num_config); //实际匹配的配置总数
参数configs将包含在你平台上所有有效的EGLframebuffer配置列表。支持的总数通过num_config返回,而实际返回的 configs 的配置个数依赖于程序传入的 config_size,如果 config_size < num_config,则不是所有可行的config都会被返回。如果想要获取系统支持的所有配置信息,最好的方法就是先给eglGetConfigs传一个null的configs参数,这样执行后就会得到系统支持的配置总数num_config,然后使用num_config来给configs分配合适的内存大小,再用得到的configs来调用eglGetConfig。
示例:
EGLConfig *configs_list;
EGLint num_configs;
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推荐最佳配置
EGLBoolean eglChooseConfig(EGLDisplay display, // 指定EGL显示连接 const EGLint *attribList, // 指定configs匹配的属性列表EGLConfig *configs, // 指定配置列表EGLint maxReturnConfigs, // 指定配置的大小EGLint *numConfigs) // 指定返回的配置大小
glChooseConfig()函数将适配一个你所期望的配置,并且尽可能接近一个有效的系统配置。参数 attribList 指定了选择配置时需要参照的属性。参数 configs 将返回一个按照 attribList 排序的平台有效的所有 EGL framebuffer 配置列表。参数 config_size 指定了可以返回到 configs 的总配置个数。参数 num_config 返回了实际匹配的配置总数。
示例:
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();
}
如果找到了多个配置,则基于属性的优先级进行排序,下表显示了基于属性值的用来选择和排序的顺序(不需过多关注),也包括了 EGL 规范中所有 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 |
4. 创建渲染区域Surface
当有了符合条件的 EGLConfig 后,就可以通过 eglCreateWindowSurface 函数创建渲染区域。
4.1 创建屏幕上的渲染区域:EGL窗口
创建surface
EGLSurface eglCreateWindowSurface( EGLDisplay display, //对应的EGL display连接EGLConfig config, //EGL frame buffer配置,定义了可用于Surface的frame buffer资源NativeWindowType native_window, //原生窗口EGLint const * attrib_list); // attrib_list为Window Surface属性列表,可以为NULL,成功时返回新创建的EGLSurface,失败时返回EGL_NO_SURFACE.// 可能出现的错误:
// EGL_BAD_DISPLAY: 连接不是一个EGL display连接
//EGL_NOT_INITIALIZED: EGL没有初始化
//EGL_BAD_CONFIG: EGL frame buffer配置无效
//EGL_BAD_NATIVE_WINDOW: native window不是与display相同平台的有效Native Window
//EGL_BAD_ATTRIBUTE: attrib_list包含无效参数,或者参数未被识别,或者参数越界
//EGL_BAD_ALLOC:已经有一个与native window关联的Surface,或者无法为新的EGL窗口分配资源,
//EGL_BAD_MATCH:本机窗口的像素格式与配置所需的颜色缓冲区的格式、类型和大小不一致
4.2 其他操作surface方法
- 销毁surface:
EGLAPI EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay display, EGLSurface surface);
与eglCreateWindowSurface对应的,还有一个eglDestroySurface,用来销毁surface,display为对应的Display,surface为将要销毁的Surface, 如果任何其它线程都没有使用这个Surface时,Surface将被立即销毁,否则要等到这个Surface不被任何线程使用时才销毁,另外,对于一个PBuffer Surface来说,其资源要等到绑定到纹理对象的颜色缓冲区释放后才被销毁。成功时返回EGL_TRUE,失败时返回EGL_FALSE,可能的错误为EGL_BAD_DISPLAY、EGL_NOT_INITIALIZED、EGL_BAD_SURFACE。
- 获取surface信息
EGLAPI EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay display, EGLSurface surface,EGLint attribute, EGLint *value);
eglQuerySurface用于获取Surface信息,display为对应的Display,surface待查询的Surface,attribute为待查询的Surface属性,value用于返回Surface属性值,成功时返回EGL_TRUE,失败时返回EGL_FALSE,可能的错误为EGL_BAD_DISPLAY、EGL_NOT_INITIALIZED、EGL_BAD_SURFACE、EGL_BAD_ATTRIBUTE。attribute取值可以是:
EGL_CONFIG_ID EGL_HEIGHT EGL_HORIZONTAL_RESOLUTION EGL_LARGEST_PBUFFER EGL_MIPMAP_LEVEL EGL_MIPMAP_TEXTURE EGL_MULTISAMPLE_RESOLVE EGL_PIXEL_ASPECT_RATIO EGL_RENDER_BUFFER EGL_SWAP_BEHAVIOR EGL_TEXTURE_FORMAT EGL_TEXTURE_TARGET EGL_VERTICAL_RESOLUTION EGL_WIDTH
- 设置surface属性
EGLAPI EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay display, EGLSurface surface,EGLint attribute, EGLint value);
eglSurfaceAttrib用于设置Surface属性,display为对应的Display,surface为要设置的Surface,attribute为要设置的Surface属性,value为要设置的Surface属性值,成功时返回EGL_TRUE,失败时返回EGL_FALSE,可能的错误为EGL_BAD_DISPLAY、EGL_BAD_MATCH、EGL_NOT_INITIALIZED、EGL_BAD_SURFACE、EGL_BAD_ATTRIBUTE。attribute取值可以是:
EGL_MIPMAP_LEVEL:默认值为0。 EGL_MULTISAMPLE_RESOLVE:EGL_MULTISAMPLE_RESOLVE_DEFAULT或>EGL_MULTISAMPLE_RESOLVE_BOX,默认值为前者。 EGL_SWAP_BEHAVIOR:EGL_BUFFER_PRESERVED或EGL_BUFFER_DESTROYED,默认值由实现而定。
- 创建屏幕外的渲染区域
EGLSurface eglCreatePbufferSurface(EGLDisplay display, // 指定EGL显示连接EGLConfig config, // 指定配置const EGLint *attribList) // 指定像素缓冲区属性
OpenGL ES 3.0不仅可以在屏幕上的窗口渲染,还可以渲染称作pbuffer的不可见屏幕外表面。PBuffer Surface是不同于Window Surface的另一种EGLSurface,eglCreatePbufferSurface用于创建off-screen的pixel buffer Surface,display为对应的Display,config为frame buffer配置,attribList为PBuffer属性列表,可以为NULL,成功时返回新创建的EGLSurface,失败时返回EGL_NO_SURFACE,可能的错误为EGL_BAD_DISPLAY、EGL_NOT_INITIALIZED、EGL_BAD_CONFIG、EGL_BAD_ATTRIBUTE、EGL_BAD_ALLOC、EGL_BAD_MATCH。attribList的属性可以是:
EGL_HEIGHT:默认值为0。 EGL_LARGEST_PBUFFER:默认值为EGL_FALSE。 EGL_MIPMAP_TEXTURE:默认值为EGL_FALSE。 EGL_TEXTURE_FORMAT:默认值为EGL_NO_TEXTURE,还可以选择EGL_TEXTURE_RGB或>EGL_TEXTURE_RGBA。 EGL_TEXTURE_TARGET:默认值为EGL_NO_TEXTURE,还可以选择EGL_TEXTURE_2D。 EGL_VG_ALPHA_FORMAT:只适用于OpenVG,默认值为EGL_VG_ALPHA_FORMAT_NONPRE,>还可以选择EGL_VG_ALPHA_FORMAT_PRE。 EGL_VG_COLORSPACE:只适用于OpenVG,默认值为EGL_VG_COLORSPACE_sRGB,还可以选>择EGL_VG_COLORSPACE_LINEAR。 EGL_WIDTH:默认值为0。
PBuffer Surface与Window Surface
除了可以用OpenGL ES 3.0在屏幕上的窗口渲染之外,还可以渲染称作PBuffer(像素缓冲区Pixel Buffer的缩写)的不可见屏幕外表面,和窗口一样,PBuffer可以利用OpenGL ES 3.0中的任何硬件加速,PBuffer最常用于生成纹理贴图,如果想要做的是渲染到一个纹理,那么建议使用帧缓冲区对象(FBO)代替PBuffer,因为帧缓冲区更高效,不过在某些FBO无法使用的情况下,PBuffer仍然有用,例如用OpenGL ES在屏幕外表面上渲染,然后将其作为其它API(如OpenVG)中的纹理。另外,EGLSurface还有个Pixmap Surface,简单总结一下三者的特点。window是on-screen的,pbuffer和pixmap是off-screen的,window绑定到了NativeWindow,pixmap绑定到了NativePixmap,pbuffer没有任何本地绑定,window是双缓冲区的,pbuffer和pixmap是单缓冲区的,window默认在back buffer渲染,通过eglSwapBuffers交换到屏幕上显示,pbuffer在显存中分配,由EGL_HEIGHT和EGL_WIDTH指定大小,常用作纹理数据,pixmap绑定到本地的像素缓冲区,这个缓冲区可以被其它API使用。创建不同的EGLSurface时,需要在EGLConfig中配置EGL_SURFACE_TYPE,window、pbuffer、pixmap分别对应于EGL_WINDOW_BIT、EGL_PBUFFER_BIT、EGL_PIXMAP_BUFFER。
5. 创建渲染上下文
创建渲染上下文
EGLAPI EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay display, EGLConfig config,EGLContext share_context,const EGLint *attribList);
eglCreateContext用于创建EGL渲染Context,display为对应的Display,config为frame buffer配置,share_context为其它的共享Context,可以设置为EGL_NO_CONTEXT,attribList为Context属性列表,成功时返回新创建的EGLContext,失败时返回EGL_NO_CONTEXT,可能的错误为EGL_BAD_MATCH、EGL_BAD_DISPLAY、EGL_NOT_INITIALIZED、EGL_BAD_CONFIG、EGL_BAD_CONTEXT、EGL_BAD_ATTRIBUTE、EGL_BAD_ALLOC。attrib_list属性目前只有EGL_CONTEXT_CLIENT_VERSION,整数值,指定OpenGL ES版本,默认值为1,还可以是2、3等其它版本值,创建OpenGL ES Context时设置这个属性,也就是说渲染API为EGL_OPENGL_ES_API时才设置这个属性,为此还要设置或查询渲染API,使用如下两个函数。
销毁渲染上下文
EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay display, EGLContext context);
eglDestroyContext用于销毁渲染Context,dpy为对应的Display,ctx为要销毁的Context,如果有其它线程使用这个Context时就要等到不使用时再销毁,否则立即销毁,成功时返回EGL_TRUE,失败时返回EGL_FALSE,可能的错误为EGL_BAD_DISPLAY、EGL_NOT_INITIALIZED、EGL_BAD_CONTEXT。
获取Context信息
EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay display, EGLContext context,EGLint attribute, EGLint *value);
eglQueryContext用于获取Context信息,dpy为对应的Display,ctx为要查询的Context,attribute为要查询的Context属性,value返回查询的Context属性值,成功时返回EGL_TRUE,失败时返回EGL_FALSE,可能的错误为EGL_BAD_DISPLAY、EGL_NOT_INITIALIZED、EGL_BAD_CONTEXT、EGL_BAD_ATTRIBUTE。attribute取值可以是:
EGL_CONFIG_ID EGL_CONTEXT_CLIENT_TYPE EGL_CONTEXT_CLIENT_VERSION EGL_RENDER_BUFFER
eglMakeCurrent
EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay display, EGLSurface draw,EGLSurface read, EGLContext context);
创建了Surface和Context之后,因为可能有多个Surface和Context,所以需要通过eglMakeCurrent绑定Context到Surface,display为对应的Display,draw用于绘制,read用于读,ctx为要绑定的Context,成功是返回EGL_TRUE,失败时返回EGL_FALSE,可能的错误为EGL_BAD_DISPLAY、EGL_NOT_INITIALIZED、EGL_BAD_SURFACE、EGL_BAD_CONTEXT、EGL_BAD_MATCH、EGL_BAD_ACCESS 、EGL_BAD_NATIVE_PIXMAP、EGL_BAD_NATIVE_WINDOW、EGL_BAD_CURRENT_SURFACE、EGL_BAD_ALLOC、EGL_CONTEXT_LOST。因为EGL规范要求eglMakeCurrent实现进行一次刷新,所以这一调用对于基于图块的架构代价很高。
OpenGL ES (二)EGL介绍和使用相关推荐
- 【Android OpenGL开发】OpenGL ES与EGL介绍
什么是OpenGL ES OpenGL(Open Graphics Library)是一个跨编程语言.跨平台的编程图形程序接口,主要用于图像的渲染. Android提供了简化版的OpenGL接口,即O ...
- Adreno OpenGL ES 2.0 介绍(3)
Adreno OpenGL ES 2.0 介绍(3) 1. 应用程序示例 1.2 在Android上创建ES 2.0 上下文/环境 1.3 Adreno GPU检测 1.4 检查支持的ES拓展 1. ...
- Adreno OpenGL ES 3.1 介绍(3)
Adreno OpenGL ES 3.1 介绍(3) 4.1.7单独的着色器对象 4.1.8着色器存储缓冲区对象 4.1.7单独的着色器对象 OpenGL ES中的关键对象类型之一是程序对象. 他们需 ...
- OpenGL ES和EGL关系(二十五)
什么是 EGL EGL 是 OpenGL ES 和本地窗口系统(Native Window System)之间的通信接口,它的主要作用: 与设备的原生窗口系统通信: 查询绘图表面的可用类型和配置: 创 ...
- OpenGL ES与EGL的关系(二十一)
什么是OpenGL? Open Graphics Library (OpenGL) is a cross-language, cross-platform application programmin ...
- opengl,opengl es,egl,glfw,glew
OpenGL ES之GLFW窗口搭建 - Plato - 博客园概述 本章节主要总结如何使用GLFW来创建Opengl窗口.主要包括如下内容: OpenGl窗口创建介绍 GLFW Window版编译 ...
- 与context的关系_你还不知道 OpenGL ES 和 EGL 的关系?
什么是 EGL EGL 是 OpenGL ES 和本地窗口系统(Native Window System)之间的通信接口,它的主要作用: 与设备的原生窗口系统通信: 查询绘图表面的可用类型和配置: 创 ...
- opengl、opengl es、webgl介绍与opengl开发入门
1.OpenGL OpenGL(英语:Open Graphics Library,译名:开放图形库或者"开放式图形库")常用于CAD.虚拟现实.科学可视化程序和电子游戏开发.Ope ...
- OpenGL ES: (3) EGL、EGL绘图的基本步骤、EGLSurface、ANativeWindow
1. EGL概述 EGL 是 OpenGL ES 渲染 API 和本地窗口系统(native platform window system)之间的一个中间接口层,它主要由系统制造商实现. EGL提供如 ...
- OpenGL ES基本概念介绍
最近不太忙,打算这周开始学习下OpenGL,网上也已经有好多关于OpenGL的书籍和资料了.至于为什么还要写,是为了养成一个良好的学习习惯,也算给自己的学习过程做一个总结. 基本概念 OpenGL定义 ...
最新文章
- 文件时间信息在测试中的应用
- python综合学习一之多线程
- Java常用设计模式————建造者模式
- 嘘!你与谷歌语音助手的对话,可能已经泄露……
- IOS-程序员和设计师必备的20个CSS工具
- sudo chown r mysql_Linux 文件基本属性: chown修改所属组 和 chmod修改文件属性命令
- jest (让人愉悦的测试框架)
- Maxwell简单使用
- Python怎么安装PHP,php中ThinkPHP的下载和安装
- catia 桥接曲面圆角_CATIA建模教程(二)——圆角及桥接在空间曲线中的应用.pdf...
- Java多线程案例-单例模式【饿汉模式,懒汉模式】
- linux df -h显示空间信息不正确
- 修改docker镜像提高下载速度
- Wopus问答第一期
- 学习博客:关键字package包的使用
- mt4 python神经网络_用Python写MT4自动交易策略来炒外汇
- linux kernel build
- 人生新的开始,组建大数据公司
- VISTA无人驾驶模拟器;FinRL量化金融深度强化学习库;『深度神经网络应用』电子书;CUDA/TensorRT案例集锦;前沿论文 | ShowMeAI资讯日报
- 中文版PyCharm改为英文版PyCharm
热门文章
- java scavenge_Java垃圾收集器之Parallel Scavenge收集器
- obs噪音抑制调多少合适_(3)阿里国际站OBS申请设置使用教程,OBS音频没有声音怎么办?国际站直播回放如何下载?...
- 程序员转行一般是因为什么,会去哪些行业?
- php mocking,php – Mocking Static Eloquent Models方法包括find()
- pancake-frontend(薄饼)二次开发
- [NOIp 2014]解方程
- 郑轻oj1000-从今天开始入坑C语言
- opengl绘制太阳、地球、月亮,贴上纹理,设置光照,符合自转和公转规律
- 作业中关于H5中动画的实现——animation
- 折下我的翅膀,送你飞翔