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.創建一個渲染上下文
如果把渲染引擎看做一個畫家,那麼畫家開始作畫之前需要做一系列的準備工作,譬如:佈置好場景,擺好畫架,釘好畫布,調整好燈光,準備號畫筆油彩,站好位置,然後才能開始下筆作畫。
前期的這一系列準備過程在D3D和Ogl這樣的渲染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;
}
題外(緩衝區):
首先顏色緩衝區就是幀緩衝區,你需要渲染的場景最終每一個像素都要寫入該緩衝區,然後由它在渲染到屏幕上顯示.
深度緩衝區與幀緩衝區對應,用於記錄上面每個像素的深度值,通過深度緩衝區,我們可以進行深度測試,從而確定像素的遮擋關係,保證渲染正確.
模版緩衝與深度緩衝大小相同,通過設置模版緩衝每個像素的值,我們可以指定在渲染的時候只渲染某些像素,從而可以達到一些特殊的效果.
具體的使用可以多看看相關的例子.