零基础 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);
九.猜你喜欢
- OpenGL ES 简介
- OpenGL ES 版本介绍
- OpenGL ES 2.0 和 3.0区别
- OpenGL ES 名词解释(一)
- OpenGL ES 名词解释(二)
- OpenGL ES GLSL 着色器使用过程
- OpenGL ES EGL 简介
- OpenGL ES EGL 名词解释
暂无评论内容