1. 程式人生 > IOS開發 >OpenGL學習(八)-- OpenGL ES 初探(上)

OpenGL學習(八)-- OpenGL ES 初探(上)

我的 OpenGL 專題學習目錄,希望和大家一起學習交流進步!


一、簡介

在之前,我寫了幾篇學習 OpenGL 的文章,大家有興趣的可以去看一下,在學習了 OpenGL 的基礎上,現在再來學習一下它的簡化版本—— OpenGL ES

OpenGL ES(OpenGL for Embedded Systems)是以手持和嵌⼊式裝置為⽬標的⾼級 3D 圖形應⽤程式程式設計介面(API)。 OpenGL ES 是目前智慧手機中佔據統治地位的圖形 API。支援的平臺包括:iOS,Andriod,BlackBerry,bada,Linux

Windows,它還是基於瀏覽器的 3D 圖形 Web 標準WebGL 的基礎。

OpenGL ESOpenGL 的簡化版本,它消除了冗餘功能,提供了一個既易於學習又更易於在移動圖形硬體中實現的庫。OpenGL ES允許應⽤程式利⽤底層圖形處理器的強大功能。iOS 裝置上的 GPU 可以執行復雜的 2D3D 繪圖,以及最終影象中每個畫素的複雜著色計算。

OpenGl渲染流程.png

簡單的來說,OpenGL ESOpenGL 學習起來大致一樣,有很多重複的知識點。整個渲染管線流程如上圖,還是以前那一套,具體流程可以看我之前寫過的 《OpenGL基礎渲染》。所以這篇文章就不再贅述渲染流程,而是著重介紹 OpenGL ES

中幾個重要的步驟。 可程式設計管線中,我們只能操作 頂點著色器片元著色器

二、關鍵步驟介紹

1、頂點著色器

1)頂點著色器的輸入輸出:

頂點著色器 實現了頂點操作的通用可程式設計方法。

頂點著色器輸入 包括:

  • 著色器程式 —— 描述頂點上執⾏操作的頂點著色器程式原始碼(GLSL程式碼)或者可執行⽂檔案。
  • 頂點著色器輸入(或者屬性 Attributes—— 用頂點陣列提供的每個頂點的資料。
  • 統一變數(uniform—— 頂點(或者片段)著色器使用的不變資料(例如旋轉矩陣)。
  • 取樣器 —— 代表頂點著色器使用紋理的特殊統一變數型別。

圖形表述如下圖所示:

OpenGL ES頂點著色器.png

2)頂點著色器的業務:

  • 1、通過矩陣變換位置
  • 2、計算光照公式生成逐頂點顏色
  • 3、生成或變換紋理座標

此外,因為頂點著色器由應用程式規定,所以它可以用於執行自定義計算,實施新的變換、照明或者較傳統的固定功能管線所不允許的基於頂點的效果。

3)GLSL 程式碼的簡單認識:

格式:通道修飾符 型別 變數名

attribute vec4 position;
attribute vec2 textCoordinate;
uniform mat4 rotateMatrix;
複製程式碼
  • attributeuniform 對應 通道修飾符 , 分別是 attribute 屬性通道uniform 通道。
  • vec4vec2mat4 對應 型別vec4 代表 4 維向量, vec2 代表 2 維向量, mat4 代表 44 列的矩陣型別。
  • positiontextCoordinate 對應 變數名,可以隨便起。
varying lowp vec2 varyTextCoord;
複製程式碼

varying 代表的也是一種通道, lowp 是一個精度,低精度、高精度等,可以不寫。

  • 這裡 position 宣告的是 頂點座標textCoordinate 宣告的是 紋理座標rotateMatrix 宣告的是個 旋轉矩陣

4)頂點著色器的程式碼案例:

attribute vec4 position;
attribute vec2 textCoordinate;
uniform mat4 rotateMatrix;
varying lowp vec2 varyTextCoord;
void main()
{
// 把textCoordinate交給varyTextCoord,就可以把紋理座標傳遞到片元著色器裡面去。
	varyTextCoord = textCoordinate;

	vec4 vPos = position;
	vPos = vPos * rotateMatrix;// 讓每一個頂點都和旋轉矩陣相乘
	
	gl_Position = vPos;// gl_Position是一個內建變數,是vec4型別的,必須給它賦值。
}
複製程式碼

GPU 來執行上述程式碼,有幾個頂點就會執行其次,GPU 是並行的,所以會並行把所有頂點都執行了。

2、圖元裝配

頂點著色器之後,OpenGL ES 3.0 圖形管線的下一階段是 圖元裝配

圖元(Primitive): 是三角形、直線或者點精靈等幾何物件。

圖元裝配: 將頂點資料計算組合成一個個圖元,在這個階段會執行裁剪、透視分割和 Viewport 變換操作。 在這之後將進⼊ 光柵化 階段。

3、光柵化

在此階段繪製對應的圖元(點精靈、直線或者三角形)。光柵化是將圖元轉化為一組二維片段的過程,然後這些片段由片元著色器處理。這些二維片段代表著可在螢幕上繪製的畫素。

光柵化階段.png

4、片元(片段)著色器

1)片元著色器的輸入輸出:

片元/⽚段著色器輸入 包括:

  • 著色器程式 —— 描述⽚段上執⾏操作的片元著⾊器程式原始碼/可執行⽂件。
  • 輸入變數—— 光柵化單元用插值為每個片段生成的頂點著⾊器輸出。
  • 統一變數(uniform—— 頂點(或者片段)著色器使用的不變資料。
  • 取樣器 —— 代表⽚元著色器使⽤紋理的特殊統一變數型別。

圖形表述如下圖所示:

ES 片元著色器.png

2)片元著色器的業務:

  • 1、計算顏色
  • 2、獲取紋理值
  • 3、往畫素點中填充顏色值【紋理值/顏色值】

總結: 它可以用於圖片/視訊/圖形中每個畫素的顏色填充(比如給視訊新增濾鏡,實際上就是將視訊中每個圖片的畫素點顏色填充進行修改)。

3)片元著色器的程式碼案例:

varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
void main()
{
	// texture2D(紋理取樣器,紋理座標); 為了取得紋素(紋理對應座標上的顏色值),比如取到了一個rgba四維變數
	gl_FragColor = texture2D(colorMap,varyTextCoord);
}
複製程式碼

頂點著色器 裡的 varying lowp vec2 varyTextCoord;片元著色器 裡的 varying lowp vec2 varyTextCoord; 必須定義的一模一樣才行,包括通道、精度、型別和變數名都要一致,這樣才能從頂點著色器傳進來。 uniform sampler2D colorMap 是由 uniform 通道傳進來的紋理取樣器,通過它可以拿到對應的紋理。

5、逐片段操作

片元著色器之後,下一階段就是 逐片段操作

逐片段操作.png

  • 畫素歸屬測試: 這個測試確定幀快取區中位置 (Xw,Yw) 的畫素目前是不是歸 OpenGL ES 所有。例如,如果⼀個顯示 OpenGL ES 幀快取區視窗的視窗被另外一個視窗所遮蔽,則窗⼝系統可以確定被遮蔽的畫素不屬於 OpenGL ES 上下文。從⽽完全不顯示這些畫素。雖然畫素歸屬測試是 OpenGL ES 的⼀部分,但它不由開發人員控制,⽽是在 OpenGL ES 內部進行。
  • 裁剪測試: 裁剪測試確定 (Xw,Yw) 是否位於作為 OpenGL ES 狀態的一部分的裁剪矩形範圍內。如果該⽚段位於裁剪區域之外,則被拋棄。
  • 深度測試: 輸⼊片段的深度值比較,確定⽚段是否應該被拒絕。
  • 混合: 混合將新生成的⽚段顏⾊值與儲存在幀緩衝區 (Xw,Yw) 位置的顏⾊值組合起來。
  • 抖動: 抖動可用於最⼩化,因為使用有限精度在幀快取區中儲存顏色⽽產生的偽像。

6、EGL (Embedded Graphics Library )

OpenGL ES 命令需要 渲染上下文繪製表面 才能完成圖形影象的繪製。

  • 渲染上下文: 儲存相關 OpenGL ES 狀態。
  • 繪製表⾯: 是⽤於繪製圖元的表面,它指定渲染所需要的快取區型別,例如顏色緩衝區、深度緩衝區和模板緩衝區。

OpenGL ES API 並沒有提供如何建立渲染上下文或者上下文如何連線到原⽣窗⼝系統。EGLKhronos 渲染 API(如OpenGL ES)和原生視窗系統之間的介面。唯一⽀持 OpenGL ES 卻不⽀持 EGL 的平臺是 iOSApple 提供自己的 EGL APIiOS 實現,稱為 EAGL。 因為每個窗⼝系統都有不同的定義,所以 EGL 提供基本的不透明型別—EGLDisplay,這個型別封裝了所有統相關性,⽤於和原⽣生窗⼝系統介面。

至此,我們完成了 OpenGL ES 的初探(上)。後面我還會繼續分享深入學習 OpenGL ES 的學習成果給大家,點選進入 《OpenGL ES初探(下)—— GLKit》

以上的總結參考了並部分摘抄了以下文章,非常感謝以下作者的分享!: 《OPENGL ES 3.0程式設計指南 原書第2版》

轉載請備註原文出處,不得用於商業傳播——凡幾多