OpenGL ES
1.OpenGL ES是OpenGL的子集
2.是針對嵌入式設備及移動終端設備的高級3D圖形應用程序,例如iOS、Android、Windows等
3.OpenGL ES 是跨平臺的,不會提供窗口相關方法,需要系統各自提供載體
OpenGL ES渲染流程
下圖出自蘋果官方文檔OpenGL ES as a Client-Server Architecture
OpenGL ES的渲染主要分為兩部分:CPU和GPU
CPU部分
1.app代碼通過OpenGL ES API,會調度OpenGL ES Framework
2.通過OpenGL ES client 調度 OpenGL ES sever,將頂點數據等傳遞到GPU
GPU部分
做一些圖形硬件的處理,例如光柵化、顯示界面等。
以上圖片的過程
1.API獲得頂點數據,將頂點數據從內存中拷貝至頂點緩沖區(顯存)
2.拿到數據之后,通過attribute通道傳遞至頂點著色器,同事,紋理坐標通過Texture通道傳遞到頂點著色器和片元著色器。
3.圖元裝配,即圖元的鏈接方式,一共有9種,常用的有6種,此步驟將頂點變換為圖形
4.光柵化: 確定圖形與屏幕對應的位置
5.片元(片段/像素)著色器:處理對應像素點的顏色值
6.將處理好的每個像素點的顏色值存儲到幀緩存區,然后顯示器中顯示
7.API:可以通過API操作頂點緩沖區、頂點著色器、紋理坐標、片元著色器
Apple官方圖示
來自蘋果官方文檔OpenGL ES as a Graphics Pipeline
1.APP:提供圖元裝配頂點信息,圖片信息
2.Vertex(頂點著色器):處理頂點 -> 圖形變換(旋轉、縮放、平移)
3.Geometry(圖元裝配):圖元裝配 + 裁剪(超出屏幕部分被裁剪)
4.Fragment(片元著色器) :紋理處理+霧化處理
5.Framebuffer Operation(幀緩沖區) :透明度混合、模板、深度測試;最后在混合
頂點著?器
輸入,有3種方式
1.通過attribute通道輸入頂點數據,提供每個頂點的數據
2.通過uniform通道輸入統一變量,即頂點/片元著色器中使用的不變數據
3.采樣器:表示頂點著色器使用紋理的特殊統一變量類型
輸出:經過處理的最終頂點數據,有2種
gl_Position
是GLSL的內建變量,是將處理后的最終頂點數據復制給它。gl_PointSize
是指頂點尺寸,即可以在頂點著色器中修改每個點的大小,使用率較低。
頂點著色器處理的業務
1.矩陣變換位置
2.計算光照公式生成逐頂點顏色(也可以片元著色器)
3.生成/變換紋理坐標:片元著色器是沒有辦法傳入屬性即attribute的,可以通過頂點著色器橋接,間接將紋理坐標屬性傳遞到片元著色器
頂點著色器GLSL代碼示例
1.attribute、uniform 表示client與server之間的通道
2.其中的vec4、vec2都是向量類型,表示四維向量和二維向量
3.mat4:4*4矩陣
4.varying是修飾符:通過varying將紋理坐標傳入到片元著色器
5.lowp:低精讀
6.main中的操作
- 實現了紋理坐標的橋接
- 實現了頂點旋轉矩陣的相乘:列向量 與 列矩陣 相乘,得到旋轉后的頂點坐標
- 將上述得到的頂點坐標,賦值給
gl_Position
attribute vec4 position;
attribute vec2 textCoordinate;
uniform mat4 rotateMatrix;
varying lowp vec2 varyTextCoord;
void main()
{
varyTextCoord = textCoordinate;
vec4 vPos = position;
vPos = vPos * rotateMatrix;
gl_Position = vPos;
}
圖元裝配、光柵化
1.圖元裝配:將頂點數據計算成一個個圖元
2.光柵化:將圖元轉化為一組二維片段的過程,主要是由于屏幕是2D的,所以轉換的像素點也是二維的
片元著色器
輸入同頂點著色器一樣,有3種方式
1.由頂點著色器橋接傳遞過來的紋理坐標等
2.通過uniform通道輸入統一變量,即頂點/片元著色器中使用的不變數據
3.采樣器:表示頂點著色器使用紋理的特殊統一變量類型,例如紋理就是通過采樣器來傳遞
4.輸出:某個像素點經過片元著色器處理后的結果
片元著色器業務
1.計算顏色
2.獲取紋理值
3.往像素點填充顏色值(紋理值/顏色值)
片元著色器GLSL代碼示例
1.varying:必須和頂點著色器中一模一樣,這樣才能傳遞紋理坐標
2.sampler2D 采樣器類型
3.texture2D(紋理采樣器,紋理坐標):獲取對應位置/坐標的顏色值,簡稱獲得紋素
4.gl_FragColor(內建變量):將最終的顏色值賦值給它
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
void main() {
gl_FragColor = texture2D(colorMap, varyTextCoord); }
總結
1.頂點著色器、片元著色器都是代碼段,類似于iOS中的函數/方法,有返回值
1.1 頂點著色器的返回值會被復制給gl_Position
1.2 片元著色器的結果會賦值給gl_fragColor
2.這兩個返回值都屬于GLSL中的內建變量,是封裝好的,直接將數據賦值給它即可
2.1gl_Position
頂點著色器中某一個頂點經過一系列處理后得到的結果
2.2gl_fragColor
經過片元著色器對某一個像素點來進行處理之后的結果
逐片段操作
這個過程都是GPU內部處理的,開發者并不需要關心,將處理好的數據存儲到幀緩存區,最后讀取幀緩存區將圖形顯示到屏幕上
OpenGL ES的應用
圖片濾鏡
1.獲取圖片中的每一個像素點
2.像素點做飽和度處理
3.得到新的顏色
4.將新的顏色翻入幀緩存區
5.最后進行顯示
視頻濾鏡
- 原理以及處理方式是一樣的(GLSL代碼),視頻也是一幀一幀處理的,而一幀就是一張圖片
1.獲得視頻MP4文件
2.拿到h264(視頻壓縮文件)
3.將視頻解碼(解壓),還原成一幀一幀的圖片
4.針對一幀一幀的圖片進行處理
EGL(Embedded Graphics Library)
- OpenGL ES 命令需要
渲染上下?
和繪制表面
才能完成圖形圖像的繪制
2.渲染上下?: 存儲相關OpenGL ES狀態,是一個狀態機
繪制表面:?于繪制圖元的表面,需要指定渲染的緩存區,例如顏?緩、深度和模板
3.OpenGL ES API 并沒有提供如何創建渲染上下文或者上下文如何連接到原生窗口系 統. EGL 是Khronos 渲染API(如OpenGL ES) 和原?窗?系統之間的接?.
唯?支持 OpenGL ES 卻不支持EGL的平臺是iOS. Apple 提供?己的EGL API的iOS實現,稱為EAGL
4.因為每個窗?系統都有不同的定義,所以EGL提供基本的不透明類型—EGLDisplay, 這 個類型封裝了所有系統相關性,用于和原生窗?系統接?