1. 程式人生 > >[原] OpenGL ES 學習筆記 (一)

[原] OpenGL ES 學習筆記 (一)

信號 ppi sci DC RM 視錐 技術分享 img 比較

1. OpenGL ES 的坐標系在屏幕上的分布

技術分享圖片               OpenGL ES 的坐標系{x, y, z}

通過圖片的三維坐標系可以知道:
- 它是一個三維坐標系 {x, y, z}
- 三維坐標中心在正方體的幾何中心 {0, 0, 0}
- 整個坐標系是 [0, 1] 的點,也就是說 OpenGL 中只支持 0 ~ 1 的點 (這裏所講的 0 和 1 ,最好理解成 0 --> 無限小, 1 --> 無限大 ,它並不是指 0 個單位的長度,或 1 個單位的長度。

2. OpenGL 能直接繪制的是: 點精靈、線、三角形,它們統稱為 圖元(Primitive)

,不能直接繪制四邊形。

2.1 線元

Line Strip , 指首尾相接的線段,第一條線和最後一條線沒有連接在一起;
Line Loops, 指首尾相接的線段,第一條線和最後一條線連接在一起,即閉合的曲線;

技術分享圖片 2.2 三角形

Triangle Strip, 指條帶,相互連接的三角形
Triangle Fan, 指扇面,相互連接的三角形


技術分享圖片
                      Triangle
技術分享圖片       扇面 2.3 點精靈 【主要應用在 紋理 方面】

3. OpenGL ES 2 的渲染管線

技術分享圖片               圖形管線(Graphics Pipeline)

因為這裏是 iOS 端的圖,所以重新繪制了一下:


技術分享圖片                 OpenGL ES 2 渲染流程圖 primitive assembly : 圖元裝配 rasterization: 光柵華 per-fragment operation:分段操作

4. Vertex Arrays / Buffer Objects :

4.1 Vertex Arrays Objects (簡稱:VAOs),頂點數組對象,就是一個數組,包含頂點坐標、顏色值、紋理坐標等數據;通過 CPU內存關聯到 GPU 的內存區被 GPU 所使用;

【官方解釋:Vertex data may be sourced from arrays that are stored in application memory (via a pointer) or faster GPU memory (in a buffer object).(意指:頂點數組保存在程序內存或快速GPU內存中,前者通過數組指針訪問數據,後者直接通過 Buffer Objects 訪問。【就是指 VAOs 或 VBOs 方式訪問】)】

例如:繪制的三角形的數組(三個頂(端)點坐標)如下圖:

技術分享圖片 VFVertex的定義: 技術分享圖片 4.2 Vertex Buffer Objects , (簡稱:VBOs [ Vertex Buffer Objects ]),緩存對象,就是持有頂點數組數據或數據下標的對象【並不是指面向對象裏面的對象哦,其實一塊 GPU 內存塊】。

【官方解釋:Buffer objects hold vertex array data or indices in high-performance server memory. (意指:VBOs 是持有保存在GPU快速內存區的頂點數據或頂點數據下標的緩存對象。)】

5. Vertex Shader (頂點著色器) :

處理頂點相關的數據,包括頂點在屏幕的位置(矩陣變換),頂點處的光照計算,紋理坐標等。

                  頂點著色器的信號圖:

技術分享圖片

5.1 輸入信號:Attributes、Uniforms、Samplers (optional)

a. Attributes : 屬性的意思,指每一個頂點數據;

b. Uniforms :

b.1. 統一的意思 , 是一個只讀全局常量,存儲在程序的常量區;
b.2. 當 Vertex Shader 和 Fragment Shader 定義了同名同類型的 Uniform 常量時,此時的 Uniform 常量就變成了全局常量(指向同一塊內存區的常量);

c. Samplers (可選的) : 是一個特殊的 Uniforms 保存的是 Texteures(紋理) 數據;

5.2 輸出信號: Varying

Varying :
a. 它是 Vertex Shader 與 Fragment Shader 的接口,是為了解決功能性問題(兩個 Shader 的信息交互);

b. 儲存 Vertex Shader 的輸出信息;

c. Vertex Shader 與 Fragment Shader 中必須要有必須要同名同類型的Varying 變量,不然會編譯錯誤(因為它是兩個 Shader 的信息接口啊,不一樣還接什麽口啊。)

5.3 交互信息: Temporary Variables

Temporary Variables :
a. 指臨時變量;
b. 儲存 Shader 處理過程中的中間值用的;
c. 聲明在 Funtions(函數) 或 Variable(變量) 內部;

5.4 輸出的內建變量: gl_Position、gl_FrontFacing、gl_PointSize

a. gl_Position ** ( highp vec4 變量 ) :

就是 Vertex Position,Vertex Shader 的輸出值,而且是必須要賦值的變量;只有在 Vertex Shader 中使用才會有效**;

註意:highp vec4, highp ( high precision ) 高精度的意思,是精度限定符; vec4 ( Floating Point Vector ) 浮點向量 , OpenGL ES 的數據類型。

b. gl_PointSize ( mediump float 變量 ) :

告訴 Vertex Shader 柵格化點的尺寸(pixels,像素化),想要改變繪制點的大小就是要用這個變量 只有在 Vertex Shader 中使用才會有效

 註意:mediump , mediump ( medium precision ) 中等精度的意思,是精度限定符;還有最後一個精度限制符是 lowp ( low precision ),低精度的意思。

c. gl_FrontFacing ( bool 變量 ) :
改變渲染物體的 Front Facing 和 Back Facing , 是用於處理物體光照問題的變量,雙面光照(3D 物體裏外光照)問題的時候才會使用的變量,只能在 Vertex Shader 中進行設置, Fragment Shader 是只讀的

6. Primitive Assembly (圖元裝配) :

第一步,把 Vertex Shader 處理後的頂點數據組織成 OpenGL ES 可以直接渲染的基本圖元:點、線、三角形;

第二步,裁剪 ( Clipping ) ,只保留在渲染區域(視錐體,視覺區域)內的圖元;

第二步,剔除 ( Culling ),可通過編程決定剔除前面、後面、還是全部;

【註意】視錐體,實際上是一個三維錐體包含的空間區域,由攝影機和物體的捕捉關系形成;

技術分享圖片

視錐體

7. Rasterization ( 光柵化 ) :

                光柵化的信號圖:

技術分享圖片

  作用是,將基本圖元(點、線、三角形)轉換成二維的片元(Fragment, 包含二維坐標、顏色值、紋理坐標等等屬性), 像素化基本圖元使其可以在屏幕上進行繪制(顯示)。

8. Texture Memory ( 紋理內存 ) :

  Texture 就是指保存了圖片(位圖)的所有顏色的緩存;Texture Memory 就是圖片的顏色(像素)內存;每一個嵌入式系統對 Texture Memory 的大小都是有限制的;

  1. 完整的 iOS 渲染繪制管線圖中,向上指向 Vertex Shader 的虛線,意指 Texture Coordinate (紋理坐標)信息是通過程序提供給它的;

  2. 完整的 iOS 渲染繪制管線圖中,指向 Fragment Shader 的實線,因為 Fragment Shader 處理的是光柵化後的數據,即像素數據,而 Texture 本身就是像素數據,所以 Texture Memory 可以直接當成 Fragment Shader 的輸入;

9. Fragment Shader ( 片元著色器 )

片元著色器信號圖:

技術分享圖片
  1. 輸入信號: Varying、Uniforms、Samples
    與 Vertex Shader 的輸入是同一個意思,具體請查看 Vertex Shader 處的解釋~~~;

  2. 輸入的內建變量:gl_FragCoord、gl_FrontFacing、gl_PointCoord

    a. gl_FragCoord ( mediump vec4 只讀變量 ) : 是保存窗口相對坐標的 { x, y, z, 1/w } 的變量,z 表示深度 (will be used for the fragment‘s depth), w 表示旋轉;

    b. gl_PointCoord ( mediump int 只讀變量 ) : 是包含了當前片元原始點位置的二維坐標;點的範圍是 [ 0, 1 ] ;

    c. gl_FrontFacing : 請查看 Vertex Shader 處的解釋;

  1. 輸出信號 (內建變量) : gl_FragColor、gl_FragData (圖上沒寫)

    a. gl_FragColor ( mediump vec4 ) : 片元的顏色值;

    b. gl_FragData ( mediump vec4 ) : 是一個數組,片元顏色集;

  【註意】註:兩個輸出信號只能同時存在一個,就是 寫了 gl_FragColor 就不要寫 gl_FragData , 反之亦然;

10. Per-Fragment Operations :

              信號圖:

技術分享圖片
  1. Pixel ownership test ( 像素歸屬測試 ) :
    判斷像素在 Framebuffer 中的位置是不是為當前 OpenGL ES Context 所有,即測試某個像素是否屬於當前的 Context 或是否被展示(是否被用戶可見);

  2. Scissor Test ( 裁剪測試 ) :
    判斷像素是否在由 glScissor* 定義的裁剪區域內,不在該剪裁區域內的像素就會被丟棄掉;

  3. Stencil Test ( 模版測試 ):
    將模版緩存中的值與一個參考值進行比較,從而進行相應的處理;

  4. Depth Test ( 深度測試 ) :
    比較下一個片段與幀緩沖區中的片段的深度,從而決定哪一個像素在前面,哪一個像素被遮擋;

  5. Blending ( 混合 ) :
    將片段的顏色和幀緩存中已有的顏色值進行混合,並將混合所得的新值寫入幀緩存 (FrameBuffer) ;

  6. Dithering ( 抖動 ) :
    使用有限的色彩讓你看到比實際圖象更為豐富的色彩顯示方式,以緩解表示顏色的值的精度不夠大而導致顏色劇變的問題。


11. Render Buffer & Frame Buffer:

                      關系圖:

技術分享圖片
  1. Render Buffer ( 渲染緩存 ) :

    a. 簡稱 RBO , Render Buffer Object;
    b. 是由程序(Application)分配的 2D 圖片緩存;
    c. Render Buffer 可以分配和存儲顏色(color)、深度(depth)、模版(stectil)值,也可以把這三種值裝載到 Frame Buffer 裏面;

  1. Frame Buffer ( 幀緩存 ) :

    a. 簡稱 FBO , Frame Buffer Object;
    b. 是顏色、深度、模板緩存裝載在 FBO 上所有裝載點的合集;
    c. 描述顏色、深度、模板的大小和類型的屬性狀態;
    d. 描述 Texture 名稱的屬性狀態;
    e. 描述裝載在 FBO 上的 Render Buffer Objects ( 渲染緩存對象 ) 的屬性狀態;

  【註意】

    FBO API 支持的操作如下:

    1. 只能通過 OpenGL ES 命令 ( API ) 創建 FBO 對象;

    2. 使用一個 EGL Context 去創建和使用多個 FBO , 即不要為每一個 FBO 對象創建一個正在渲染的上下文(rendering context);

    3. 創建 off-screen 的顏色、深度、模板渲染緩存和紋理需要裝載在 FBO 上;

    4. 通過多個 FBO 來共享顏色、深度、模板緩存;

    5. 正確地裝載紋理的顏色或深度到 FBO 中,避免復制操作;


12. EAGL API : 技術分享圖片

官方的是 EGL API 與平臺無關,因為它本身是可以進行平臺定制的,所以 iOS 下就被 Apple 定制成了 EAGL API 。

EAGL.h : 裏面的核心類是 EAGLContext , 上下文環境;

EAGLDrawable.h : 用於渲染繪制輸出的 EAGLContext 分類;

CAEAGLLayer : iOS 端的渲染窗口寄宿層;

  [註]

  1. EGL API 設計出來的目的就是為了在 OpenGL ES 2 能在窗口系統 (屏幕 ,iOS 是 CAEAGLLayer 類為寄宿層的 View)進行渲染繪制;
  2. 可以進行 EGL 渲染的前提是:

    a. 可以進行顯示的設備( iOS 下當然是手機或模擬器 )

    b. 創建渲染面(rendering surface), 設備的屏幕 ( on-screen ) 或 像素緩存 ( pixel Buffer ) ( off-screen )

    [註] pixel Buffer , 這種 buffer 是不能直接顯示的,只能成為渲染面或通過其它 API 分享出去,如: pbuffers 經常被用於 Texture 的 maps , 因為 Texture 本身也是像素嘛;

  3.創建渲染上下文 ( rendering context ), 即 OpenGL ES 2 Rendering Context ;

[原] OpenGL ES 學習筆記 (一)