草庐IT

OpenGL ES EGL 名词解释

猿说编程 2023-04-08 原文

目录

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 特效

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 转场

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 函数

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES GPUImage 使用

零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES GLSL 编程

一.前言

OpenGL ES 定义了一个渲染图形的 API。它没有定义窗口系统。为了使 OpenGL ES 可以工作于各种平台之上,我们可以通过 google angle 完成;

ANGLE 的目标是通过将 OpenGL ES API 调用转换为该平台可用的硬件支持的 API 之一,。就是把 OpenGL ES 翻译成其他的语言,譬如说 D3D9 / OpenGL ES / Vulkan / Metal 等等。

ANGLE 支持 Windows / Mac / Linux / Android / Ios ;

ANGLE 目前提供从 OpenGL ES 2.0、3.0 和 3.1 到 Vulkan、桌面 OpenGL、OpenGL ES、Direct3D 9 和 Direct3D 11 的转换;

详细参考:OpenGL ES EGL 简介

二.EGLNativeDisplayType

EGLNativeDisplayType 在 OpenGL ES 与本地窗口系统之间架起了一座沟通的桥梁,EGLNativeDisplayType 一般使用默认的 EGL_DEFAULT_DISPLAY,在不同平台其实现是不同的,EGL 只提供抽象标准,在 Windwos 中 该值默认为 DX ,如果想使用 OPenGL,可以通过如下设置配置

EGLAttrib dispattrs[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE,
                EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE,EGL_NONE };

三.EGLNativeWindowType

EGLNativeWindowType 表示窗口句柄,在不同平台其实现是不同的,EGL 只提供抽象标准,在 Windows 中 EGLNativeWindowType 实际上就是窗口句柄 HWND ,头文件声明如下:

#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP) /* Windows Desktop */

typedef HWND    EGLNativeWindowType;
#else
/* Windows Store */
#include <inspectable.h>
typedef IInspectable* EGLNativeWindowType;

#endif

如果是想在窗口实时查看渲染结果,我们可以通过 eglCreateWindowSurface 创建可显示的 EGLSurface ,绑定窗口 HWND 后预览显示;

如果是离屏幕渲染,不需要绑定窗口,那么就不需要该参数,可以直接使用 eglCreatePbufferSurface 创建不可显示的 EGLSurface,保存在显存中的帧;

四.EGLDisplay

**EGLDisplay 是一个关联系统物理屏幕的通用数据类型。**对于 PC 来说, EGLDisplay 就是显示器的句柄。不管是嵌入式系统或 PC ,都可能有多个物理显示设备。为了使用系统的显示设备, EGL 提供了 EGLDisplay 数据类型,以及一组操作设备显示的 API 。

在不同平台上有不同的机制以关联窗口系统,在 Windows 上是 WGL ,在 Linux 上是 GLX ,在 Apple OS 上是 AGL 等。

**EGL 则是平台上 WGL / GLX / AGL 的等价物。**eglGetDisplay 为原生窗口系统 displayId 获取一个 EGL display 连接,在 OpenGL ES 与本地窗口系统之间架起了一座沟通的桥梁

EGLDisplay eglGetDisplay(EGLNativeDisplayType displayId);

1.默认原生窗口渲染

EGLNativeDisplayType 默认为 EGL_DEFAULT_DISPLAY ,即返回与默认原生窗口的连接,在 Windows 中默认为 DX 渲染

eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);

2.强制启用 OPenGL 渲染

EGLAttrib dispattrs[] = { EGL_PLATFORM_ANGLE_TYPE_ANGLE,
            EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE,EGL_NONE };

eglDisplay = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
            EGL_DEFAULT_DISPLAY, dispattrs);

五.EGLConfig

EGLConfig 是对 EGLSurface 的 EGL 配置,可以理解为绘制目标 framebuffer 的配置属性

六.EGLSurface

EGLSurface 也被称为渲染区域,系统窗口或 frame buffer 句柄 ,可以理解为一个后端的渲染目标窗口 ;

** EGLSurface 相当于一块画布(一块内存空间),用户想绘制的信息首先都要先绘制到 EGLSurface 上**

EGLSurface 分为以下三类:

1.Surface – 可显示的 Surface,实际上就是一个 FrameBuffer,用于绑定窗口后预览显示;

2.PixmapSurface – 不是可显示的 Surface,保存在系统内存中的位图;

3.PBufferSurface – 不是可显示的 Surface,保存在显存中的帧,用于离屏渲染,不需要绑定窗口

1.创建屏幕上的渲染区域 – EGL 窗口,实时预览

eglCreateWindowSurface 成功时返回新创建的 EGLSurface ,失败时返回 EGL_NO_SURFACE.

EGLSurface eglCreateWindowSurface(
	EGLDisplay display,	        //对应的EGL display连接
 	EGLConfig config,	        //EGL frame buffer配置
 	NativeWindowType native_window,	//原生窗口
 	EGLint const * attrib_list);	// Window Surface属性列表,可以为NULL

2.创建屏幕外的渲染区域 – 离屏渲染

创建一个离屏 pixel buffer surface 返回它的句柄

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

相关错误码:

EGL_BAD_MATCH :提供了与窗口属性不匹配的 EGLConfig,或该 EGLConfig 不支持渲染到窗口
EGL_BAD_CONFIG :提供的 EGLConfig 没有得到系统支持
EGL_BAD_NATIVE_WINDOW :提供的原生窗口句柄无效
EGL_BAD_ALLOC :无法为新的窗口分配资源,或已经有和提供的原生窗口关联的 EGLConfig

七.EGL Pbuffer 创建屏幕外渲染区域

除了可以用 OpenGL ES 3.0 在屏幕上的窗口渲染之外,还可以渲染称作 Pbuffer (像素缓冲区 Pixel buffer 简写)的不可见的屏幕外表面,不需要绑定窗口,用于离屏渲染。

和窗口一样,pbuffer 可以利用 OpenGL ES 3.0 中的任何硬件加速。Pbuffer 最常用于生成纹理贴图。如果你想要做的是渲染到一个纹理,那么我们建议使用帧缓冲区代替 Pbuffer,因为 帧缓冲区更高效。

创建 Pbuffer 和创建 EGL 窗口非常类似,只有少数微小的不同。为了创建 Pbuffer ,需要和窗口一样找到 EGLConfig ,并作一处修改:我们需要扩增 EGL_SURFACE_TYPE 的值,使其包含 EGL_PBUFFER_BIT。

EGLSurface eglCreatePbufferSurface(
            EGLDisplay display, // 指定EGL显示连接
            EGLConfig config, // 符合条件的 EGLConfig
            const EGLint *attribList); // 指定像素缓冲区属性列表,可为 NULL

创建一个 EGL 像素缓冲区:

	EGLint attribList[] = {
			EGL_SURFACE_TYPE,EGL_PBUFFER_BIT,
			EGL_RENDERABLE_TYPE, EGL_OPENGL_ES3_BIT_KHR,
			EGL_RED_SIZE, 5,
			EGL_GREEN_SIZE, 6,
			EGL_BLUE_SIZE, 5,
			EGL_DEPTH_SIZE, 1,
			EGL_NONE
	};

   // 查询EGL表面配置

	const EGLint MaxConfigs = 10;
	EGLConfig configs[MaxConfigs]; // We'll only accept 10 configs
	EGLint numConfigs;
	if (!eglChooseConfig(display, attribList, configs, MaxConfigs, &numConfigs)) {
		// Something didn't work … handle error situation
	} else {
		// Everything's okay. Continue to create a rendering surface
	}

    // Proceed to create a 512*512 pbuffer
	EGLSurface pbuffer;
	EGLint attribList2[] =
			{
					EGL_WIDTH, 512,
					EGL_HEIGHT, 512,
					EGL_LARGEST_PBUFFER, EGL_TRUE,
					EGL_NONE
			};

	pbuffer = eglCreatePbufferSurface(display, config, attribList2);

	if (pbuffer == EGL_NO_SURFACE) {
		switch (eglGetError()) {
			case EGL_BAD_ALLOC:
				// Not enough resources available. Handle and recover
				break;

			case EGL_BAD_CONFIG:
				// Verify that provided EGLConfig is valid
				break;

			case EGL_BAD_PARAMETER:
				// Verify that EGL_WIDTH and EGL_HEIGHT are non-negative values
				break;

			case EGL_BAD_MATCH:
				// Check window and EGLConfig attributes to determine
				// compatibility, or verify that the EGLConfig
				// supports rendering to a window,
				break;
		}
	}

	EGLint width;
	EGLint height;
	if(!eglQuerySurface( display,pbuffer,EGL_WIDTH,&width) ||
	   !eglQuerySurface( display,pbuffer,EGL_HEIGHT,&height))
	{
		//Unable to query surface information
	}

八.EGLContext

1.创建上下文

OpenGL ES 图形上下文,它代表了 OpenGL 状态机;如果没有它,OpenGL 指令就没有执行的环境。

EGLAPI EGLContext EGLAPIENTRY eglCreateContext(
		EGLDisplay display,
                EGLConfig config,
                EGLContext share_context,
                const EGLint *attribList);

EGLContext 上下文包含了操作所需的所有状态信息,OpenGL ES 必须有一个可用的上下文才能进行绘图。

2.使用上下文

EGLAPI EGLBoolean EGLAPIENTRY eglMakeCurrent(
		EGLDisplay display,
                EGLSurface draw,
              	EGLSurface read, EGLContext context);

3.获取上下文信息

eglQueryContext 用于获取 Context 信息

EGLAPI EGLBoolean EGLAPIENTRY eglQueryContext(
                 EGLDisplay display,
                 EGLContext context,
                 EGLint attribute,
                 EGLint *value);

成功时返回 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

4.销毁渲染上下文

EGLAPI EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay display, EGLContext context);

九.猜你喜欢

  1. OpenGL ES 简介
  2. OpenGL ES 版本介绍
  3. OpenGL ES 2.0 和 3.0 区别
  4. OpenGL ES 名词解释(一)
  5. OpenGL ES 名词解释(二)
  6. OpenGL ES GLSL 着色器使用过程
  7. OpenGL ES EGL 简介
  8. OpenGL ES EGL 名词解释

有关OpenGL ES EGL 名词解释的更多相关文章

  1. ruby - 有人可以帮助解释类创建的 post_initialize 回调吗 (Sandi Metz) - 2

    我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法

  2. ruby - 解释为局部变量会覆盖方法名称吗? - 2

    如thisquestion,当在其自己的赋值中使用未定义的局部变量时,它的计算结果为nil。x=x#=>nil但是当局部变量的名称与现有的方法名称冲突时,就比较棘手了。为什么下面的最后一个示例返回nil?{}.instance_eval{a=keys}#=>[]{}.instance_eval{keys=self.keys}#=>[]{}.instance_eval{keys=keys}#=>nil 最佳答案 在Ruby中,因为可以在没有显式接收器和括号的情况下调用方法,所以在局部变量引用和无接收器无参数方法调用之间存在语法歧义:f

  3. 语法类似于 GitHub Flavored Markdown 的 Ruby markdown 解释器? - 2

    我使用Jekyll运行博客,并认为我会解决RedcarpetMarkdown解释器,因为它是developedandusedbyGitHub.好吧,我只是碰巧遇到了一个错误,去检查问题,然后foundthis.Maintainersays,"Asyouprobablyhavenoticed(harharharhar)Idon'thavetimetomaintainRedcarpetanymore.It'snotapriorityforme(IfindMarkdownthoroughlyboring)andit'snotapriorityforGitHub,becausewenolong

  4. ruby - 有人可以解释一下在 Ruby 中注入(inject)的真实、通俗易懂的用法吗? - 2

    我正在学习Ruby,遇到了inject。我正处于理解它的风口浪尖,但当我是那种需要真实世界的例子来学习一些东西的人时。我遇到的最常见的例子是人们使用inject来添加一个(1..10)范围的总和,我不太关心这个。这是一个任意的例子。在实际程序中我会用它做什么?我正在学习,所以我可以继续使用Rails,但我不必有一个以Web为中心的示例。我只需要一些我可以全神贯注的目标。谢谢大家。 最佳答案 inject有时可以通过它的“其他”名称reduce更好地理解。它是一个对Enumerable进行操作(迭代一次)并返回单个值的函数。它有许多有

  5. ruby - 一种语言如何被自身解释(如 Rubinius)? - 2

    我使用Ruby编程已经有一段时间了,现在只使用Ruby的标准MRI实现,但我一直对我经常听到的其他实现感到好奇。前几天我在读有关Rubinius的文章,这是一个用Ruby编写的Ruby解释器。我试着在不同的地方查找它,但我很难弄清楚这样的东西到底是如何工作的。我在编译器或语言编写方面从来没有太多经验,但我真的很想弄明白。一门语言究竟如何才能被自己解释?编译中是否有一个我不明白这有意义的基本步骤?有人可以像我是个白痴一样向我解释这个吗(因为无论如何这都不会太离谱) 最佳答案 它比你想象的要简单。Rubinius并非100%用Ruby编

  6. Ruby 代码解释 - 2

    谁能解释一下这段Ruby代码:defadd_spec_path_to(args)#:nodoc:args我看到了运算符用于连接字符串或在其他语言中用作按位运算符,但有人可以在这种情况下对其进行解释。它是以某种方式将一个空白的lamda附加到args上还是我完全错了?我还可以看到它是这样使用的:before_parts(*args)是Hash关键字?我也不确定||=是什么接线员在说。我同样对什么一无所知caller(0)[2]是。 最佳答案 我假设args是一个Array。Hash是类的名称-第一行将空哈希{}推送到argsunles

  7. python - 解释性语言中的链接和加载 - 2

    在编译型语言中,源代码由编译器转化为目标代码,不同的目标文件(如果有多个文件)由链接器链接并由加载器加载到内存中执行。如果我有一个使用解释性语言(例如ruby​​或python)编写的应用程序,并且如果源代码跨多个文件拆分,那么这些文件究竟何时组合在一起。换句话说,链接何时完成?解释型语言一开始就有链接器和加载器,还是解释器包揽一切?我真的很困惑,无法理解它!!谁能对此有所启发?! 最佳答案 解释型语言或多或少是可执行文件的大型配置,称为解释器。该可执行文件(例如/usr/bin/python)是实际运行的程序。然后它读取它要执行的

  8. ruby - 解释型语言(如 Ruby)如何运行? - 2

    我打算学习Ruby。我知道这是一种解释语言。我知道编译语言最终会被翻译成机器码,但是ruby​​解释器是做什么的呢?我读到解释器是用C编写的,但是每一行ruby​​都转换为c,然后再次编译为机器代码吗?我也听说过JIT,但是如果这会增加答案的复杂性,那么您就不需要回答它了。我正在寻找的是我的Ruby代码发生了什么。 最佳答案 它将Ruby代码转换为某种更简单的“中间”表示形式(在最近的版本中,它编译为字节码)。它还会在您计算机的内存中构建一个虚拟机,模拟执行该表示的物理机。这台机器是一台物理机器的镜像,至少在合理和有用的范围内。它通

  9. ruby - 有人可以用 Ruby 向我解释 NaN 吗? - 2

    我刚刚在我的程序中的一些数字操作中发现了一个错误,我得到了一个FloatDomainError(NaN)所以我开始记录传入的数字:if(metric.is_a?(Numeric))self.metric=metricelseLOGGER.warn("metric#{metric}isnotanumber")self.metric=0end但传入的数字是NaN显然is_a?(Numeric)因为我没有收到日志警告,它会将指标传递给我的指标=方法,这是我获取FloatDomainError的地方现在,如果我错了,请纠正我,但是NaN(不是数字)的类型似乎在语义上是错误的吗??谁能给我解释一

  10. ruby-on-rails - 你能解释一下这段 Ruby 代码中发生了什么吗? - 2

    我现在正在努力学习Ruby和RubyonRails。我正在学习LearningRails,第1版,但我很难理解其中的一些代码。我通常使用C、C++或Java工作,因此Ruby对我来说是一个很大的改变。我目前对数据库迁移器的以下代码块感到困惑:defself.upcreate_table:entriesdo|t|t.string:namet.timestampsendendt变量来自哪里?它实际上代表什么?它有点像for(i=0;i另外,:entries是在什么地方定义的?(entries是我的Controller的名称,但是这个函数怎么知道的?) 最佳答案

随机推荐