OpenGL 圖形庫使用(二) —— 渲染模式、對象、擴展和狀態機

版本記錄

版本號 時間
V1.0 2017.07.22

前言

OpenGL 圖形庫項目中一直也沒用過,最近也想學著使用這個圖形庫,感覺還是很有意思,也就自然想著好好的總結一下。
1. OpenGL 圖形庫使用(一) —— 概念基礎

深入認識OpenGL ES

它是一個API(Application Programming Interface, 應用程序編程接口),包含了一系列可以操作圖形、圖像的函數。然而,OpenGL本身并不是一個API,它僅僅是一個由Khronos組織制定并維護的規范(Specification)

OpenGL規范嚴格規定了每個函數該如何執行,以及它們的輸出值。至于內部具體每個函數是如何實現(Implement)的,將由OpenGL庫的開發者自行決定。因為OpenGL規范并沒有規定實現的細節,具體的OpenGL庫允許使用不同的實現,只要其功能和結果與規范相匹配(亦即,作為用戶不會感受到功能上的差異)。實際的OpenGL庫的開發者通常是顯卡的生產商。你購買的顯卡所支持的OpenGL版本都為這個系列的顯卡專門開發的。當你使用Apple系統的時候,OpenGL庫是由Apple自身維護的。在Linux下,有顯卡生產商提供的OpenGL庫,也有一些愛好者改編的版本。這也意味著任何時候OpenGL庫表現的行為與規范規定的不一致時,基本都是庫的開發者留下的bug

所有版本的OpenGL規范文檔都被公開的寄存在Khronos那里。

OpenGL ES 3.0主要新功能有:

  • 渲染管線多重增強,實現先進視覺效果的加速,包括遮擋查詢(Occlusion Query)變緩反饋(Transform Feedback)實例渲染(Instanced Rendering)、四個或更多渲染目標支持。
  • 高質量ETC2/EAC紋理壓縮格式成為一項標準功能,不同平臺上不再需要需要不同的紋理集。
  • 新版GLSL ES 3.0著色語言,全面支持整數和32位浮點操作。
  • 紋理功能大幅增強,支持浮點紋理、3D紋理、深度紋理、頂點紋理、NPOT紋理、R/RG單雙通道紋理、不可變紋理、2D陣列紋理、無二次冪限制紋理、陰影對比、調配(swizzle)、LOD與mip level clamps、無縫立方體貼圖、采樣對象、紋理MSAA抗鋸齒渲染器。
  • 一系列廣泛的精確尺寸紋理和渲染緩沖格式,便攜移動應用更簡單。

在ios上,可以支持openGL ES 3.0的最低環境是iphone5s ios 7.0


核心模式與立即渲染模式

下面我們就看一下渲染模式。

早期的OpenGL使用立即渲染模式(Immediate mode,也就是固定渲染管線),這個模式下繪制圖形很方便。OpenGL的大多數功能都被庫隱藏起來,開發者很少能控制OpenGL如何進行計算的自由。而開發者迫切希望能有更多的靈活性。隨著時間推移,規范越來越靈活,開發者對繪圖細節有了更多的掌控。立即渲染模式確實容易使用和理解,但是效率太低。因此從OpenGL3.2開始,規范文檔開始廢棄立即渲染模式,并鼓勵開發者在OpenGL的核心模式(Core-profile)下進行開發,這個分支的規范完全移除了舊的特性。

當使用OpenGL的核心模式時,OpenGL迫使我們使用現代的函數。當我們試圖使用一個已廢棄的函數時,OpenGL會拋出一個錯誤并終止繪圖。現代函數的優勢是更高的靈活性和效率,然而也更難于學習。立即渲染模式從OpenGL實際運作中抽象掉了很多細節,因此它在易于學習的同時,也很難讓人去把握OpenGL具體是如何運作的。現代函數要求使用者真正理解OpenGL和圖形編程,它有一些難度,然而提供了更多的靈活性,更高的效率,更重要的是可以更深入的理解圖形編程。

當使用新版本的OpenGL特性時,只有新一代的顯卡能夠支持你的應用程序。這也是為什么大多數開發者基于較低版本的OpenGL編寫程序,并只提供選項啟用新版本的特性。


擴展

OpenGL的一大特性就是對擴展(Extension)的支持,當一個顯卡公司提出一個新特性或者渲染上的大優化,通常會以擴展的方式在驅動中實現。如果一個程序在支持這個擴展的顯卡上運行,開發者可以使用這個擴展提供的一些更先進更有效的圖形功能。通過這種方式,開發者不必等待一個新的OpenGL規范面世,就可以使用這些新的渲染特性了,只需要簡單地檢查一下顯卡是否支持此擴展。通常,當一個擴展非常流行或者非常有用的時候,它將最終成為未來的OpenGL規范的一部分。

使用擴展的代碼大多看上去如下:

if(GL_ARB_extension_name)
{
    // 使用硬件支持的全新的現代特性
}
else
{
    // 不支持此擴展: 用舊的方式去做
}


狀態機

OpenGL自身是一個巨大的狀態機(State Machine):一系列的變量描述OpenGL此刻應當如何運行。OpenGL的狀態通常被稱為OpenGL上下文(Context)。我們通常使用如下途徑去更改OpenGL狀態:設置選項,操作緩沖。最后,我們使用當前OpenGL上下文來渲染。

假設當我們想告訴OpenGL去畫線段而不是三角形的時候,我們通過改變一些上下文變量來改變OpenGL狀態,從而告訴OpenGL如何去繪圖。一旦我們改變了OpenGL的狀態為繪制線段,下一個繪制命令就會畫出線段而不是三角形。

當使用OpenGL的時候,我們會遇到一些狀態設置函數(State-changing Function),這類函數將會改變上下文。以及狀態使用函數(State-using Function),這類函數會根據當前OpenGL的狀態執行一些操作。只要你記住OpenGL本質上是個大狀態機,就能更容易理解它的大部分特性。


對象

OpenGL庫是用C語言寫的,同時也支持多種語言的派生,但其內核仍是一個C庫。由于C的一些語言結構不易被翻譯到其它的高級語言,因此OpenGL開發的時候引入了一些抽象層。“對象(Object)”就是其中一個。

在OpenGL中一個對象是指一些選項的集合,它代表OpenGL狀態的一個子集。比如,我們可以用一個對象來代表繪圖窗口的設置,之后我們就可以設置它的大小、支持的顏色位數等等。可以把對象看做一個C風格的結構體(Struct)

struct object_name 
{
    float  option1;
    int    option2;
    char[] name;
};

當我們使用一個對象時,通常看起來像如下一樣(把OpenGL上下文看作一個大的結構體)。

// OpenGL的狀態
struct OpenGL_Context {
    ...
    object* object_Window_Target;
    ...     
};

// 創建對象
unsigned int objectId = 0;
glGenObject(1, &objectId);
// 綁定對象至上下文
glBindObject(GL_WINDOW_TARGET, objectId);
// 設置當前綁定到 GL_WINDOW_TARGET 的對象的一些選項
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_WIDTH, 800);
glSetObjectOption(GL_WINDOW_TARGET, GL_OPTION_WINDOW_HEIGHT, 600);
// 將上下文對象設回默認
glBindObject(GL_WINDOW_TARGET, 0);

這一小段代碼展現了你以后使用OpenGL時常見的工作流。我們首先創建一個對象,然后用一個id保存它的引用(實際數據被儲存在后臺)。然后我們將對象綁定至上下文的目標位置(例子中窗口對象目標的位置被定義成GL_WINDOW_TARGET)。接下來我們設置窗口的選項。最后我們將目標位置的對象id設回0,解綁這個對象。設置的選項將被保存在objectId所引用的對象中,一旦我們重新綁定這個對象到GL_WINDOW_TARGET位置,這些選項就會重新生效。

使用對象的一個好處是在程序中,我們不止可以定義一個對象,并設置它們的選項,每個對象都可以是不同的設置。在我們執行一個使用OpenGL狀態的操作的時候,只需要綁定含有需要的設置的對象即可。

參考資源

1. LearnOpenGL
2. opengl.org:OpenGL官方網站。
3. OpenGL registry:包含OpenGL各版本的規范和擴展。

后記

未完,待續~~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,533評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,055評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,365評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,561評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,346評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,889評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,978評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,118評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,637評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,558評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,739評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,246評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,980評論 3 346
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,619評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,347評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,702評論 2 370

推薦閱讀更多精彩內容