EGL簡(jiǎn)介以及窗口初始化

屏幕上可見的幀緩沖區(qū)由一個(gè)像素?cái)?shù)據(jù)的二維數(shù)組表示。直接在可顯示緩沖區(qū)上更新像素由一個(gè)嚴(yán)重的問題——用戶在部分更新幀緩沖區(qū)時(shí)看到偽像或者閃爍的現(xiàn)象

為了解決這個(gè)問題竹揍,引入了雙緩沖區(qū)州刽。

OpenGLES應(yīng)用程序中迎献,這種活動(dòng)通過EGL函數(shù)eglSwapBuffers控制:

eglSwapBuffers(exContext->eglDisplay, esContext->eglSurface);

EGL提供以下機(jī)制:

與設(shè)備的原生窗口系統(tǒng)通信

查詢繪圖表面的可用類型和配置

創(chuàng)建繪圖表面

在OpenGLES3.0和其它圖形渲染API(如桌面OpenGL和OpenVG——硬件加速矢量圖形的跨平臺(tái)API绢慢,活著窗口系統(tǒng)的原生繪圖命令)之間同步渲染

管理紋理貼圖等渲染資源

與窗口系統(tǒng)通信

Apple提供自己的EGL API的iOS 實(shí)現(xiàn)只嚣,稱為EAGL

因?yàn)槊總€(gè)窗口系統(tǒng)都有不同語義沮稚,所以EGL提供基本的不透明類型——EGLDisplay,該類封裝了所有系統(tǒng)相關(guān)性册舞,用于和原生窗口系統(tǒng)接口交互蕴掏。

任何使用EGL的應(yīng)用程序必須執(zhí)行的第一個(gè)操作是創(chuàng)建和初始化與本地EGL顯示的連接。

一调鲸、初始化EGL

EGLConfig config;

EGLint majorVersion;

EGLint minorVersion;

EGLint contextAttribs[] = {

EGL_CONTEXT_CLIENT_VERSION,? ? ? ? 3,? ? ? ? EGL_NONE

};

// 獲取寬和高

esContext->width = ANativeWindow_getWidth(esContext->eglNativeWindow);esContext->height = ANativeWindow_getHeight(esContext->eglNativeWindow);

// 打開與EGL顯示服務(wù)器的連接盛杰,默認(rèn)為EGL_DEFAULT_DISPLAY

esContext->eglDisplay = eglGetDisplay(esContext->eglNativeDisplay);

// 如果顯示連接不可用,則返回EGL_NO_DISPLAY標(biāo)志藐石,此時(shí)無法創(chuàng)建窗口

if (esContext->eglDisplay == EGL_NO_DISPLAY) {

return GL_FALSE;

}

// 初始化egl并回傳版本號(hào)

if (!eglInitialize(esContext->eglDisplay, &majorVersion, &minorVersion)) {

return GL_FALSE;

}

成功打開連接后即供,需要初始化EGL,這通過調(diào)用如下函數(shù)完成:

EGLAPI EGLBoolean EGLAPIENTRY eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor);

dpy —— 指定EGL顯示連接

major —— 返回EGL的主版本號(hào)

minor —— 返回EGL的副版本號(hào)

二于微、確定可用表面配置

一旦初始化了EGL逗嫡,就可以確定可用渲染表面的類型和配置,有兩種方法:

查詢每個(gè)表面配置株依,找出最好的選擇

指定一組需求祸穷,讓EGL推薦最佳配置

通常使用第二種方法更簡(jiǎn)單,而且最有可能得到匹配勺三。

任何一種情況下雷滚,EGL將返回一個(gè)EGLConfig,這是包含有關(guān)特定表面及其特性(每個(gè)顏色變量分量的位數(shù)吗坚、與EGLConfig相關(guān)的深度緩沖區(qū)(如果存在))的EGL內(nèi)部數(shù)據(jù)結(jié)構(gòu)的標(biāo)識(shí)符祈远。

EGLint numConfigs = 0;

EGLint attribList[] = {

EGL_RED_SIZE, 5,

EGL_GREEN_SIZE, 6,

EGL_BLUE_SIZE, 5,

EGL_ALPHA_SIZE, (flags & ES_WINDOW_ALPHA) ? 8 : EGL_DONT_CARE,

EGL_DEPTH_SIZE, (flags & ES_WINDOW_DEPTH) ? 8 : EGL_DONT_CARE,

EGL_STENCIL_SIZE, (flags & ES_WINDOW_STENCIL) ? 8 : EGL_DONT_CARE,

EGL_SAMPLE_BUFFERS, (flags & ES_WINDOW_MULTISAMPLE) ? 1 : 0,

EGL_RENDERABLE_TYPE, getContextRenderableType(esContext->eglDisplay),

EGL_NONE

};

// 選擇Config

if (!eglChooseConfig(esContext->eglDisplay, attribList, &config, 1, &numConfigs)) {

return GL_FALSE;

}

if (numConfigs < 1) {

return GL_FALSE;

}

三、查詢EGLConfig屬性

EGLConfig包含關(guān)于EGL啟用的表面的所有信息商源〕捣荩可用顏色、與配置相關(guān)的其它緩沖區(qū)(深度和模板緩沖區(qū)等)牡彻、表面類型和其它特性

// Android需要獲取EGL_NATIVE_VISUAL_ID的值并將其放如ANativeWindow_setBuffersGeometry函數(shù)中

EGLint format = 0;

eglGetConfigAttrib(esContext->eglDisplay, config, EGL_NATIVE_VISUAL_ID, &format);

ANativeWindow_setBuffersGeometry(esContext->eglNativeWindow, 0, 0, format);

四扫沼、創(chuàng)建屏幕上的渲染區(qū)域:EGL窗口

EGLAPI EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy,

EGLConfig config,

EGLNativeWindowType win,

const EGLint *attrib_list);

該函數(shù)用于創(chuàng)建一個(gè)窗口,以我們得到的原生顯示管理器的連接和前一步得到的EGLConfig為參數(shù)庄吼。它需要原生窗口系統(tǒng)事先創(chuàng)建一個(gè)窗口缎除。

創(chuàng)建窗口示例:

// 創(chuàng)建一個(gè)EGL窗口表面示例

EGLint list[] = {

EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE

};

EGLSurface window = eglCreateWindowSurface(esContext->eglDisplay, config,

esContext->eglNativeWindow, list);

if (window == EGL_NO_SURFACE) {

switch (eglGetError()) {

case EGL_BAD_MATCH:

break;

case EGL_BAD_CONFIG:

break;

case EGL_BAD_NATIVE_WINDOW:

break;

case EGL_BAD_ALLOC:

break;

}

}

上面的代碼是創(chuàng)建一個(gè)繪圖場(chǎng)景,但是我們還必須完成兩個(gè)步驟总寻,才能成功地用OpenGLES繪圖器罐。然而窗口不是唯一可用的渲染表面,也可以使用屏幕外渲染區(qū)域渐行,也就是離屏渲染轰坊。

屏幕外渲染區(qū)域(離屏渲染):EGL Pbuffer

OpenGLES3.0除了可以進(jìn)行屏幕渲染铸董,也可以在不可見的屏幕外渲染,也就是在像素緩沖區(qū)上進(jìn)行渲染肴沫,支持硬件加速粟害。Pbuffer最常用于紋理貼圖。

創(chuàng)建Pbuffer 和 創(chuàng)建EGL窗口非常相似颤芬,只有少數(shù)微笑的不同我磁。

創(chuàng)建Pbuffer需要和窗口一樣找到EGLConfig,并作一些修改:需要擴(kuò)增EGL_SURFACE_TYPE的值驻襟,使其包含EGL_PBUFFER_BIT夺艰。

創(chuàng)建EGL像素緩沖區(qū)示例如下:

EGLint bufferList[] = {

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

};

const EGLint MaxConfigs = 10;

EGLConfig configs[MaxConfigs];

EGLint numConfigs;

if (!eglChooseConfig(esContext->eglDisplay, bufferList, configs, MaxConfigs, &numConfigs)) {

return GL_FALSE;

}

EGLSurface pbuffer;

EGLint attribufferList[] = {

EGL_WIDTH, 512,

EGL_HEIGHT, 512,

EGL_LARGEST_PBUFFER, EGL_TRUE,

EGL_NONE

};

pbuffer = eglCreatePbufferSurface(esContext->eglDisplay, config, attribufferList);

if (pbuffer == EGL_NO_SURFACE) {

switch (eglGetError()) {

case EGL_BAD_ALLOC:

break;

case EGL_BAD_CONFIG:

break;

case EGL_BAD_PARAMETER:

break;

case EGL_BAD_MATCH:

break;

}

}

// 檢查pbuffer 分配的內(nèi)存大小

EGLint width;

EGLint height;

if (!eglQuerySurface(esContext->eglDisplay, pbuffer, EGL_WIDTH, &width)

|| !eglQuerySurface(esContext->eglDisplay, pbuffer, EGL_HEIGHT, &height)) {

// 不能查詢 surface的信息

return GL_FALSE;

}

五、創(chuàng)建渲染上下文

渲染上下文是OpenGLES3.0的內(nèi)部數(shù)據(jù)結(jié)構(gòu)沉衣,包含操作所需要的所有狀態(tài)信息郁副。它包含了對(duì)頂點(diǎn)著色器和片元著色器數(shù)據(jù)的引用。

// 5.創(chuàng)建上下文

esContext->eglContext = eglCreateContext(esContext->eglDisplay, config,

EGL_NO_CONTEXT, contextAttribs);

// 判斷上下文是否創(chuàng)建成功

if (esContext->eglContext == EGL_NO_CONTEXT) {

return GL_FALSE;

}

// 根據(jù)之前的配置構(gòu)建上下文

if (!eglMakeCurrent(esContext->eglDisplay, esContext->eglSurface, esContext->eglSurface, esContext->eglContext)) {

return GL_FALSE;

}

六豌习、指定某個(gè)EGLContext為當(dāng)前上下文

// 指定某個(gè)EGLContext為當(dāng)前上下文

if (!eglMakeCurrent(esContext->eglDisplay, esContext->eglSurface,

esContext->eglSurface, esContext->eglContext)) {

return GL_FALSE;

}

同步渲染

多個(gè)圖形API在單個(gè)窗口中的渲染存谎,此時(shí)需要使用同步渲染,需要應(yīng)用程序允許多個(gè)庫渲染到共享窗口肥隆。

如果不止使用OpenGLES3.0渲染既荚,則不能簡(jiǎn)單地調(diào)用glFinish來抱著個(gè)所有渲染已經(jīng)發(fā)生,你可以調(diào)用:

EGLBoolean eglWaitClient()

延遲客戶端的執(zhí)行栋艳,直到某個(gè)API的所有渲染完成恰聘,成功返回EGL_TRUE,失敗時(shí)返回EGL_FALSE并發(fā)送EGL_BAD_CURRENT_SURFACE錯(cuò)誤

同樣吸占,如果你需要保證原生窗口系統(tǒng)的渲染完成晴叨,則調(diào)用如下函數(shù):

EGLBoolean eglWaitNative(EGLint engine)

engine,指定渲染程序等待渲染完成

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末矾屯,一起剝皮案震驚了整個(gè)濱河市兼蕊,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌件蚕,老刑警劉巖孙技,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異排作,居然都是意外死亡牵啦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門纽绍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蕾久,“玉大人,你說我怎么就攤上這事拌夏∩” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵障簿,是天一觀的道長(zhǎng)盹愚。 經(jīng)常有香客問我,道長(zhǎng)站故,這世上最難降的妖魔是什么皆怕? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮西篓,結(jié)果婚禮上愈腾,老公的妹妹穿的比我還像新娘。我一直安慰自己岂津,他們只是感情好虱黄,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吮成,像睡著了一般橱乱。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上粱甫,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天泳叠,我揣著相機(jī)與錄音,去河邊找鬼茶宵。 笑死危纫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的乌庶。 我是一名探鬼主播叶摄,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼安拟!你這毒婦竟也來了蛤吓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤糠赦,失蹤者是張志新(化名)和其女友劉穎会傲,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拙泽,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淌山,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了顾瞻。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泼疑。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖荷荤,靈堂內(nèi)的尸體忽然破棺而出退渗,到底是詐尸還是另有隱情移稳,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布会油,位于F島的核電站个粱,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏翻翩。R本人自食惡果不足惜都许,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望嫂冻。 院中可真熱鬧胶征,春花似錦、人聲如沸桨仿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蹬敲。三九已至暇昂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伴嗡,已是汗流浹背急波。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘪校,地道東北人澄暮。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像阱扬,于是被迫代替她去往敵國(guó)和親泣懊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容