歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

OpenGL 4.4 和 Android

手機硬件的更新是如此迅速以至於我們開始進入一個手機與高端PC功能無異的時代。它們的區別將只是芯片的功耗不同而已。

我不想讓自己聽起來像是在推廣我們自己的芯片,但我相信Tegra K1是未來即將發生的事物的前瞻。不僅僅發生在我們身上,我希望其他行業也能加入進來,從而使開發者可以為從PC到手機安全地假設一個相對統一的功能集。K1只是首個示例,因為它的GPU核心是Kepler 。而且它不是什麼營銷手段,它實際上是與運轉像GTX780這種神奇事物相同的微架構。幾年的血汗與淚水使其成為了可能。並且限於尺寸,功率和熱限制,它只有192個核心(而不是2304個),但它仍具有較強的性能競爭力。更重要的是在功能上它處於一個完全不同的陣營中,因為它支持完整的桌面級OpenGL4.4,包括幾何著色器,鑲嵌,計算等,還有像bindless這樣的支持其他事物的擴展。

OpenGL 渲染篇 http://www.linuxidc.com/Linux/2011-10/45756.htm

Ubuntu 13.04 安裝 OpenGL http://www.linuxidc.com/Linux/2013-05/84815.htm

OpenGL三維球體數據生成與繪制【附源碼】 http://www.linuxidc.com/Linux/2013-04/83235.htm

Ubuntu下OpenGL編程基礎解析 http://www.linuxidc.com/Linux/2013-03/81675.htm

如何在Ubuntu使用eclipse for c++配置OpenGL http://www.linuxidc.com/Linux/2012-11/74191.htm

《OpenGL超級寶典》學習筆記 http://www.linuxidc.com/Linux/2013-10/91414.htm

但是Android只支持OpenGL ES,對嗎?實際上不是這樣的。雖然現在在Android平台上,首選的官方支持的圖形API是OpenGL ES,你仍然可以使用EGL在平台上創建一個"大"OpenGL 上下文,前提是你的設備支持它。這使得在不同的操作系統上傳輸數據很實用,Windows/Linux/Mac/streamOS 都有OpenGL的後台程序,可以快速啟動並模擬裁剪平面(clip planes),alpha測試,或者spec中的少數差異。它同樣可以作為一個不錯的引用渲染後端程序,在ES渲染路徑啟動和運行之前驗證你的端口。

不要擔心,你可以在你的app中同時使用GLES和BigGL。實際上,這很簡單。最重要的事情在EGL中,它是Android為創建OpenGL上下文而公開的API。Java或C/C++同樣可以這樣做,但是要注意需要EGL_SPEC.1.4以上版本。

首先,在創建上下文(或者調用任何一個EGL函數)之前,要知道哪個版本的GL最支持當前設備。可以通過簡單地調用eglBindAPI(EGL_OPENGL_API)來完成。該API會將EGL切換到桌面OpenGL模式,如果當前設備不支持,則返回EGL_TRUE或者留下未改變的狀態並返回EGL_FALSE。鑒於該函數可以切換全局狀態,所以最安全的做法是讓EGL首先調用它,之後不再調用。

創建完上下文之後,如果eglBindAPI()函數沒有切換BigGL模式,你就要和你之前那樣創建你的ES上下文。如果切換成功,你可選擇性地創建BigGL上下文。幸運的是,EGL讓它簡單化。因為我們已經調用了eglBindAPI(EGL_OPENGL_API),EGL已經設置為BigGL模式,所以我們只需要在配置文件和上下文中調整一些屬性即可。

首先,在傳遞給eglChooseConfig()的配置屬性中,我們需要確保 EGL_RENDERABLE_TYPE 設置為 EGL_OPENGL_BIT ,而不是EGL_OPENGL_ES2_BIT.

其次, 傳遞給函數 eglCreateContext() 的屬性也需要稍微調整。對於 ES上下文,通常把 EGL_CONTEXT_CLIENT_VERSION 設為 1, 2 或3, 這取決於你想搭建哪個版本的OpenGL ES.對於BigGL上下文,我們不使用這個屬性,所以不要設置。事實上,你可以直接把BigGL的屬性列表置空。

粗略地講,這比較像下面的樣本 (為簡潔起見,忽視錯誤檢查):

if(eglBindAPI(EGL_OPENGL_API)) { // Create a BigGL context... EGLDisplay display = eglGetDisplay(...); eglInitialize(display, ...); const EGLint configAttrs[] = { EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, // backbuffer attributes here... EGL_NONE }; EGLConfig config; EGLint numConfigs = 0; eglChooseConfig(display, configAttrs, &config, 1, &numConfigs); EGLint ctxAttrs[] = { EGL_NONE }; eglCreateContext(display, config, EGL_NO_CONTEXT, ctxAttrs); } else { // TODO: Fallback to old ES context creation... }

最後一點問題,也是我對於使用OpenGL或者OpenGL ES的開發人員的一些建議,不論他們基於怎樣的平台進行開發。尤其重要的一點是像上面提到的那樣在API之間進行切換。並且,不要隱式地鏈接到GL符號!就算是再多的功能,你都應當使用eglGetProcAddress(),並且當心不要在上下文中共享函數指針。如果你做了一下比較瘋狂的事情,比如在同一個應用中創建了一個BigGL上下文和一個ES上下文,或者創建了像glDrawElement()這樣的函數,在兩者的API中都存在,但是可能指向了完全不同的實現方法。這就意味著你應當僅鏈接到libEGL,所以需要通過qglGetProcAddress()函數查詢所有的符號。

編輯:應當指出的是,從技術的角度講,通過eglGetProcAddress()可獲得的“EGL_KHR_get_all_proc_addresses”應當是目前的核心功能,但是我堅信,既然目前它在Android通用EGL接口上進行了實現,也就意味著它可以單獨驅動,這可能在舊版本的Android上無法正常工作。但是如果你正在考慮支持BigGL,你可能不希望舊設備成為你道路上的絆腳石。

特別強調:我強烈建議如果可能的話,任何正在開發的應用程序應該也有GLES渲染路徑。BigGL對於開發是實用的,對於一些邊緣特性,甚至會更實用,但是有GLES後端同樣會幫助Android避免分段存儲,並且幫助你的應用更多的曝光在盡可能多的用戶面前。

更多Android相關信息見Android 專題頁面 http://www.linuxidc.com/topicnews.aspx?tid=11

Copyright © Linux教程網 All Rights Reserved