1.為什么要不停地清空屏幕?
? 最新的GPU以不同的方式工作,使用特殊的渲染技術,如果屏幕是干凈的,能工作得更快.
? 通過讓GPU清空屏幕,可以節(jié)省拷貝浪費的時間.
2.GLSurfaceView和TextureView對比.
? GLSurfaceView在幕后,實際上創(chuàng)建了一個窗口(Window),并在視圖層次(View Hierachy)上穿了個"洞",讓底層的OpenGL surface 顯示出來.
? 但是GLSurfaceView與常規(guī)視圖view不同,它沒有動畫或者變形特效,因為它是窗口(window)的一部分.
? TextureView(紋理視圖),從Android4.0開始,它可以渲染OpenGL而不用創(chuàng)建單獨的窗口或打洞了,這就意味著,這個視圖像一個常規(guī)窗口一樣,可以被操作,且有動畫和變形特效.
? 但是,TextureView類沒有內(nèi)置OpenGL初始化操作,要想使用TextrueView,一種方法是執(zhí)行自定義的OpenGL初始化,并在TextureView上運行;
另外一種方法是把GLSurfaceView的源代碼拿出來,把他適配到TextureView上.
3.GLSurfaceView在后臺線程中渲染!
? GLSurfaceView會在一個單獨的線程中調(diào)用渲染器的方法.默認情況下,GLSurfaceView會以顯示設備的刷新頻率不斷地渲染,當然,它也可以配置為按請求渲染,只需要用GLSurfaceView.RENDERMODE_WHEN_DIRTY作為參數(shù)調(diào)用GLSurfaceView.setRenderMode()即可.
? 后臺線程和主UI線程之間的通信方法如下:在主線程中的GLSurfaceView實例可以調(diào)用queueEvent()方法傳遞一個Runnable給后臺渲染線程,渲染線程可以調(diào)用Activity的runOnUIThread()來傳遞事件(event)給主線程.
4.定義頂點時 三角形的卷曲順序
? 當我們定義三角形的時候,我們總是以逆時針的順序排列頂點;這稱為卷曲順序(winding order).
? 因為在任何地方都使用這種一致的卷曲順序,可以優(yōu)化性能:
? ? 使用卷曲順序可以指出一個三角形屬于任何給定物體的前面或者后面,OpenGL可以忽略那些無論如何都無法被看到的后面的三角形.
? ** 無論何時,如果我們想表示一個OpenGL中的物體,都要考慮如何用點,直線及三角形把它組合出來 **
5.本地環(huán)境工作時,它并不期望內(nèi)存塊像GC一樣,會被移來移去或者被自動釋放.
? OpenGL作為本地系統(tǒng)庫直接運行在硬件上;沒有虛擬機,也沒有垃圾回收或內(nèi)存壓縮.
6.Android代碼運行在虛擬機內(nèi)部,與OpenGL通信有兩種技術.
? a.使用JNI,調(diào)用android.opengl.GLES20包里的方法時就是使用JNI調(diào)用本地系統(tǒng)庫的.
? b.改變內(nèi)存分配的方式,java有一個特殊的類的集合,它們可以分配本地內(nèi)存塊,并且把java的數(shù)據(jù)復制到本地內(nèi)存. 本地內(nèi)存可以被本地環(huán)境存取,而不受垃圾回收器的管控.
7.字節(jié)序(Endianness)
? 字節(jié)序是描述一個硬件架構(gòu)是如何組織位bit和字節(jié)byte的方式,它們在底層組成一個數(shù)字.
? 現(xiàn)實中,最常見的就是多字節(jié)數(shù),既可以把它們按大頭序(bit endian order) 排列,即把最重要的字節(jié)放在前面; 或者按小頭序(little endian order) 排列, 即把最不重要的字節(jié)放前面.
? 大頭序? 二進制? ? ? ? ? ? ? 十六進制? 十進制
? ? ? ? ? 00100111 00010000? 27 10? ? 10000
? 小頭序? 二進制? ? ? ? ? ? ? 十六進制? 十進制
? ? ? ? ? 00010000 00100111? 10 27? ? 10000
8.為什么要使用著色器?
? 在著色器出現(xiàn)之前,OpenGL只能使用一個固定的方法集合控制很少而有限的事情,比如場景里有多少光線或者加多少霧;這些API易使用難擴展.
? 在GLES2.0,加入了可編程API,為了保持簡潔,固定的API完全刪除了,因此,必須使用著色器.
? 現(xiàn)在用著色器控制每個頂點贏該如何畫到屏幕上,我們也控制所有點,直線和三角形上的每個片段應該如何繪制;
? 現(xiàn)在可以按每個像素實現(xiàn)光照和其他優(yōu)美的效果,如卡通著色.
? 只要可以用著色器語言表達出來, 就可以加入任何理想的自定義效果.
? ** 作為OpenGL和著色器的參考,knronos.org提供了一個很好的快色參考卡片
? ? https://www.khronos.org/opengles/sdk/docs
? ? /reference_cards/OpenGL-ES-2_0-Reference-card.pdf
? ? https://www.khronos.org/registry/OpenGL/specs/es
? ? /2.0/GLSL_ES_Specification_1.00.pdf
? **
9.光柵化(Rasterization)技術
? OpenGL通過"光柵化"的過程把每個點,直線及三角形分解成大量的小片段,它們可以映射到移動設備顯示屏的像素上,從而生成一副圖像.
? 這些片段類似于顯示屏上的像素,每一個都包含單一的純色.RGBA.
? OpenGL將多個頂點生成一條直線-->>創(chuàng)建片段-->>顯示系統(tǒng)會把這些片段直接映射到屏幕上的像素,結(jié)果一個片段就對應一個像素;
? 然而并不總是這樣的: 一個超高分辨率的設備可能需要使用較大的片段吻育,以減少GPU的工作符合.
10.兩種類型的著色器.
? a.頂點著色器(vertex shader): 生成每個頂點的最終位置,針對每個頂點,它都會執(zhí)行一次;一旦最終位置確定了,OpenGL就可以把這些可見頂點的集合組裝成點,直線以及三角形.
? b.片段著色器(fragment shader): 為組成點,直線或者三角形的每個片段生成最終的顏色,針對每個片段,它都會執(zhí)行一次;一個片段是一個小的,單一顏色的長方形區(qū)域,類似于計算機屏幕上的一個像素.
** 精度限定符 ** start
? 在這個片段著色器中,文件頂部的第一行代碼定義了所有符點數(shù)據(jù)類型的默認精度.類似java浮點數(shù)還是雙精度浮點數(shù)一樣.
? 可以選擇lowp,mediump,highp. 然而只有某些硬件實現(xiàn)支持在片段著色器中使用highp.
? 為什么頂點著色器沒有定義精度呢? 頂點著色器同樣可以改變其默認的精度,但是,對于一個頂點的位置而言,精確度是最重要的,OpenGL設計者決定把頂點著色器的精度默認設置成最高級--highp.
? 高精度數(shù)據(jù)類型更加準確,但是這是以降低性能為代價的;對于片段著色器,出于最大兼容性的考慮,選擇了mediump,這也是基于速度和質(zhì)量的權(quán)衡.
** 精度限定符 ** end
11.OpenGL顏色模型
? OpenGL使用累加RGB顏色模型.
? 它只用了三種基本顏色:紅色,綠色和藍色.
? 許多顏色都是通過把這三種基本顏色按不同比例混合在一起而創(chuàng)造的.
? 這個模型的工作原理與學校里學過的減色繪畫模型不同: 在減色繪畫模型里,加入藍色和黃色制作出綠色,而加入很多顏色會產(chǎn)生黑棕色或者黑色. 這是因為顏料不發(fā)光,而是吸收光;畫上使用的顏色越多,光被吸收得越多,這幅畫就會表現(xiàn)得越暗.
? 累加RGB模型遵循光本身的屬性,當兩柱不同顏色的光線混合在一起時,不會看見更暗的顏色,而是更高的顏色.
? **https://en.wikipedia.org/wiki/RGB_color_model**
12.為什么不直接使用庫翻伺?
? 對Android來說,已經(jīng)有很多合適的三維庫了,從簡單的開元封裝---libgdx()逾冬,再到比較高級的商業(yè)化框架旗唁,比如Unity3D()。
? 這些庫能幫助你提高生產(chǎn)率浦旱,但只有當你對OpenGL、三維渲染九杂,以及底層是如何把這些東西拼在一起的有了基本的理解后才能體會到颁湖;否則這些庫沒有任何意義宣蠕,也許感覺像使用黑箱魔法一樣。
? 研究這些庫有助于學習如何開發(fā)自己的組件甥捺。 Java3D和jMonkeyEngine是Java桌面版上廣泛使用的框架抢蚀,是很好的學習起點。
? ##
? http://code.google.com/p/libgdx
? http://unity3d.com
? http://www.oracle.com/technetwork/java/javase/tech/index-jsp-138252.html
? http://jmonkeyengine.com
? ##
13.