Android OpenGL ES 离屏幕渲染1——EGL环境的创建,以及基础概念的理解

创建EGL上下文、配置EGL环境、创建EGL DISPLAY

什么是EGL:

        由于OpenGL ES并不负责窗口管理以及上下文管理,该职责由各个平台自行完成;在Android平台下OpenGL ES的上下文环境是依赖EGL的API进行搭建的。

        对于EGL这个框架,谷歌已经提供了GLSurfaceView,是一个已经封装EGL相关处理的工具类,但是不够灵活;对于更加核心的OpengGL ES的用法(例如多线程共享纹理)则需要开发者自行搭建EGL开发环境。

        EGL是一套OpenGLES、OpenVG等渲染接口和它所运行的平台的底层原生窗口系统之间的桥接接口,也就是帮助OpenGLES或其他Khronos图形API渲染的内容投射到目标系统窗口的接口。它帮助处理图形上下文管理、表面/缓冲区绑定和渲染同步。并使用其他 Khronos API 实现高性能、加速、混合模式 2D 和 3D 渲染。EGL 还提供 Khronos旗下图形API 之间的互操作能力,以实现 API 之间的高效数据传输,例如在运行 OpenMAX AL 的视频子系统和运行 OpenGL ES 的 GPU 之间。

        EGL 提供创建渲染表面的机制,OpenGL ES 和 OpenVG 等客户端 API 可在该表面上进行绘制,为客户端 API 创建图形上下文,并同步客户端 API 和原生平台渲染 API 的绘制。这样便可使用 OpenGL ES 和 OpenVG 进行无缝渲染,从而实现高性能、加速、混合模式的 2D 和 3D 渲染。

        EGL 可以在多种操作系统(如 Android 和 Linux)和本机窗口系统(如 X 和 Microsoft Windows)上实现。实现还可以选择允许通过其他受支持的本机渲染 API(如 Xlib 或 GDI)渲染到特定类型的 EGL 表面。EGL 提供:

1、  用于创建客户端 API 可以在其上绘制和共享的渲染表面(窗口、pbuffers、pixmaps)的机制

2、  用于为客户端 API 创建和管理图形上下文的方法

3、  用于同步客户端 API 以及本机平台渲染 API 的绘制的方法。

        总结:为了创建和管理OpenGL ES的上下文、按照用户要求渲染图像到对应平台表面、渲染线程管理、生命周期、缓冲区等资源,以及把渲染的内容投射到目标容器(如某个surface),需要使用EGL接口进行简介操作。而安卓自带的GLSurfaceView只是把EGL的创建以及和安卓系统Surface绑定的过程封装起来,让程序员方便一些而已。

示意图来自:

https://www.cnblogs.com/yongdaimi/p/11244950.html

创建EGL显示设备:

Display(EGLDisplay) 是对实际显示设备的抽象(这个设备不一定是物理存在,也可以是逻辑存在),也就是最终的画面输出终端。

        既然要进行渲染,那创建一个FrameBuffer容器是必须的,但这个容器根据自己的需要,可以通过绑定对应系统的窗口直接显示,也可以只是EGL内部一个不可见的容器——也就是所谓的离屏渲染

        在安卓中的创建也很简单,调用android.opengl.EGL14#eglGetDisplay(int)工具方法即可获得一个EGLDisplay对象,并使用android.opengl.EGL14#eglInitialize方法对其进行初始化。具体代码如下:

mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY)
val versions = IntArray(2)
EGL14.eglInitialize(mEGLDisplay, versions, 0, versions, 1)

创建EGL配置信息表:

        有了渲染的FrameBuffer容器,还需要告诉EGL渲染时,像素的格式,例如红绿蓝透明度4通读占的bit数、深度信息记录的bit数等配置。详细各种配置的参数解释具体可参阅:https://registry.khronos.org/EGL/sdk/docs/man/html/eglChooseConfig.xhtml

 private val mEGLConfigAttrs = intArrayOf(EGL14.EGL_RED_SIZE, 8,EGL14.EGL_GREEN_SIZE, 8,EGL14.EGL_BLUE_SIZE, 8,EGL14.EGL_ALPHA_SIZE, 8,EGL14.EGL_DEPTH_SIZE, 8,EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT,EGL14.EGL_NONE)val configs: Array<EGLConfig?> = arrayOfNulls(1)val configNum = IntArray(1)EGL14.eglChooseConfig(mEGLDisplay, mEGLConfigAttrs, 0, configs, 0, 1, configNum, 0) //获取1个EGL配置,因为这个例子只需要一个

(安卓SDK自带的exoplayert2也自带了一些EGLConfig属性表的例子,可以参考com.google.android.exoplayer2.util.EGLSurfaceTexture#EGL_CONFIG_ATTRIBUTES、com.google.android.exoplayer2.util.GlUtil.Api17#getEglConfig

创建EGL渲染上下文:

使用刚刚创建的EGLDisplay及其EGLConfig通过EGL创建EGLContext。

函数形式:

    public static native EGLContext eglCreateContext(EGLDisplay dpy,EGLConfig config,EGLContext share_context,int[] attrib_list,int offset);

具体代码:

mEGLContext = EGL14.eglCreateContext(mEGLDisplay, mEGLConfig, EGL14.EGL_NO_CONTEXT, mEGLContextAttrs, 0) 

        第三个参数如果有需要共享这个EGLContext,如实现多线程渲染,则可以传入一个已创建成功的上下文, 这样就可以得到一个共享的上下文(Shared Context)。例子可以参考:https://juejin.cn/post/6969580005151997989

        eglCreateContext 为当前渲染 API(使用 eglBindAPI 设置)创建 EGL 渲染上下文并返回上下文句柄。然后可以使用该上下文渲染到 EGL 绘图表面。如果 eglCreateContext 无法创建渲染上下文,则返回 EGL_NO_CONTEXT。

        如果传入的share_context不是EGL_NO_CONTEXT,而是像mEGLContext这种已经创建好的的eglContext,则这个上下文本身以及这个它所使用的其他上下文,所有已被它共享、且可共享的数据(由当前渲染 API 的客户端 API 规范定义),在这个新创建的上下文上也会共享得到。但是,所有共享数据的渲染上下文本身必须存在于同一地址空间中。如果两个渲染上下文都属于同一个进程,则它们共享一个地址空间。

        attrib_list 指定上下文的属性列表。该列表具有与 eglChooseConfig 中描述的相同的结构。可以指定的属性和属性值可参考:

https://registry.khronos.org/EGL/sdk/docs/man/html/eglCreateContext.xhtml

创建EGLSurface:

        Surface(EGLSurface)是对用来存储图像的内存区域。也就是实际存储数据的地方

        根据自己需要绘制内容的大小和需求,创建EGLSurface。例子使用的是PbufferSurface。

mEGLSurface = EGL14.eglCreatePbufferSurface(mEGLDisplay, mEGLConfig, eglSurfaceAttrs, 0)

        也可以根据需要创建其他类型的Surface,例如WindowSurface、PixmapSurface,android使用eglCreateWindowSurface可以创建一个SurfaceViewSurfaceHolderSurface捆绑EGLSurface,这样内容可以展示这些Window对象不过不是渲染

把刚刚创建的一系列EGL对象进行绑定:

        绑定EGLSurface和EGLContext到显示设备(EGLDisplay),但这个EGLDisplay的内容没有和View绑定,所以并不会直接显示

EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)

销毁EGL环境:

        当在渲染任务完成后,在使用完OpenGL ES后,要把EGL环境进行销毁,否则会浪费设备资源。销毁之前创建EGL上下文存储图像内容Surface以及投射内容显示设备EGLDisplay具体代码

        // 与显示设备解绑EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_CONTEXT)// 销毁 EGLSurfaceEGL14.eglDestroySurface(mEGLDisplay, mEGLSurface)// 销毁EGLContextEGL14.eglDestroyContext(mEGLDisplay, mEGLContext)// 销毁EGLDisplay(显示设备)EGL14.eglTerminate(mEGLDisplay)

结尾:

        本文主要介绍EGL概念、作用,为后续的离平后续开始介绍EGL环境创建如何进行OpenGL ES API调用结果进行提取

引用:

OpenGL ES:Android平台EGL环境 - 简书

Android OpenGL ES从白痴到入门(四):离屏渲染(Pbuffer)_pbuffers+pixmaps-CSDN博客

EGL Overview - The Khronos Group Inc

https://en.wikipedia.org/wiki/OpenVG

https://registry.khronos.org/EGL/sdk/docs/man/html/eglChooseConfig.xhtml

https://registry.khronos.org/EGL/sdk/docs/man/html/eglCreateContext.xhtml

OpenGL ES 共享上下文实现多线程渲染 - 掘金

https://www.cnblogs.com/yongdaimi/p/11244950.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/42323.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java中 普通for循环, 增强for循环( foreach) List中增删改查的注意事项

文章目录 俩种循环遍历增加删除1 根据index删除2 根据对象删除 修改 俩种循环 Java中 普通for循环&#xff0c; 增强for循环( foreach) 俩种List的遍历方式有何异同&#xff0c;性能差异&#xff1f; 普通for循环&#xff08;使用索引遍历&#xff09;&#xff1a; for (int…

测试环境:使用OpenSSL生成证书并配置Https

文章目录 需求1、安装OpenSSL1.1、安装包下载1.2、安装&#xff08;以window 64位为例&#xff09;1.3、配置环境变量&#xff08;非必须&#xff09; 2、生成证书2.1、新建文件夹2.2、生成根证书2.2.1、生成私钥2.2.2、生成根证书&#xff0c;并且自签名 2.3、服务端证书生成2…

pyqt5导出数据到excel并设置单元格格式然后点击打开

pyqt5导出数据到excel并设置单元格格式然后点击打开 1、流程 1、从sqlite3获取数据 2、创建Workbook、sheet 3、设置列宽,单元格填充颜色 4、写数据进单元格 5、设置文件名并保存 6、设置pyqt5输出框可直接点击打开文件2、代码 from openpyxl import Workbook from openpyx…

【双一流高校主办,Springer-LNICST出版,EI稳定检索】2024年应用计算智能、信息学与大数据国际会议(ACIIBD 2024,7月26-28)

2024年应用计算智能、信息学与大数据国际学术会议&#xff08;ACIIBD 2024&#xff09;将于2024年7月26-28日在中国广州举办。会议将聚焦于计算智能及其应用、信息、大数据等相关的研究领域&#xff0c; 广泛邀请国内外知名专家学者&#xff0c;共同探讨相关学科领域的最新发展…

rsyslog日志转发

前言 Rsyslog可用于接受来自各种来源(本地和网络)的输入&#xff0c;转换它们&#xff0c;并将结果输出到不同&#xff08;通过模板和filter过滤&#xff09;的目的地&#xff08;目录文件中&#xff09; rsyslog是一个开源工具&#xff0c;被广泛用于Linux系统以通过TCP/UDP…

2025届秋招提前批信息汇总(计算机类)

私企篇 深信服 链接&#xff1a;https://app.mokahr.com/campus_apply/sangfor/27944#/home内推码&#xff1a;NTAHRFS截止时间&#xff1a;6月21日 TP-LINK 链接&#xff1a;https://hr.tp-link.com.cn/jobList?jobId107&jobDirection0&workPlace0&currentPa…

[spring] Spring MVC - security(上)

[spring] Spring MVC - security&#xff08;上&#xff09; 这部分的内容基本上和 [spring] rest api security 是重合的&#xff0c;主要就是添加 验证&#xff08;authentication&#xff09;和授权&#xff08;authorization&#xff09;这两个功能 即&#xff1a; 用户…

HTTPS 发送请求出现TLS握手失败

最近在工作中&#xff0c;调外部接口&#xff0c;发现在clientHello步骤报错&#xff0c;服务端没有返回serverHello。 从网上找了写方法&#xff0c;都没有解决&#xff1b; 在idea的vm options加上参数&#xff1a; -Djavax.net.debugSSL,handshake 把SSL和handshake的日…

构建基于Spring Cloud的微服务监控系统

构建基于Spring Cloud的微服务监控系统 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 随着微服务架构的流行&#xff0c;应用程序变得更加复杂和分布式&…

python自动化办公之cryptography加密解密

目录 用到的库 实现效果 代码部分 1、加密2024.txt文件 2、解密2024.txt文件 用到的库 cryptography 实现效果 加密文件和解密文件 代码部分 1、加密2024.txt文件 # 加密 from cryptography.fernet import Fernet # 生成加密密钥 keyFernet.generate_key() cipher_s…

go语言中使用WaitGroup和channel实现处理多线程问题

WaitGroup 背景 如果将一个任务分为任意个小任务&#xff0c;并且不关心小任务的执行顺序&#xff0c;并且希望等待全部的小任务执行完成后再去操作后面的逻辑&#xff0c;那我推荐你用sync.WaitGRoup 使用方法 比如&#xff0c;有一个任务需要执行 3 个子任务&#xff0c;…

Raw Socket(一)实现TCP三次握手

实验环境&#xff1a; Windows物理机&#xff1a;192.168.1.4 WSL Ubuntu 20.04.6 LTS&#xff1a;172.19.32.196 Windows下的一个http服务器&#xff1a;HFS&#xff0c;大概长这个样子&#xff1a; 客户端就是Ubuntu&#xff0c;服务端就是这个…

收银系统源码-线上商城预售功能

1.功能描述 预售&#xff1a;智慧新零售收银系统&#xff0c;线上商城营销插件之一&#xff0c;商品出售时可设置以支付定金或全款的方式提前预售&#xff0c;门店按订单量备货&#xff0c;降低压货成本&#xff1b; 2.适用场景 易损商品提前下单备货&#xff0c;如水果生鲜…

【算法笔记自学】第 5 章 入门篇(3)——数学问题

5.1简单数学 #include <cstdio> #include <algorithm> using namespace std; bool cmp(int a,int b){return a>b; } void to_array(int n,int num[]){for(int i0;i<4;i){num[i]n%10;n /10;} } int to_number(int num[]){int sum0;for(int i0;i<4;i){sumsu…

C++ Lambda表达式第二篇, Lambda表达式

C Lambda表达式 Lambda 捕获含有模板参数的Lambda表达式无模板参数的Lambda表达式 Lambda 捕获 captures是零个或多个捕获的逗号分隔列表&#xff0c;可以选择以capture-default开头。捕获列表定义可从 lambda 函数体内访问的外部变量。唯一的捕获默认值是 &&#xff0c;…

Kylin系列(二)架构解析:深入理解 Kylin 的架构设计

目录 1. 引言 2. Kylin 的基本概念 2.1 预计算 2.2 多维数据集&#xff08;Cube&#xff09; 2.3 维度和度量 3. Kylin 的架构设计 3.1 数据源 3.2 数据建模 3.2.1 星型模型 3.2.2 雪花模型 3.3 多维数据集构建 3.3.1 数据导入 3.3.2 维度和度量计算 3.3.3 存储优…

AI微电影制作教程:轻松打造高清小人国画面

AI微电影作为一种新兴的视频内容形式&#xff0c;以其独特的视觉效果和制作技术在各大视频平台上取得了显著的流量表现。 2. AI微电影的特点 2.1 高清画质与流畅动作&#xff1a;AI微电影以其高分辨率和流畅的动作给观众带来优质的视觉体验。 2.2 微缩画面效果&#xff1a;独…

大数据面试题之Presto[Trino](6)

如何诊断Presto查询慢的问题&#xff1f; 诊断Presto查询慢的问题通常需要一个系统化的方法&#xff0c;结合监控、日志分析、查询优化策略和系统配置调整等多个方面。以下是一些具体的步骤和建议&#xff1a;1、查看Presto Dashboard&#xff1a; 登录Presto的Web UI&#xf…

WebKit 入门案例教程

WebKit 的基本概念 1.什么是 WebKit&#xff1f;&#xff1a;WebKit 是一个开源的浏览器引擎&#xff0c;用于渲染 HTML、CSS 和 JavaScript 等内容。 2.WebKit 的组件&#xff1a;WebKit 的组件包括 HTML 解析器、CSS 解析器、JavaScript 引擎、布局引擎等。 3.WebKit 的应用…

用 adb 来模拟手机插上电源和拔掉电源的情形

实用的 ADB 命令 要模拟手机从 USB 充电器上拔掉的情形&#xff0c;你可以使用&#xff1a; adb shell dumpsys battery set usb 0或者&#xff0c;如果你使用的是 Android 6.0 或更高版本的设备&#xff0c;你可以使用&#xff1a; adb shell dumpsys battery unplug要重新…