OpenGL ES 2.0 知識串講(1)――OpenGL ES 2.0 概括

出處:電子設備中的畫家|王爍 於 2017 年 7 月 9 日發表,原文鏈接(http://geekfaner.com/shineengine/blog2_OpenGLESv2_1.html)

 

寫在前面的話

電腦是做什麼用的?

電腦又被稱爲計算機,那麼最重要的工作就是計算。看過三體的同學都知道, 電腦中有無數納米級別的計算單元,通過 0 和 1 的轉換,完成加減乘除的操作。

是什麼使得電腦工作?

驅動,驅使着硬件完成工作。

誰來寫驅動?

製造電腦的公司自己來寫驅動,因爲他們對自己的底層硬件架構最熟悉。

誰會使用驅動?

所有的軟件工程師都會直接或者間接的使用到驅動。

那麼問題來了,如果說不同的電腦公司,製造出來不同的硬件,使用不同的 驅動,提供出來不同的接口供軟件工程師進行使用,那麼軟件工程師就要崩潰了。

所以,一定是需要一個標準,來統一一下。

那麼在哪裏進行統一?

硬件沒有辦法統一,每個電腦公司爲了優化自己電腦性能和功耗,製造出來 不同的硬件架構,這是需要無數的心血完成的,如果統一了,那麼就不需要那麼 多電腦公司了。

所以只能統一驅動的接口。

電腦組件大致分爲:CPU、GPU、內存、總線等。而 OpenGL 就是 GPU 驅動 的一套標準接口(OpenGL ES 爲嵌入式設備 GPU 驅動的標準接口,比如手機, OpenGL ES 全稱:OpenGL for Embedded Systems)。

所以綜上所述,我使用了 5 個問題,引出了 OpenGL 的用處:就是將複雜的、 各種各樣的 GPU 硬件包裝起來,各個電腦公司編寫自家的驅動,然後提供出來 一套統一的接口,供上層軟件工程師調用。這樣,世界就和平了。

誰這麼牛,定義了 OpenGL 這套標準?

Khronos。每當我打這幾個字母的時候,都會抱有一種敬畏的心理,因爲它 不是一家公司,它是一個組織,它是由衆多大公司聯合組建而來,比如 Apple、 Intel、AMD、Google、ARM、Qualcomm、Nvidia 等等等等。各個大公司投入了大 量的人力、資金等創建了這個組織。對電腦 GPU 定義了統一的接口 OpenGL,對 手機 GPU 定義了統一的接口 OpenGL ES(我也非常有幸,在 Intel 工作期間,跟 Intel 駐 Khronos 的 3D 負責人共事了一段時間,每週一次的跨洋電話,都會讓我受益匪淺)

這個組織除了定義了 OpenGL 接口之外,還定義了很多其他接口。目前針對 GPU 又提出了另外一套更底層的接口 Vulkan,這是一套比 OpenGL 更底層的接口, 使用其可以更容易優化,不過目前硬件廠商的驅動還有待開發,可能普及 Vulkan 還需要很多年。就好比 OpenGL ES 已經發展到了 3.1,而市面上的手機很多還是 只能支持 OpenGL ES 2.0 一樣。所以新的科技從提出,到實現,到量產,到使用, 到普及,是一段很長的路。

所以,我們現在學習 OpenGL ES 2.0 是適時的,且是非常必要的(不懂 2.0, 想直接學習更難的 3.0、3.1、Vulkan,很難)。

事先預告一下,OpenGL ES 2.0 會分十三個課程,結束之後,我會立即奉上 OpenGL ES 3.0 在 OpenGL ES 2.0 基礎上的改變。

OpenGL 和我們遊戲開發者有什麼關係?

電腦/手機屏幕上顯示的東西,要麼是 2D 的,要麼是 3D 的,那麼如果是 3D 的,不管是 App 也好,遊戲也好,簡單的圖片界面也好,底層都是通過 GPU、 通過 OpenGL(ES)繪製出來的。

開發 App 的時候,是通過創建控件的方式,而控件已經對底層進行了一層封裝,所以 App 開發者很少會接觸到 OpenGL(ES)。

遊戲的開發是通過遊戲引擎,而遊戲引擎的最底層,是直接調用了 OpenGL(ES),直接對 GPU 進行控制。

所以說遊戲引擎工程師必須懂 OpenGL(ES),而遊戲開發者,想要更好的對遊戲進行更好的理解和優化,也建議學一些 OpenGL(ES)。

DirectX 是什麼?

最後一個問題。我們發現 Khronos 組織的成員中,我沒有提到大名鼎鼎的微 軟,因爲微軟不在組織中,而它提出了自己的 GPU 驅動標準,DirectX。

所以目前手機,不管是 iOS 還是 Android,都是支持 OpenGL ES。電腦,Windows 系統支持 DirectX 和 OpenGL,Linux/Mac(Unix)系統支持 OpenGL。

OpenGL ES 的兩個小夥伴

雖然,我們教程的標題是 OpenGL ES,但是我們的內容將不僅限於 OpenGL ES。 OpenGL ES 是負責 GPU 工作的,目的是通過 GPU 計算,得到一張圖片,這張圖 片在內存中其實就是一塊 buffer,存儲有每個點的顏色信息等。而這張圖片最終是要顯示到屏幕上,所以還需要具體的窗口系統來操作,OpenGL ES 並沒有相關的函數。所以,OpenGL ES 有一個好搭檔 EGL。

EGL,全稱:embedded Graphic Interface,是 OpenGL ES 和底層 Native 平臺 視窗系統之間的接口。所以大概流程是這樣的:首先,通過 EGL 獲取到手機屏幕 的 handle,獲取到手機支持的配置(RGBA8888/RGB565 之類,表示每個像素中包 含的顏色等信息的存儲空間是多少位),然後根據這個配置創建一塊包含默認 buffer 的 surface(buffer 的大小是根據屏幕分辨率乘以每個像素信息所佔大小計 算而得)和用於存放 OpenGL ES 狀態集的 context,並將它們 enable 起來。然後, 通過 OpenGL ES 操作 GPU 進行計算,將計算的結果保存在 surface 的 buffer 中。 最後,使用 EGL,將繪製的圖片顯示到手機屏幕上。

 

而在 OpenGL ES 操作 GPU 計算的時候,還需要介紹 OpenGL ES 的另外一個好搭檔 GLSL。

GLSL,全稱:OpenGL Shading Language,是 OpenGL ES 中使用到的着色器的 語言,用這個語言可以編寫小程序運行在 GPU 上。

在這裏需要先提到 CPU 和 GPU 的區別,它們的功能都是用於計算,也都是由很多核組成,區別在於 CPU 的核比較少,但是單個核的計算能力比較強,而 GPU 的核很多,但是每個核的計算能力都不算特別強。目前 GPU 的主要工作是用於生成圖片(現在也有通過 GPU 進行高性能運算_並行運算,但是在這裏不屬於討論的範圍),原因就是圖片是由很多像素組成,每個像素都包含有顏色、深度等信息,而爲了得到這些信息數據,針對每個像素點的計算,是可以通過統一的算法來完成。GPU 就擅長處理針對這種大規模數據,使用同一個算法進行計算。而這個算法,就是使用 GLSL 寫成 Shader,供 GPU 運算使用。

在圖形學的視角中,所有的圖片都是由三角形構成的。所以通過 OpenGL ES 繪製圖片的時候,我們需要通過 OpenGL ES API 創建用於在 GPU 上運行的 shader, 然後將通過 CPU 獲取到的圖片頂點信息,傳入 GPU 中的 Shader 中。在 Vertex Shader 中通過矩陣變換,將頂點座標從模型座標系轉換到世界座標系,再到觀察座標系,到裁剪座標系,最後投影到屏幕座標系中,計算出在屏幕上各個頂點的座標。然後,通過光柵化,以插值的方法得到所有像素點的信息,並在 Fragment shader 中計算出所有像素點的顏色。最後,通過 OpenGL ES 的 API 設定的狀態,將得到的像素信息進行 depth/stencil test、blend,得到最終的圖片。


屏幕圖片的本質和產生過程

當我們買一個手機的時候,我們會非常關注這個手機的分辨率。分辨率代表着像素的多少,比如我們熟知的 iphone6 的分辨率爲 1334×750,而 iphone6 plus 的分辨率是1920×1080。

手機屏幕上的圖片,是由一個一個的像素組成,那麼可以計算出來,一個屏幕上的圖片,是由上百萬個像素點組成。而每個像素點都有自己的顏色,每種顏色都是由 RGB 三原色組成。三原色按照不同的比例混合,組成了手機所能顯示出來的顏色。

每個像素的顏色信息都保存在 buffer 中,這塊 buffer 可以分給 RGB 每個通 道各 8bit 進行信息保存,也可以分給 RGB 每個通道不同的空間進行信息保存, 比如由於人眼對綠色最敏感,那麼可以分配給 G 通道 6 位,R 和 B 通道各 5 位。這些都是常見的手機配置。假如使用 RGB888 的手機配置,也就是每種顏色的取值從 0 到 255,0 最小,255 最大。那麼紅綠藍都爲 0 的時候,這個像素點的顏色就是黑色,紅綠藍都爲 255 的時候,這個像素點的顏色就是白色。當紅爲 255, 綠藍都爲 0 的時候,這個像素點的顏色就是紅色。當紅綠爲 255,藍爲 0 的時候, 這個像素點的顏色就是黃色。當然不是隻取 0 或者 255,可以取 0-255 中間的值, 100,200,任意在 0 和 255 中間的值都沒有問題。那麼我們可以算一下,按照紅綠藍不同比例進行搭配,每個像素點,可以顯示的顏色有 255*255*255=16581375 種,這個數字是非常恐怖,所以我們的手機可以顯示出來各種各樣的顏色。 這裏在延伸的科普一下,我們看到手機可以顯示那麼多種顏色了,但是是不是說我們的手機在顏色上就已經發展到極致了呢?其實是遠遠沒有的,在這個手機配置下,三原色中每一種的取值可以從 0 到 255,而在現實生活中,它們的取 值可以從 0 到 1 億,而我們人類的眼睛所能看到的範圍是,從 0 到 10 萬。所以手機硬件還存在很大的提升空間。而在手機硬件提升之前,我們也可以通過 HDR 等技術儘量的在手機中多顯示一些顏色。所以,講到這裏,我們知道了,手機屏幕上顯示的圖片,是由這上百萬個像素點,以及這上百萬個像素點對應的顏色組成的。

用程序員的角度來看,就是手機屏幕對應着一塊 buffer,這塊 buffer 對應上百萬個像素點,每個像素點需要一定的空間來存儲其顏色。如果使用更加形象的例子來比喻,手機屏幕對應的 buffer 就好像一塊巨大的棋盤,棋盤上有上百萬個格子,每個格子都有自己的顏色,那麼從遠處整體的看這個棋盤,就是我們看手機的時候顯示的樣子。這就是手機屏幕上圖片的本質。

通過我們對 EGL、GLSL、OpenGL ES 的理解,藉助一張圖片,從專業的角度來解釋一下手機屏幕上的圖片是如何生成的。

opengles

 

首先,通過 EGL 獲取手機屏幕,進而獲取到手機屏幕對應的這個棋盤,同時, 在手機的 GPU 中根據手機的配置信息,生成另外一個的棋盤和一個本子,本子是用於記錄這個棋盤初始顏色等信息。

然後,OpenGL ES 就好像程序員的畫筆,程序員需要知道自己想畫什麼東西,比如想畫一個蘋果,那麼就需要通過爲數不多的基本幾何圖元(如點、直線、三 角形)來創建所需要的模型。比如用幾個三角形和點和線來近似的組成這個蘋果 (圖形學的根本就是點、線和三角形,所有的圖形,都可以由這些基本圖形組成, 比如正方形或者長方形,就可以由兩個三角形組成,圓形可以由無數個三角形組成,只是三角形的數量越多,圓形看上去越圓潤)。

根據這些幾何圖元,建立數學描述,比如每個三角形或者線的頂點座標位置、每個頂點的顏色。得到這些信息之後,可以先通過 OpenGL ES 將 EGL 生成的棋盤 (buffer)進行顏色初始化,一般會被初始化爲黑色。然後將剛纔我們獲取到的頂點座標位置,通過矩陣變化的方式,進行模型變換、觀察變換、投影變換,最後映射到屏幕上,得到屏幕上的座標。這個步驟可以在 CPU 中完成,也就是在 OpenGL ES 把座標信息傳給 Shader 之前,在 CPU 中通過矩陣相乘等方式進行更新,或者是直接把座標信息通過 OpenGL ES 傳給 Shader,同時也把矩陣信息傳給 Shader,通過 Shader 在 GPU 端進行座標更新,更新的算法通過 GLSL 寫在 Shader 中。這個進行座標更新的 Shader 被稱爲 vertex shader,簡稱 VS,是 OpenGL ES2.0, 也是 GLSL130 版本對應的最重要兩個 shader 之一,作用是完成頂點操作階段中的所有操作。經過矩陣變換後的像素座標信息,爲屏幕座標系中的座標信息。在 VS 中,最重要的輸入爲頂點座標、矩陣(還可以傳入頂點的顏色、法線、紋理 座標等信息),而最重要的運算結果,就是這個將要顯示在屏幕上的座標信息。 VS 會針對傳入的所有頂點進行運算,比如在 OpenGL ES 中只想繪製一個三角形 和一條線,這兩個圖元不共享頂點,那麼在 VS 中,也就傳入了 5 個頂點信息, 根據矩陣變換,這 5 個頂點的座標轉換成了屏幕上的頂點座標信息,從圖上顯示, 也就是從左上角的圖一,更新成了中上圖的圖二。

再然後,當圖二生成之後,我們知道了圖元在屏幕上的頂點位置,而頂點的顏色在 VS 中沒有發生變化,所以圖元的頂點顏色我們也是知道的。下面就是根據 OpenGL ES 中設置的狀態,表明哪些點連成線,哪些點組成三角形,進行圖元裝配,也就是我們在右上角的圖三中看到的樣子。這個樣子在 GPU 中不會顯示, 那幾條線也是虛擬的線,是不會顯示在棋盤 buffer 中的,而 GPU 做的是光珊化,這一步是發生在從 VS 出來,進入另外一個Shader (Pixel shader,也稱 fragment shader)之前,在 GPU 中進行的。作用是把線上,或者三角形內部所有的像素點找到,並根據插值或者其他方式計算出其顏色等信息(如果不通過插值,可以使用其他的方法,這些在 OpenGL ES 和 GLSL 中都可以進行設置)。也就生成了下面一行的圖四和圖五。

我們大概可以看到在圖 4 和圖 5 種出現了大量的頂點,大概數一下估計有 40 個點左右,這些點全部都會進入 PS 進行操作,在 PS 中可以對這些點的顏色進行操作,比如可以只顯示這些點的紅色通道,其他的綠藍通道的值設置爲 0, 比如之前某個點的 RGB 爲 200,100,100。在 PS 中可以將其通過計算,更新爲 200,0,0。這樣做的結果就是所顯示的圖片均爲紅色,只是深淺不同。這也就好像戴上了一層紅色的濾鏡,其他顏色均爲濾掉了。所以用 PS 來做濾鏡是非常方便的。再比如,假如一盞紅色的燈照到了蘋果上,那麼顯示出來的顏色就是在蘋果原本的顏色基礎上,紅色值進行一定的增值。

所以,總結一下,經過 VS 和 PS 之後,程序員想要畫的東西,就已經被畫出來了。想要繪製的東西,也就是左下角圖五的樣子。然後再根據 OpenGL ES 的設置,對新繪製出來的東西進行 Depth/Stencil Test,剔除掉被遮擋的部分,將剩餘部分與原圖片進行 Blend,生成新的圖片。 最後,通過 EGL,把這個生成的棋盤 buffer 和手機屏幕上對應的棋盤 buffer 進行調換,讓手機屏幕顯示這個新生成的棋盤,舊的那個棋盤再去繪製新的圖片信息。周而復始,不停的把棋盤進行切換,也就像過去看連環畫一樣,動畫就是由一幅幅的圖片組成,當每秒切換的圖片數量超過 30 張的時候,我們的手機也就看到了動態的效果。這就是屏幕上圖片的產生過程。

在這裏再進行一下延伸,這個例子中,VS 計算了 5 個頂點的數據,PS 計算 了大概 40 個頂點的數據,而我們剛纔說過,手機中存在上百萬個像素點,這上百萬個像素點都可以是頂點,那麼這個計算量是非常大的。而這也是爲什麼要將 shader 運算放在 GPU 中的原因,因爲 GPU 擅長進行這種運算。

我們知道 CPU 現在一般都是雙核或者 4 核,多的也就是 8 核或者 16 核,但是 GPU 動輒就是 72 核,多的還有上千核,這麼多核的目的就是進行並行運算, 雖然單個的 GPU 核不如 CPU 核,但是單個的 GPU 核足夠進行加減乘除運算,所以大量的 GPU 核用在圖形學像素點運算上,是非常有效的。而 CPU 雖然單個很強大,而且也可以通過多級流水來提高吞吐率,但是終究還是不如 GPU 的多核來得快。但是在通過 GPU 進行多核運算的時候,需要注意的是:如果 shader 中存放判斷語句,就會對 GPU 造成比較大的負荷,不同 GPU 的實現方式不同,多數 GPU 會對判斷語句的兩種情況都進行運算,然後根據判斷結果取其中一個。

我們通過這個例子再次清楚了 OpenGL ES 繪製的整個流程,而這個例子也是最簡單的一個例子,其中有很多 OpenGL ES 的其他操作沒有被涉及到。比如,我們繪製物體的顏色大多是從紋理中採樣出來,那麼設計到通過 OpenGL ES 對紋理 進行操作。而 OpenGL ES 的這些功能,我們會在下面一點一點進行學習。


OpenGL ES pipeline

opengles

 

EGL 是用於與手機設備打交道,比如獲取繪製 buffer,將繪製 buffer 展現到手機屏幕中。那麼拋開 EGL 不說,OpenGL ES 與 GLSL 的主要功能,就是往這塊 buffer 上繪製圖片。

所以,我們可以把OpenGL ES和GLSL的流程單獨拿出來進行歸納總結,而這幅流程圖就是著名的 OpenGL ES2.0 pipeline。

首先,最左邊的 API 指的就是 OpenGL ES 的 API,OpenGL ES 其實是一個圖形學庫,由 109 個 API 組成,只要明白了這 109 個 API 的意義和用途,就掌握了OpenGL ES 2.0。

然後,我們通過 API 先設定了頂點的信息,頂點的座標、索引、顏色等信息,將這些信息傳入 VS。

在 VS 中進行運算,得到最終的頂點座標。再把算出來的頂點座標進行圖元裝配,構建成虛擬的線和三角形。再進行光珊化(在光珊化的時候,把頂點連接起來形成直線,或者填充多邊形的時候,需要考慮直線和多邊形的直線寬度、點的大小、漸變算法以及是否使用支持抗鋸齒處理的覆蓋算法。最終的每個像素點,都具有各自的顏色和深度值)。

將光珊化的結果傳入 PS,進行最終的顏色計算。

然後,這所謂最終的結果在被實際存儲到繪製 buffer 之前,還需要進行一系列的操作。這些操作可能會修改甚至丟棄這些像素點。

這些操作主要爲 alpha test、Depth/Stencil test、Blend、Dither。

Alpha Test 採用一種很霸道極端的機制,只要一個像素的 alpha 不滿足條件, 那麼它就會被 fragment shader 捨棄,被捨棄的 fragments 不會對後面的各種 Tests 產生影響;否則,就會按正常方式繼續下面的檢驗。Alpha Test 產生的效果也很極端,要麼完全透明,即看不到,要麼完全不透明。

Depth/stencil test 比較容易理解。由於我們繪製的是 3D 圖形,那麼座標爲 XYZ,而 Z 一般就是深度值,OpenGL ES 可以對深度測試進行設定,比如設定深度值大的被拋棄,那麼假如繪製 buffer 上某個像素點的深度值爲 0,而 PS 輸出的 像素點的深度值爲 1,那麼 PS 輸出的像素點就被拋棄了。而 stencil 測試更加簡單,其又被稱爲蒙版測試,比如可以通過 OpenGL ES 設定不同 stencil 值的配拋棄, 那麼假如繪製 buffer 上某個像素點的 stencil 值爲 0,而 PS 輸出的像素點的 stencil 值爲 1,那麼 PS 輸出的像素點就被拋棄了。

既然說到了 Depth/stencil,那麼就在這裏說一下繪製 buffer 到底有多大,存 儲了多少信息。按照我們剛纔的說法,手機可以支持一百萬個像素,那麼生成的 繪製 buffer 就需要存儲這一百萬個像素所包含的信息,而每個像素包含的信息, 與手機配置有關,假如手機支持 Depth/stencil。那麼通過 EGL 獲取的繪製 buffer 中,每個像素點就包含了 RGBA 的顏色值,depth 值和 stencil 值,其中 RGBA 每個分量一般佔據 8 位,也就是 8bit,也就是 1byte,而 depth 大多數佔 24 位,stencil 佔 8 位。所以每個像素佔 64bit,也就是 8byte。那麼 iphone6 plus 的繪製 buffer 的尺寸爲 1920×1080×8=16588800byte=16200KB=15.8MB。

下面還有 blend,通過 OpenGL ES 可以設置 blend 混合模式。由於繪製 buffer 中原本每個像素點已經有顏色了,那麼 PS 輸出的顏色與繪製 buffer 中的顏色如何混合,生成新的顏色存儲在繪製 buffer 中,就是通過 blend 來進行設定。

最後的 dither,dither 是一種圖像處理技術,是故意造成的噪音,用以隨機化量化誤差,阻止大幅度拉昇圖像時,導致的像 banding(色帶)這樣的問題。也 是通過OpenGL ES 可以開啓或者關閉。(Patrick:Dither還需要再開一個課題好好說)

經過了這一系列的運算和測試,也就得到了最終的像素點信息,將其存儲到繪製 buffer 上之後,OpenGL ES 的 pipeline 也就結束了。

整個pipeline中,縱向按照流水線作業,橫線按照獨立作業,多級並行、提高渲染性能。


OpenGL ES API 總覽

剛纔我們已經說了,OpenGL ES 就是一個圖形學庫,由 109 個 API 組成。之後的教程我們會對這 109 個 API 進行詳細解釋,在這裏我們先介紹一下這 109 個 API 大概是做什麼的。

首先,有 9 個 API,用於從手機創建繪製 buffer。雖然 EGL 會提供給 OpenGL ES 一塊繪製 buffer,這塊繪製 buffer 之後還會顯示在屏幕上,但是 OpenGL ES 也可以根據自定義的配置生成一塊或者多塊 buffer,並且可以先把一些內容繪製到這些備用 buffer 上,之後根據一定的處理,最後再將正式的內容繪製到真正的繪製 buffer 上,然後顯示到屏幕上。或者也可以直接把備用 buffer 中的內容顯示到屏幕上。一般複雜一些的圖形程序,都會使用到這些 API。

然後,有 12 個 API,用於溝通 GPU 可編程模塊 Shader。根據我們上面所說的內容,講到了 shader 的概念。Shader 是由 OpenGL ES 創建的,在 OpenGL ES 看來 shader 就類似於一個 handle;然後通過 OpenGL ES 給 shader 中寫入內容; 觸發 GPU 對 Shader 進行編譯;編譯成功之後,通過 OpenGL ES 將一個 VS 和一個 PS 連接在一起,綁定在一個叫做 program 的另外一個 handle 上面;通過 OpenGL ES 啓用這個 program,也就相當於啓用 program 綁定的兩個編譯好的 shader,供 GPU 調用。

之後,有 27 個 API,用於傳入繪製信息,比如通過 API 從 CPU 把頂點信息、 矩陣、紋理圖片等傳入 GPU 中。傳入的方式有很多種,我們之後再一一講解。

再之後,有 30 個 API,用於設置繪製狀態,OpenGL ES 又被人稱爲狀態集, 因爲它就是不停的在設置各種狀態供 GPU 等調用,比如設置是否進行顏色混合以及如何混合,比如設置是否需要 depth、stencil 等 test,以及如何 test 等。

其次,有 2 個 API,用於執行繪製命令,也就是執行這個 API 的時候,將之 前傳入 GPU 的信息關聯在一起。在這個 API 中,可以設置使用哪些頂點進行繪製,以及如何將這些頂點進行圖元裝配等。

還有 25 個 API,用於查詢環境、清理狀態,由於 OpenGL ES 是狀態集,所以 基本上所有的狀態信息都可以查詢出來,即使我們並沒有進行設置,這些狀態也會有默認值,獲取這些狀態信息,可以更有利的幫助我們做出判斷。

最後還有 4 個 API,用於其他用處,等我們說到的時候再進行一一介紹。

本節教程就到此結束,希望大家繼續閱讀我之後的教程。

謝謝大家,再見!


寫在末尾的話

做圖形學相關的工作已經超過五年了,從手機GPU驅動,android app,遊戲引擎,遊戲開發,從底層一路走到應用層。零零散散寫過很多OpenGL ES相關的文章和代碼。

和老闆聊天,學會了積累二字。所以決定一鼓作氣,將之前所有文章彙總成冊,將之前代碼彙總成項目,算是對自己工作五年的一個交代。

文章就在這裏,代碼託管在github:https://github.com/Wangsh09/ShineEngine。目前是一個OpenGL ES功能的代碼,以後可能是一個簡易引擎,也可能是別的。

圖形學博大精深,前面的路還很遠。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章