Android 平臺(tái)上,在調(diào)用OpenGL ES API 之前,需要在初始化EGL 。之后 OpenGL ES 調(diào)用API 渲染的物體,才能正常地顯示在Android 的窗口上。換句話說(shuō),EGL 為OpenGL ES 的調(diào)用提供了渲染的環(huán)境。
源碼來(lái)自:https://github.com/googlesamples/android-ndk/tree/master/native-activity
EGL 初始化
-
獲取前臺(tái)窗口(Display),并初始化Display
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY) //后兩個(gè)參數(shù)傳0,表明我們不需要返回版本信息 eglInitialize(display,0,0) -
根據(jù)指定屬性選擇最優(yōu)配置
const EGLint attribs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_BLUE_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_RED_SIZE, 8, EGL_NONE }; //第一遍是為了獲取支持屬性的配置個(gè)數(shù) EGLint numConfigs; eglChooseConfig(display,attribs,NULL,0,&numConfigs); //第二遍 eglChooseConfig 是為了獲取所有支持屬性的配置列表 std::unique_ptr<EGLConfig[]> supportedConfigs(new EGLConfig[numConfigs]); assert(supportedConfigs); eglChooseConfig(display, attribs, supportedConfigs.get(), numConfigs, &numConfigs); assert(numConfigs); auto i = 0; for (; i < numConfigs; i++) { auto &cfg = supportedConfigs[i]; EGLint r, g, b, d; if (eglGetConfigAttrib(display, cfg, EGL_RED_SIZE, &r) && eglGetConfigAttrib(display, cfg, EGL_GREEN_SIZE, &g) && eglGetConfigAttrib(display, cfg, EGL_BLUE_SIZE, &b) && eglGetConfigAttrib(display, cfg, EGL_DEPTH_SIZE, &d) && r == 8 && g == 8 && b == 8 && d == 0) { config = supportedConfigs[i]; break; } } if (i == numConfigs) { config = supportedConfigs[0]; } -
使用選譯的配置創(chuàng)建Surface (相當(dāng)于后臺(tái)窗口)
EGLSurface surface = eglCreateWindowSurface(display, config, engine->app->window, NULL); -
使用配置創(chuàng)建 EGL上下文
EGLContext context = eglCreateContext(display,config,NULL,NULL) -
綁定 EGLContext 與 surface ( Draw Surface , Read Surface , 一般都是同一個(gè)Surface )
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { LOGW("Unable to eglMakeCurrent"); return -1; }
EGL雙緩沖技術(shù)
OpenGL ES API 渲染的事物,默認(rèn)是渲染在初始化EGL時(shí)指定 EGLSurface 上,這個(gè)EGLSurface 可以理解渲染時(shí)的后臺(tái)窗口,維護(hù)了一個(gè)渲染緩沖區(qū)。
而初始化EGL 時(shí)獲取的 EGLDisplay,可以理解為渲染時(shí)的前臺(tái)窗口,內(nèi)部同樣也維護(hù)了一個(gè)渲染緩沖區(qū)。
在所有 OpenGL ES API 調(diào)用之后,EGLSurface 與 EGLDisplay 交換緩沖區(qū) ,之后顯示一幀圖像到Android前臺(tái)窗口上
eglSwapBuffers(engine->display, engine->surface)