Android OpenGL EGL使用——自定义相机

news2025/1/7 20:06:23

如果要使用OpenGl来自定义相机,EGL还是需要了解下的。

可能大多数开发者使用过OpengGL但是不知道EGL是什么?EGL的作用是什么?这其实一点都不奇怪,因为Android中的GlSurfaceView已经将EGL环境都给配置好了,你一直在使用,只是不知道他的存在罢了。

很多人可能在使用OpenGl ES渲染数据的时候都带着一个疑问,渲染的数据到底到哪里去了?没看到画布,Android中的自定义view不都是有画布的吗?

EGL就是底层OpenGL绘制图形的画布。请见<EGL和OpenGl ES的关系>介绍。

一、EGL简介

1、了解EGL是什么

EGL是什么?EGL:全称Embedded Graphic Library。EGL是渲染API(如OpenGL, OpenGL ES, OpenVG)和本地窗口系统之间的接口。它处理图形上下文管理,表面/缓冲区创建,绑定和渲染同步,并使用其他Khronos API实现高性能,加速,混合模式2D和3D渲染OpenGL / OpenGL ES渲染客户端API OpenVG渲染客户端API原生平台窗口系统。这个稍微了解下就OK,你只要知道它是一个用来给OpenGl ES提供绘制界面的接口就可以了。

EGL的作用:

  1. 与设备的原生窗口系统通信。
  2. 查询绘图表面的可用类型和配置。
  3. 创建绘图表面。
  4. 在OpenGL ES 和其他图形渲染API之间同步渲染。
  5. 管理纹理贴图等渲染资源。
2、EGL和OpenGl ES的关系

(1)从上面的讲解我们基本上可以知道,EGL是为OpenGl提供绘制表面的。

对的,这就是OpenGl ES数据渲染画布所在了。想必到这里大家也清楚了渲染数据去处的问题了。

EGL还有什么用呢?EGL可以理解为OpenGl ES ES和设备之间的桥梁。完全可以这么理解。

(2) OpenGL 是跨平台的、专业的图形编程接口,而接口的实现是由厂商来完成的。

OpenGL使用这些接口绘制完成后,需要把数据渲染到屏幕上,就需要EGL来接手这部分工作。

EGL是 OpenGL ES 和底层 Native 平台 视窗系统之间的接口,如下图所示。

(3)有一个类比的例子

我们来思考一下画家绘画的过程:首先要有一名懂得各种绘画技艺的画家,然后他需要一张画布,一些笔,一些颜料,一些辅助工具(尺、模板、橡皮、调色板等等),然后他在画布上绘制第一幅画,完成之后展示给人们看;在人们观赏第一幅画的时候,他可以在第二张画布上绘制第二幅画,绘制完成后收回第一幅画,将第二幅画展现给人们看;接着使用工具擦除第一幅画,在同一张画布上绘制第三幅画;周而复始,人们便看到了一幅接一幅的画。

对比 OpenGL ES/EGL,各要素的对应关系大体如下:

  • 画家:编程人员
  • 笔、颜料、辅助工具:OpenGL ES API
  • 画布:EGL 创建的 Surface

所以计算机绘画的本质就是选择图像显示的像素格式,申请一块内存(画布),填充像素(颜色),绘制完成之后,通知计算机显示到屏幕上(按比例发射RGB光),最终就看到了所绘制的画面。之所以要先选择像素格式,是因为无论是所申请内存的大小,还是硬件驱动解析这块内存的方式,都是由像素格式决定的。
 

3、EGL包括哪些内容

EGL接口中含有3个对象,如下图所示:

简单讲解下各部分的作用:

  1. Display(EGLDisplay) 是对实际显示设备的抽象。
  2. Surface(EGLSurface)是对用来存储图像的内存区FrameBuffer 的抽象,包括Color Buffer,Stencil Buffer,Depth Buffer。
  3. Context (EGLContext) 存储 OpenGL ES绘图的一些状态信息。

二、EGL使用步骤

1、创建EGLDisplay,得到默认的显示设备(窗口)

首先我们需要知道绘制内容的目标在哪里,EGLDisplayer是一个封装系统屏幕的数据类型,通常通过eglGetDisplay方法来返回EGLDisplay作为OpenGl ES的渲染目标,eglGetDisplay()

mEgl = EGLContext.getEGL() as EGL10
//get Display device
mEGLDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY)

2、初始化显示设备

第一参数代表Major版本,第二个代表Minor版本。如果不关心版本号,传0或者null就可以了。初始化与 EGLDisplay 之间的连接:eglInitialize()

mEgl.eglInitialize(mEGLDisplay, version)

3、配置显示设备的属性,确定渲染表面的配置信息

mEgl.eglChooseConfig(
        mEGLDisplay,
        attribList,
        configs,
        configs.size,
        numConfigs
    )

4、创建OpenGL上下文环境EGLContext实例

注:OpenGL的任何一条指令都必须再自己的OpenGL上下文环境中进行。

mEgl.eglCreateContext(
    mEGLDisplay,
    config,
    EGL10.EGL_NO_CONTEXT,
    contextList
)

eglCreateContext中的第三个参数可以传入一个EGLContext类型的变量,该变量的意义是可以与正在创建的上下文环境共享OpenGl资源,包括纹理ID,FrameBuffer以及其他Buffer资源。如果没有的话可以填写Null.

5、创建渲染表面EGLSurface

通过上面四步,获取OpenGl 上下文之后,说明EGL和OpenGl ES端的环境已经搭建完毕,也就是说OpengGl的输出我们可以获取到了(OpenGL的绘制数据我们可以获取到了,接下来就是如何显示这些数据到显示设备上)。下面的步骤我们讲如何将EGl和设备屏幕连接起来。如果连接呢?当然,这时候我们就要使用EGLSurface了,我们通过EGL库提供eglCreateWindowSurface可以创建一个实际可以显示的surface.当然,如果需要离线的surface,我们可以通过eglCreatePbufferSurface创建。其中,eglCreateWindowSurface()用于创建屏幕上渲染区域,eglCreatePbufferSurface用于创建屏幕外渲染区域。

private EGLSurface mSurface= EGL14.EGL_NO_SURFACE;
mEGLSurface = mEgl.eglCreateWindowSurface(
    mEGLDisplay,
    mEGLConfig,
    mSurface,
    attribList
)

6、绑定三者:Display 显示设备,surface渲染表面,context上下文环境

通过上面的步骤,EGL的准备工作做好了,一方面我们为OpenGl ES渲染提供了目标及上下文环境,可以接收到OpenGl ES渲染出来的纹理,另一方面我们连接好了设备显示屏(这里指SurfaceView或者TextureView),接下来我们讲解如何在创建好的EGL环境下工作的。首先我们有一点必须要明确,OpenGl ES 的渲染必须新开一个线程,并为该线程绑定显示设备及上下文环境(Context)。因为前面有说过OpenGl指令必须要在其上下文环境中才能执行。所以我们首先要通过 eglMakeCurrent()方法来绑定该线程的显示设备及上下文。

通过eglMakeCurrent方法将EGLSurface,EGLContext,EGLDisplay绑定成功之后,OpenGL ES环境就搭建好了,接下来便可以渲染了。

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

7、交换缓冲

绑定完成之后,就可以进行RenderLoop循环了。这里简单说一下,EGL的工作模式是双缓冲模式,其内部有两个FrameBuffer(帧缓冲区,可以理解为一个图像存储区域),当EGL将一个FrameBuffer显示到屏幕上的时候,另一个FrameBuffer就在后台等待OpenGl ES进行渲染输出。直到调用了eglSwapBuffers这条指令的时候,才会把前台的FrameBuffers和后台的FrameBuffer进行交换,这样界面呈现的就是OpenGl ES刚刚渲染的结构了。即,切换 front buffer 和 back buffer 送显。

屏幕外的渲染不需要调用此方法。

mEgl.eglSwapBuffers(mEGLDisplay, mEGLSurface)

如何进行渲染显示(未完待续。。。)

8、释放EGL环境

当然,在所有的操作都执行完之后,我们要销毁资源。特别注意,销毁资源必须在当前线程中进行,不然会报错。首先取消eglMakeCurrent的绑定,销毁三个对象:EGLSurface,EGLContext和EGLDisplay,即销毁显示设备(EGLSurface),然后销毁上下文(EGLContext),停止并释放线程,最后终止与EGLDisplay之间的链接。

mEgl.eglMakeCurrent(
    mEGLDisplay, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE,
    EGL10.EGL_NO_CONTEXT
)
mEgl.eglDestroySurface(mEGLDisplay, mEGLSurface)//销毁EGLSurface
mEgl.eglDestroyContext(mEGLDisplay, mEGLContext)//销毁上下文EGLContext
mEgl.eglTerminate(mEGLDisplay)//终止与EGLDisplay的连接
mEGLDisplay = EGL10.EGL_NO_DISPLAY
mEGLContext = EGL10.EGL_NO_CONTEXT
mEGLSurface= EGL10.EGL_NO_SURFACE

参考链接:

Android 系统图形栈(一): OpenGL ES 和 EGL 介绍_android图栈-CSDN博客

Android笔记:OpenGL ES与EGL的关系与实例_egl的surface是在gpu-CSDN博客

你还不知道 OpenGL ES 和 EGL 的关系?_glumes的技术博客_51CTO博客Android OpenGL 开发—— EGL详解 - 掘金

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

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

相关文章

【机器学习】调配师:咖啡的完美预测

有一天&#xff0c;小明带着一脸期待找到了你这位数据分析大师。他掏出手机&#xff0c;屏幕上展示着一份详尽的Excel表格。“看&#xff0c;这是我咖啡店过去一年的数据。”他滑动着屏幕&#xff0c;“每个月的销售量、广告投入&#xff0c;还有当月的气温&#xff0c;我都记录…

踏上职业征程的第一步——选择理想城市迎接大学生求职新起点

概要&#x1f481;&#x1f3fb; "嘿&#xff0c;这个话题我早就想聊聊了。感觉现在好多同学在找工作时&#xff0c;签约和工作地点的选择都有点盲目。很少有人主动考虑自己喜欢哪个城市&#xff0c;所以我想说说这个。当然&#xff0c;纯属个人看法&#xff0c;大家随便吐…

模型的 PSI(Population Stability Index)

PSI&#xff08;Population Stability Index&#xff09;是一种用于评估两个数据集或时间点之间的分布变化的指标。它常用于监测模型在不同时间段或不同群体上的稳定性。PSI的计算基于两个分布的累积分布函数&#xff08;CDF&#xff09;之间的差异。 在模型监测和评估的背景下…

Django(九)

1. 用户登录-Cookie和Session 什么是cookie和session&#xff1f; 发送HTTP请求或者HTTPS请求(无状态&短连接) http://127.0.0.1:8000/admin/list/ https://127.0.0.1:8000/admin/list/http无状态短连接&#xff1a;一次请求响应之后断开连接&#xff0c;再发请求重新连…

Keepalived实现nfs高可用

Keepalived实现nfs高可用 Nfs_master服务器&#xff1a;172.20.26.167 &#xff08;keepalived、nfs、sersync、rsync&#xff09; Nfs_salve服务器&#xff1a;172.20.26.198 &#xff08;keepalived、nfs、rsync&#xff09; Nfs_client服务器&#xff1a;172.20.26.24 …

LeetCode面试题05.06

美好的一天&#xff0c;从力扣开始 王子公主请看题 整数转换。编写一个函数&#xff0c;确定需要改变几个位才能将整数A转成整数B。 示例1: 输入&#xff1a;A 29 &#xff08;或者0b11101&#xff09;, B 15&#xff08;或者0b01111&#xff09;输出&#xff1a;2示例2: 输…

Python爬虫--5

1、异步爬虫 异步爬虫的方式&#xff1a; &#xff08;1&#xff09;多线程&#xff0c;多进程&#xff08;不建议使用&#xff09; 好处&#xff1a;可以为相关阻塞的操作单独开启线程或者进程&#xff0c;阻塞操作就可以异步执行。 弊端&#xff1a;无法无限制的开启多线程…

Docker安装配置OnlyOffice

OnlyOffice 是一款强大的办公套件&#xff0c;你可以通过 Docker 轻松安装和部署它。本文将指导你完成安装过程。 步骤 1&#xff1a;拉取 OnlyOffice Docker 镜像 首先&#xff0c;使用以下命令从 Docker Hub 拉取 OnlyOffice Document Server 镜像&#xff1a; sudo docke…

【代码随想录09】28. 找出字符串中第一个匹配项的下标 459. 重复的子字符串

目录 28. 找出字符串中第一个匹配项的下标题目描述参考代码 459.重复的子字符串题目描述参考代码 28. 找出字符串中第一个匹配项的下标 题目描述 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08…

Spring Boot3.2.2整合MyBatis Plus3.5.5

目录 1.前置条件 2.导坐标 3.配置数据源 4.配置mapper扫描路径 5.MyBatis Plus代码生成器整合 1.导坐标 2.编写代码生成逻辑 1.前置条件 已经初始化好一个spring boot项目且版本为3X&#xff0c;项目可正常启动 2.导坐标 <dependency><groupId>com.baomid…

深入了解性能优化(web应用)

影响一个系统性能的方方面面 一个 web应用不是一个孤立的个体,它是一个系统的部分,系统中的每一部分都会影响整个系统的性能 一.常用的性能评价/测试指标 1.响应时间 提交请求和返回该请求的响应之间使用的时间,一般比较关注平均响应时间。 常用操作的响应时间列表: 操作 响应…

在达沃斯,人工智能引发的乐观情绪可谓一分为二

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

动手做个无人机—材料篇

基于浙江大学Fast-Lab(高飞&#xff0c;潘能)和深蓝学院合作课程&#xff1a;第二课&#xff1a;动力套焊接_哔哩哔哩_bilibili 无人机材料1&#xff1a; 1、NUC 猛虎峡谷 准系统 i5薄款&#xff1a; 一款机载电脑&#xff0c;使用i5-1135G7 &#xff0c;最大内存64G&#xff…

java-BigDecimal

为什么浮点数 float 或 double 运算的时候会有精度丢失的风险呢&#xff1f; 这个和计算机保存浮点数的机制有很大关系。我们知道计算机是二进制的&#xff0c;而且计算机在表示一个数字时&#xff0c;宽度是有限的&#xff0c;无限循环的小数存储在计算机时&#xff0c;只能被…

数据结构--数组和广义表

1. 数组的定义 略 2. 数组的顺序表示 由于数组定义后&#xff0c;数组的维度和每维的长度就不再改变&#xff0c;其结构是固定的&#xff0c;因此一般采用顺序存储结构。 3. 特殊矩阵的压缩矩阵 4. 广义表的定义和抽象操作 广义表一些操作可以看数据结构--广义表_空广义表的…

机器学习:BootStrapping(Python)

import numpy as np import pandas as pd from sklearn.neighbors import KNeighborsClassifier from sklearn.decomposition import PCA # 主成分分析 from sklearn.preprocessing import LabelEncoder, StandardScaler # 类别标签编码&#xff0c;标准化处理 import matplo…

uniapp组件库SwipeAction 滑动操作 使用方法

目录 #平台差异说明 #基本使用 #修改按钮样式 #点击事件 #API #Props #Event 该组件一般用于左滑唤出操作菜单的场景&#xff0c;用的最多的是左滑删除操作。 注意 如果把该组件通过v-for用于左滑删除的列表&#xff0c;请保证循环的:key是一个唯一值&#xff0c;可以…

k8s 使用tomcat官方镜像部署集群并解决访问页面404

一、集群节点配置&#xff1a; master:192.168.206.138 k8s-node1:192.168.206.136 k8s-node2:192.168.206.137 二、下载一个Tomcat镜像 docker pull tomcat docker images | grep tomcat docker tag docker.io/tomcat tomcat 三、根据官方镜像自己构建一个一次性就能启动的…

怎样的安全数据交换系统 可以支持信创环境?

首先&#xff0c;我来看看&#xff0c;什么是安全数据交换系统&#xff1f;安全数据交换系统是一种专门设计用于在不同网络环境之间安全传输数据的技术解决方案。它确保数据在传输过程中的完整性、机密性和可用性&#xff0c;同时遵守相关的数据保护法规和行业标准。 那么&…

笔试面试题——二叉树进阶(一)

&#x1f4d8;北尘_&#xff1a;个人主页 &#x1f30e;个人专栏:《Linux操作系统》《经典算法试题 》《C》 《数据结构与算法》 ☀️走在路上&#xff0c;不忘来时的初心 文章目录 一、根据二叉树创建字符串1、题目讲解2、思路讲解3、代码实现 二、二叉树的分层遍历1、题目讲…