轉(zhuǎn)載 https://blog.csdn.net/weixin_35127779/article/details/86540173
一、相關(guān)概念:
1.OpenGL是一套繪圖函數(shù)的標(biāo)準(zhǔn),OpenGL ES是OpenGL中針對(duì)嵌入式系統(tǒng)的一套函數(shù)子集。
2.EGL:通俗上講,OpenGL是一個(gè)操作[GPU]的API,它通過(guò)驅(qū)動(dòng)向GPU發(fā)送相關(guān)指令,控制圖形渲染管線狀態(tài)機(jī)的運(yùn)行狀態(tài)。但OpenGL需要本地視窗系統(tǒng)進(jìn)行交互,這就需要一個(gè)中間控制層,最好與平臺(tái)無(wú)關(guān)。EGL——因此被獨(dú)立的設(shè)計(jì)出來(lái),它作為OpenGL ES和本地窗口的橋梁。 EGL 是 OpenGL ES(嵌入式)和本地 平臺(tái)視窗系統(tǒng)之間的接口。
3.GLUT:是基本的窗口界面,是獨(dú)立于gl和glu的,如果不喜歡用glut可以用MFC和Win32窗口等代替,但是glut是跨平臺(tái)的,這就保證了我們編出的程序是跨平臺(tái)的,如果用MFC或者Win32只能在windows操作系統(tǒng)上使用。選擇OpenGL的一個(gè)很大原因就是因?yàn)樗目缙脚_(tái)性,所以我們可以盡量的使用glut庫(kù)。
3.glut
二、EGL使用流程
1.標(biāo)準(zhǔn) EGL 數(shù)據(jù)類型如下所示:
EGLBoolean ——EGL_TRUE =1, EGL_FALSE=0
EGLint ——int 數(shù)據(jù)類型
EGLDisplay ——系統(tǒng)顯示 ID 或句柄,可以理解為一個(gè)前端的顯示窗口
EGLConfig ——Surface的EGL配置,可以理解為繪制目標(biāo)framebuffer的配置屬性
EGLSurface ——系統(tǒng)窗口或 frame buffer 句柄 ,可以理解為一個(gè)后端的渲染目標(biāo)窗口。
EGLContext ——OpenGL ES 圖形上下文,它代表了OpenGL[狀態(tài)機(jī)] 如果沒(méi)有它,OpenGL指令就沒(méi)有執(zhí)行的環(huán)境。
下面幾個(gè)類型比較復(fù)雜,通過(guò)例子可以更深入的理解。這里要說(shuō)明的是這幾個(gè)類型在不同平臺(tái)其實(shí)現(xiàn)是不同的,EGL只提供抽象標(biāo)準(zhǔn)。
NativeDisplayType——本地系統(tǒng)顯示類型,標(biāo)識(shí)你所開(kāi)發(fā)設(shè)備的物理屏幕
NativeWindowType ——本地系統(tǒng)窗口緩存類型,標(biāo)識(shí)系統(tǒng)窗口
NativePixmapType ——本地系統(tǒng) frame buffer,可以作為 Framebuffer 的系統(tǒng)圖像(內(nèi)存)數(shù)據(jù)類型,該類型只用于離屏渲染.
2 OpenGL ES的初始化過(guò)程(EGL初始化)如下圖所示意:
Display → Config → Surface
↑
Context
↑
Application → OpenGL Command
2.1. 獲取Display。
獲得Display要調(diào)用 eglGetDisplay,參數(shù)一般為 EGL_DEFAULT_DISPLAY 。
EGLboolean eglGetDisplay(NativeDisplay dpy)
2.2. 初始化egl。
調(diào)用 eglInitialize,該函數(shù)會(huì)進(jìn)行一些內(nèi)部初始化工作,并傳回EGL版本號(hào)(major.minor)。
EGLboolean eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
2.3. 選擇Config。
Config實(shí)際指的是FrameBuffer的參數(shù),
一般用 eglChooseConfig 其中attr_list是以EGL_NONE結(jié)束的參數(shù)數(shù)組,通常以id,value依次存放,對(duì)于個(gè)別標(biāo)識(shí)性的屬性可以只有 id,沒(méi)有value。
EGLboolean eglChooseConfig(EGLDisplay dpy, const EGLint * attr_list, EGLConfig * config, EGLint config_size, EGLint *num_config)
另一個(gè)辦法是用 eglGetConfigs 來(lái)獲得所有config。
EGLboolean eglGetConfigs(EGLDisplay dpy, EGLConfig * config, EGLint config_size, EGLint *num_config)
這兩個(gè)函數(shù)都會(huì)返回不多于config_size個(gè)Config,結(jié)果保存在config[]中,系統(tǒng)的總Config個(gè)數(shù)保存 在num_config中。
可以利用eglGetConfig()中間兩個(gè)參數(shù)為0來(lái)查詢系統(tǒng)支持的Config總個(gè)數(shù)。
Config有眾多的Attribute,這些Attribute決定FrameBuffer的格式和能力,通過(guò) eglGetConfigAttrib () 來(lái)讀取,但不能修改。
2.4 構(gòu)造Surface。
Surface實(shí)際上就是一個(gè)FrameBuffer,也就是渲染目的地,通過(guò) eglCreateWindowSurface 來(lái)創(chuàng)建一個(gè)可實(shí)際顯示的Surface。
EGLSurface eglCreateWindowSurface(EGLDisplay dpy, EGLConfig confg, NativeWindow win, EGLint *cfg_attr)
系統(tǒng)通常還支持另外兩種Surface:PixmapSurface和PBufferSurface,這兩種都不是可顯示的Surface,PixmapSurface是保存在系統(tǒng)內(nèi)存中的位圖,PBuffer則是保存在顯存中的幀。
對(duì)于這兩種surfaceAndroid系統(tǒng)中,支持PBufferSurface。
Surface也有一些attribute,基本上都可以故名思意,
EGL_HEIGHT EGL_WIDTH EGL_LARGEST_PBUFFER EGL_TEXTURE_FORMAT EGL_TEXTURE_TARGET EGL_MIPMAP_TEXTURE EGL_MIPMAP_LEVEL,
通過(guò)eglSurfaceAttrib()設(shè)置、eglQuerySurface()讀取。
2.5 創(chuàng)建Context。
OpenGL ES的pipeline從程序的角度看就是一個(gè)狀態(tài)機(jī),有當(dāng)前的顏色、紋理坐標(biāo)、變換矩陣、絢染模式等一大堆狀態(tài),這些狀態(tài)作用于OpenGL 程序提交的頂點(diǎn)坐標(biāo)等圖元從而形成幀緩沖內(nèi)的像素。在OpenGL的編程接口中,Context就代表這個(gè)狀態(tài)機(jī),OpenGL API程序的主要工作就是向Context提供圖元、設(shè)置狀態(tài),偶爾也從Context里獲取一些信息。
可以用
EGLContext eglCreateContext(EGLDisplay dpy, EGLSurface write, EGLSurface read, EGLContext * share_list)
來(lái)創(chuàng)建一個(gè)Context。
2.6EGL變量之間的綁定
boolean eglMakeCurrent(EGLDisplay display, EGLSurface draw, EGLSurface read, EGLContext context)
該接口將申請(qǐng)到的display,draw(surface)和 context進(jìn)行了綁定。也就是說(shuō),在context下的OpenGLAPI指令將draw(surface)作為其渲染最終目的地。而display作為draw(surface)的前端顯示。調(diào)用后,當(dāng)前線程使用的EGLContex為context。
2.7. 繪制。
應(yīng)用程序通過(guò)OpenGL API進(jìn)行繪制,一幀完成之后,調(diào)用 eglSwapBuffers 來(lái)顯示。
eglSwapBuffers(EGLDisplay dpy, EGLContext ctx)