利用GLSL自定義的著色去加載壹張圖片,效果圖如下
整體流程圖如下
流程中主要分為4個模塊
項目的創建及自定義視圖創建等,這裏不作過多說明,主要說說著色器文件是如何創建的
自定義的著色器本質上其實是壹個字符串,且在Xcode中編寫時,是沒有任何提示的,所以需要格外仔細!
頂點著色器
片與著色器
初始化主要分為4部分
setupLayer函數:創建圖層
layer主要是用於顯示OpenGL ES繪制內容的載體
setupContext函數:創建上下文
上下文主要是用於保存 OpenGL ES 中的狀態,是壹個狀態機,不論是 GLKit 還是 GLSL ,都是需要 context 的,主要創建流程如下
deleteRenderAndFrameBuffer函數:清理緩存區
清理緩沖區的目的在於清除殘留數據,防止殘留數據對本次操作造成影響
需要清空兩個緩存區: RenderBuffer和FrameBuffer
設置RenderBUffe & FrameBuffer
首先了解壹下RenderBuffer和FrameBuffer
兩者間的關系如下圖:
setupRenderBuffer函數
主要是創建 RenderBufferID 並申請標識符,將標識符綁定至 GL_RENDERBUFFER ,並且將 layer 的相關存儲綁定到 RenderBuffer 對象
setupFrameBuffer函數
主要是創建 FrameBuffer 的ID並申請標識符,將標識符綁定至 GL_FRAMEBUFFER ,然後將 RenderBuffer 通過 glFramebufferRenderbuffer 函數綁定到 FrameBuffer 中的 GL_COLOR_ATTACHMENT0 附著點上,通過 FrameBuffer 來管理 RenderBuffer , RenderBuffer 存儲相關數據到相應緩存區
繪制的整體流程圖所示:
主要包含5部分
初始化
需要註意的是,需要將視口的大小設置為與屏幕大小壹致
GLSL自定義著色器加載
自定義著色器的加載主要分為以下幾步
讀取自定義著色器
讀取自定義著色器文件的前提是需要獲得文件的路徑,將其傳入 loadShaders 函數進行加載
loadShaders函數 & compileShader函數
loadShaders 函數:分別將頂點著色器和片元著色器編譯完成後,並返回著色器對應的 ID ,然後通過 glAttachShader 函數將頂點和片元的 shader 分別附著到 program 上,然後釋放不再使用的 shader ,並賦值給全局的 program
鏈接program
使用program
通過 glUseProgram 函數來使用鏈接成功的 program
頂點數據設置及處理
通過數組存儲頂點數據,並將頂點坐標和紋理坐標讀取到自定義的頂點著色器中
分為以下三步
開辟頂點緩存區
開啟頂點緩存區,這部分其實跟之前使用 GLKit 框架開啟緩存區步驟是壹致的,沒什麽變化,有以下四步
打開頂點/片元的通道
在 iOS 中, attribute 通道默認是關閉的,需要手動開啟,而數據有頂點坐標和紋理坐標兩種,需要分別開啟兩次,這裏的開啟與 GLKit 框架中是有所區別的,
使用自定義著色器打開通道,壹般有以下三步(相對於 GLKit 而言,只多了壹個獲取入口的步驟,後面兩步是沒有多大變化的)
加載紋理
這部分的內容主要是將 png/jpg 圖片解壓成位圖,並通過自定義著色器讀取紋理每個像素點的紋素,包含兩部分
setupTexture函數
將 png/jpg 解壓成位圖,加載成紋理數據,其中紋理的解壓縮使用的都是 CoreGraphic ,加載紋理的流程如下圖
設置紋理采樣器
主要是獲取紋理中對應像素點的的顏色值,即紋素
繪制
開始繪制,存儲到 RenderBuffer ,從 RenderBuffer 將圖片顯示到屏幕上
*調用 glDrawArrays 函數指定圖元連接方式進行繪制