很多朋友对于深入解析OpenGL ES中的EGL接口和不太懂,今天就由小编来为大家分享,希望可以帮助到大家,下面一起来看看吧!
二EGL 数据类型与初始化
EGL 包含自己的一组数据类型,并且还提供对一组特定于平台的本机数据类型的支持。
标准 EGL 数据类型如下所示:
EGL布尔值——EGL_TRUE=1, EGL_FALSE=0
EGLint —————int 数据类型
EGLDisplay ———系统显示ID或句柄,可以理解为前端显示窗口
EGLConfig ——Surface的EGL配置可以理解为绘制目标framebuffer的配置属性。
EGLSurface —— 系统窗口或帧缓冲区句柄可以理解为后端渲染目标窗口。
EGLContext ——OpenGL ES图形上下文,代表OpenGL状态机;没有它,就没有OpenGL指令的执行环境。
EGL Displays
EGLDisplay 是与系统物理屏幕相关的常见数据类型。它代表显示设备句柄,也可以认为是前端显示窗口。为了使用系统的显示设备,EGL提供了EGLDisplay数据类型,以及一组用于操作设备显示的API。
下面的函数原型用于获取Native Display:
EGLDisplayeglGetDisplay(NativeDisplayType显示);其中display参数是本机系统的窗口显示ID值。如果您只想要系统默认显示,则可以使用EGL_DEFAULT_DISPLAY 参数。如果系统上没有与给定显示参数匹配的可用本机显示ID,则该函数将返回EGL_NO_DISPLAY,而不设置任何错误状态。
由于设置无效的显示值不会导致任何错误状态,因此请在继续之前检查返回值。下面是使用EGL API获取系统Display的示例:
m_eglDisplay=eglGetDisplay(system.display);
if (m_eglDisplay==EGL_NO_DISPLAY || eglGetError() !=EGL_SUCCESS))
抛出error_egl_display;
Initialization 初始化
每个EGLDisplay在使用前都需要初始化。初始化EGLDisplay时,可以获取系统中的EGL实现版本号。就向后兼容性而言,了解当前版本号非常有价值。在移动设备上,通过动态查询EGL 版本号,您可以将附加功能或运行时环境附加到新旧版本的EGL。根据平台配置,软件开发人员可以准确地知道哪些API是可访问的,这将为您的代码提供最大的可移植性。
以下是初始化EGL的函数原型:
EGLBoolean eglInitialize (EGLDisplay dpy, EGLint *主要, EGLint *次要);其中dpy 应该是有效的EGLDisplay 。当函数返回时,major 和minor 将被分配当前的EGL 版本号。例如,EGL1.0 对于主要返回1,对于次要返回0。如果您不关心版本号,则为主版本和次版本传递NULL 是有效的。
初始化EGL
EGL初始化如下:
1. 获取Display。
要获取显示,请致电
EGLboolean eglGetDisplay(NativeDisplay dpy) 参数一般为EGL_DEFAULT_DISPLAY。
2. 初始化egl。
致电
EGLboolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) 该函数将执行一些内部初始化工作并返回EGL 版本号(major.minor)。
3. 选择Config。
Config实际上指的是FrameBuffer的参数。
一般使用
EGLboolean eglChooseConfig(EGLDisplay dpy, const EGLint * attr_list, EGLConfig * config, EGLint config_size, EGLint *num_config) 其中attr_list是以EGL_NONE结尾的参数数组,通常按照id和value的顺序存储。对于个体标识属性,只能使用id。没有价值。
该函数会返回不超过config_size的Config,结果保存在config[]中,系统中Config的总数保存在num_config中。
4、构造Surface。
Surface实际上是一个FrameBuffer,它是渲染目的地。
经过
EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig confg, NativeWindow win, EGLint *cfg_attr) 创建一个真正可以显示的Surface。
5、创建Context。
从程序角度来看,OpenGL ES的管线是一个状态机,有当前颜色、纹理坐标、变换矩阵、染色模式等很多状态。这些状态作用于OpenGL API 程序提交的顶点坐标和其他图形。因此,元素在帧缓冲区内形成像素。在OpenGL编程接口中,Context代表这个状态机。 OpenGL API程序的主要工作就是向Context提供图形元素,设置状态,偶尔也会从Context中获取一些信息。
可以使用
EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write, EGLSurface read, EGLContext * share_list) 创建一个Context。
6、EGL变量之间的绑定
boolean eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context) 该接口绑定应用的显示、绘制(表面)和上下文。也就是说,上下文下的OpenGLAPI指令将draw(surface)作为其最终渲染目的地。而display作为draw(surface)的前端显示。调用后,当前线程使用的EGLContex就是上下文。
7. 绘制。
应用程序通过OpenGL API进行绘制。一帧完成后,调用eglSwapBuffers(EGLDisplay dpy, EGLContext ctx)进行显示。
EGL Configurations 属性配置
EGLConfigs是用于描述EGL表面配置信息的数据类型。为了得到正确的渲染结果,Surface的格式非常重要。根据平台的不同,表面配置可能有限制。例如,某个平台或设备支持16位色深显示,或者不支持模板缓冲区,以及其他功能限制或精度差异。
以下是获取系统上可用的EGL配置信息的函数原型:
EGLBoolean eglGetConfigs (EGLDisplay dpy, EGLConfig *configs,EGLint config_size, EGLint *num_config);
configs 参数将包含在您的平台上有效的所有EGL 帧缓冲区配置的列表。支持的配置总数将通过num_config 返回。实际返回的configs配置数量取决于程序传入的config_size。如果config_size num_config ,则不会返回所有配置信息。如果你想获取系统支持的所有配置信息,最好的方法是首先向eglGetConfig传递一个NULL configs参数。 num_config会获取系统支持的配置总数,然后用它为configs分配合适的内存大小,然后用configs调用eglGetConfig。
以下是EGL初始化的代码:
虚拟布尔初始化(void *win)
{
关闭();
//初始化EGL
m_mutex.lock();
//1 获取显示设备的EGLDisplay对象
m_eglDisplay=eglGetDisplay(EGL_DEFAULT_DISPLAY);
如果(m_eglDisplay==EGL_NO_DISPLAY)
{
m_mutex.unlock();
XLOGE("eglGetDisplay 失败!");
返回假;
}
XLOGE("eglGetDisplay成功!");
//2 初始化显示
if (EGL_TRUE !=eglInitialize(m_eglDisplay, 0, 0))
{
m_mutex.unlock();
XLOGE("egl初始化失败!");
返回假;
}
XLOGE("egl初始化成功!");
//3 获取配置并创建surface
EGLint 配置[]={
EGL_RED_SIZE,8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
EGL_SURFACE_TYPE,
EGL_WINDOW_BIT,
EGL_无
};
EGL配置egl配置=0;
EGLint numConfigs=0;
如果(EGL_TRUE!=eglChooseConfig(m_eglDisplay,配置,eglConfig,1,numConfigs))
{
m_mutex.unlock();
XLOGE("eglChooseConfig 失败!");
返回假;
}
XLOGE("eglChooseConfig成功!");
ANativeWindow *nativeWindow=(ANativeWindow *)win;
m_eglSurface=eglCreateWindowSurface(m_eglDisplay,eglConfig,nativeWindow,NULL);
//4 创建并打开EGL上下文
const EGLint contextAttr[]={ EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
m_eglContext=eglCreateContext(m_eglDisplay,eglConfig,EGL_NO_CONTEXT,contextAttr);
如果(m_eglContext==EGL_NO_CONTEXT)
{
m_mutex.unlock();
XLOGE("eglCreateContext 失败!");
返回假;
}
XLOGE("eglCreateContext成功!");
如果(EGL_TRUE!=eglMakeCurrent(m_eglDisplay,m_eglSurface,m_eglSurface,m_eglContext))
{
m_mutex.unlock();
XLOGE("eglMakeCurrent 失败!");
返回假;
}
XLOGE("eglMakeCurrent 成功!");
m_mutex.unlock();
返回真;
}每次Opengles完成后,调用EGL进行显示
虚拟无效绘制()
{
m_mutex.lock();
if (m_eglDisplay==EGL_NO_DISPLAY || m_eglSurface==EGL_NO_SURFACE)
{
m_mutex.unlock();
返回;
}
eglSwapBuffers(m_eglDisplay, m_eglSurface);
m_mutex.unlock();
}释放EGL的资源如下:
虚拟无效关闭()
{
m_mutex.lock();
如果(m_eglDisplay==EGL_NO_DISPLAY)
{
m_mutex.unlock();
返回;
}
eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
if (m_eglSurface !=EGL_NO_SURFACE)
eglDestroySurface(m_eglDisplay, m_eglSurface);
if (m_eglContext !=EGL_NO_CONTEXT)
eglDestroyContext(m_eglDisplay, m_eglContext);
eglTerminate(m_eglDisplay);
m_eglDisplay=EGL_NO_DISPLAY;
m_eglSurface=EGL_NO_SURFACE;
m_eglContext=EGL_NO_CONTEXT;
OK,本文到此结束,希望对大家有所帮助。
【深入解析OpenGL ES中的EGL接口】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
我对图形渲染一直很有兴趣,这篇文章能让我更好地理解OpenGLES和EGL之间的关系吗?
有13位网友表示赞同!
想深入学习Android平台上的3D游戏开发,这篇博客看起来很合适。
有5位网友表示赞同!
我已经有点了解OpenGL ES了,但对EGL接口的理解比较浅。希望这篇文章能够详细介绍一些细节。
有13位网友表示赞同!
最近在尝试用OpenGLES在移动端做简单的图形渲染,感觉有点困难,希望能从这篇文章中找到一些帮助。
有13位网友表示赞同!
分享这个标题看起来很干货,希望能对EGL接口有个更深入的了解。
有7位网友表示赞同!
学习OpenGL ES遇到了一些问题,也许这篇文章能帮我解答一些疑惑。
有18位网友表示赞同!
感觉EGL接口有点抽象,这篇博客能帮助我更好地理解它是怎么运作的吗?
有17位网友表示赞同!
做图形编程开发一段时间了,对 OpenGLES 和 EGL 的关系很有兴趣,来详细学习一下。
有7位网友表示赞同!
想了解更多关于屏幕渲染方面的知识,这篇文章看起来很值得一看。
有8位网友表示赞同!
在研究移动设备图形渲染技术时,我需要了解EGL接口,这本书应该可以帮助我
有19位网友表示赞同!
一直在寻找一些深入讲解OpenGL ES和EGL的资源,这篇文章恰好是我的需求。
有5位网友表示赞同!
这个标题很有吸引力!希望能够通过文章详细理解OpenGL ES和EGL的关系。
有6位网友表示赞同!
作为一名图形编程爱好者,我期待阅读这篇关于 EGL 接口解析的文章。
有11位网友表示赞同!
想学习一些更高级的渲染技术,这篇文章可能让我了解到一些新的概念
有12位网友表示赞同!
最近接触 OpenGL ES 的开发,希望能从这篇文章中获取更多实际知识。
有18位网友表示赞同!
希望这篇文章能清晰解释 EGL 接口的使用方法和相关细节。
有14位网友表示赞同!
想深入学习如何将图形渲染程序编写的框架, 这篇文章看起来很有帮助。
有5位网友表示赞同!
对EGL接口的使用过程一知半解,希望能通过这篇文章获得更清晰的理解。
有9位网友表示赞同!