opengl es学习笔记3(EGL使用流程,EGL命令)

来源:互联网 发布:网络变声电话 编辑:程序博客网 时间:2024/04/28 11:48

EGL提供了opengl es和运行于计算机上的原生窗口系统之间的一个结合层次,如下为调用EGL的一般流程:

 

1.与窗口系统通信

调用如下函数打开与EGL显示服务器的连接:

EGLDisplaye glGetDisPlay(EGLNativeDisplayType displayId)

displayId为了匹配原生窗口系统的显示类型,默认为EGL_DEFAULT_DISPLAY

(一般都选择默认值)

 

eg: EGLDisplay display=eglGetDisplay(EGL_DEFAULT_DISPLAY)//打开与EGL的连接

If(display==EGL_NO_DISPLAY)  //表示EGL不可用

{

return EGL_FALSE;

}

检查错误:

EGLint eglGetError()  可返回错误代码,如返回EGL_SUCCESS表示没有错误。

 

2.初始化EGL

EGLboolean eglInitialize(EGLDisplay display,

     EGLint *majorVersion,

 EGLint *minorVersion)

display 指定EGL显示连接

majorVersion 指定EGL实现返回的主版本号

minorVersion 指定EGL实现返回的次版本号

 

eg:  EGLint major,minor;

if(!eglInitialize(display,&major,&minor))   //如果不能初始化EGL

{

return EGL_FALSE;      

}

 

3.让EGL选择配置(确定可用表面)

一旦初始化了EGL,就可以确定可用渲染表面的类型和配置,有2中方法:

(1)查询每个表面配置,找出最好的选择。

(2)指定一组需求,让EGL推荐最佳匹配

不管哪一种,EGL都返回一个EGLConfig(包含有关特定表面及其特性的EGL内部数据结构的标识符)

这里是第二种方法:

EGLBoolean eglChooseConfig(EGLDisplay display,

  Const EGLint *attribList,

        EGLConfig *configs,

  EGLint maxReturnConfigs,

  EGLint *numConfigs)

attribList 指定configs匹配的属性列表

configs              指定配置列表

maxReturnConfigs     指定配置大小

numConfigs 指定返回的配置大小

 

eg:  const EGLint configAttibs[]=    //属性列表

{

EGL_RENDER_TYPE,EGL_WINDOW_BIT,   //属性的相关首选值

EGL_RED_SIZE,8,

EGL_GREEN_SIZE,8

EGL_BLUE_SIZE,8

EGL_DEPTH_SIZE,24

EGL_NONE

}

 

EGLConfig config;

EGLint numConfigs;

if(!eglChooseConfig(display,configAttribs,&config,1,&numConfigs))

{      //如果成功返回则返回一组匹配你的标准的EGLConfig

Return EGL_FALSE;

}

 

4.创建屏幕上的渲染区域:EGL窗口

一旦我们有了符合渲染需求的EGLConfig就为创建窗口做好了准备。调用创建窗口:

EGLSurface eglCreateWindowSurface(EGLDisplay display,

EGLConfig config,

EGLNativeWindowType window,

Const EGLint *attribList)

display 指定EGL显示连接

config 指定配置

window   指定原生窗口

attribList 指定窗口属性列表;可能为NULL(所有相关属性设置为默认值)

 

eg:  EGLint attribList[]{

EGL_RENDER_BUFFER,EGL_BACK_BUFFER,//后台缓冲区

EGL_NONE

};

EGLSurface window=eglCreateWindowSurface(display,config,nativeWindow,

attribList或直接用NULL);

If(window==EGL_NO_SURFACE)

{

return  EGL_FALSE; 

 

或者你可以选择创建屏幕外渲染区域:EGL Pbuffer(不详细介绍了)


5.创建一个渲染上下文

  如果把渲染引擎看做一个画家,那么画家开始作画之前需要做一系列的准备工作,譬如:布置好场景,摆好画架,钉好画布,调整好灯光,准备号画笔油彩,站好位置,然后才能开始下笔作画。

  前期的这一系列准备过程在D3DOgl这样的渲染Api中对应了一系列的接口函数,这些函数初看起来又多又乱,有时调用顺序还有一定的耦合性,因此需要精心的组织这些接口,一种比较好的方法是将这些接口组织成一个叫做渲染上下文(Rendering Context)的类。

  渲染上下文是opengl es的内部数据结构,包含操作所需的所有状态信息。Opengl es必须有一个可用的上下文才能绘图。

EGLContext eglCreateContext(EGLDisplay display,

 EGLConfig config,

 EGLContext shareContext

 Const EGLint *attribList)

display 指定EGL显示连接

config 指定配置

shareContext 允许多个EGL上下文共享特定类型的数据,

使用EGL_NO_CONTEXT表示没有共享  

attribList 指定创建上下文使用的属性列表;只有一个可接受的属性

     EGL_CONTEXT_CLIENT_VERSION(opengl es的具体版本eg:3)

 

eg:  const EGLint contextAttribs[]=

{

EGL_CONTEXT_CLIENT_VERSION,3,

EGL_NONE

};

  EGLContext context=eglCreateContext(display,config,EGL_NO_CONTEXT,

  contextAttribs);

  if(context==EGL_NO_CONTEXT){

return EGL_FALSE;

}

 

6.指定某个EGLContext为当前上下文

因为一个应用程序可能创建多个EGLContext用于不同的用途,所以我们需要关联特定的EGLContext和渲染表面---这一过程常常被称作“指定当前上下文”。

EGLBoolean eglMakeCurrent(EGLDisplay display,

 EGLSurface draw,

 EGLSurface read,

 EGLContext context)

draw 指定EGL绘图表面

read 指定EGL读取表面

context 指定连接到该表面的渲染上下文

 

eg:  if(!eglMakeCurrent(display,window,window,context))

{

return EGL_FALSE;

}

 

创建EGL窗口的完整例程:

EGLboolean initializeWindow(EGLNativewindow nativeWindow)

{

const EGLint configAttribs[]=

{

EGL_RENDER_TYPE,EGL_WINDOW_BIT,

EGL_RED_SIZE,8

EGL_GREEN_SIZE,8

EGL_BLUE_SIZE,8

EGL_DEPTH_SIZE,24

EGL_NONE

};

 

const EGLint contextAttribs[]=

{

EGL_CONTEXT_CLIENT_VERSION,3,

EGL_NONE

};

//打开与EGL显示服务器的连接

EGLDisplay display=eglGetDisplay(EGL_DEFAULT_DISPLAY)

if(display==EGL_NO_DISPLAY)

{

return EGL_FALSE;

}

//初始化EGL

EGLint major,minor;

if(!eglInitialize(display,&major,&minor))

{

return EGL_FALSE;

}

//EGL选择表面配置

EGLConfig config;

EGLint numConfigs;

if(!eglChooseConfig(display,configAttribs,&config,1,&numConfigs))

{

return EGL_FALSE;

}

//渲染屏幕上的渲染区域(EGL窗口)

EGLSurface window=eglCeateWindowSurface(display,config,nativeWindow,NULL)

if(window==EGL_NO_SURFACE)

{

return EGL_FALSE;

}

//创建一个渲染上下文

   EGLContext context=eglCreateContext(display,config,EGL_NO_CONTEXT,contextAttribs)

if(context==EGL_NO_CONTEXT)

{

return EGL_FALSE;

}

//指定context为当前上下文

if(!eglMakeCurrent(display,window,window,context))

{

return EGL_FALSE;

}

return EGL_TRUE;

}

 

  题外(缓冲区):

  首先颜色缓冲区就是帧缓冲区,你需要渲染的场景最终每一个像素都要写入该缓冲区,然后由它在渲染到屏幕上显示.
  深度缓冲区与帧缓冲区对应,用于记录上面每个像素的深度值,通过深度缓冲区,我们可以进行深度测试,从而确定像素的遮挡关系,保证渲染正确.
  模版缓冲与深度缓冲大小相同,通过设置模版缓冲每个像素的值,我们可以指定在渲染的时候只渲染某些像素,从而可以达到一些特殊的效果.
具体的使用可以多看看相关的例子.

0 0