天天看點

《OpenGL ES應用開發實踐指南:Android卷》—— 2.3 定義空氣曲棍球桌子的結構

本節書摘來自華章出版社《opengl es應用開發實踐指南:android卷》一 書中的第2章,第2.3節,作者:(美)kevin brothaler ,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

在桌子被繪制到螢幕之前,我們需要告訴opengl要畫什麼。開發過程中的第一步是以opengl能了解的形式定義一個桌子結構。在opengl裡,所有東西的結構都是從一個頂點開始。

簡單來說,一個頂點就是一個代表幾何對象的拐角的點,這個點有很多附加屬性;最重要的屬性就是位置,它代表了這個頂點在空間中的定位。

我們曾說過要暫時保持事物簡單,那什麼是能表達空氣曲棍球桌子結構的最基本的圖形呢?我們可以使用長方形。既然一個長方形有4個拐角,我們就需要4個頂點。長方形是一個二維物體,是以每個頂點都需要一個位置,這個位置在每個次元上都要有一個坐标。

如果我們要把它畫到一張圖紙上,我們會得到與圖2-2類似的圖形。

《OpenGL ES應用開發實踐指南:Android卷》—— 2.3 定義空氣曲棍球桌子的結構

讓我們繼續,并寫一些代碼存儲這些頂點;這些頂點會表示為一個浮點數清單;因為它們定義在二維坐标系裡,是以每個頂點要用兩個浮點數進行标記:一個标記x軸的位置,另外一個标記y軸的位置。

因為一個頂點有兩個分量,是以首先建立一個常量用來記住這一事實;打開airhockeyrenderer類,并在它的頂端加入如下常量:

《OpenGL ES應用開發實踐指南:Android卷》—— 2.3 定義空氣曲棍球桌子的結構
《OpenGL ES應用開發實踐指南:Android卷》—— 2.3 定義空氣曲棍球桌子的結構

我們采用了浮點數的順序清單定義頂點資料,是以,我們可以用有小數點的十進制數存儲這些位置;這個數組通常稱為頂點屬性(attribute)數組。到目前為止,隻有位置屬性儲存了,但是,我們稍後也會把顔色及其他屬性用同樣的概念儲存起來。

還記得前面曾說過表示曲棍球桌子的最容易的方式是長方形嗎?然而,令人感到混亂的一點是:在opengl裡,隻能繪制點、直線以及三角形。

三角形是最基本的幾何圖形;因為它的結構如此穩定,它随處可見,比如橋梁的結構化構件;它有三條邊用來連接配接它的三個頂點,如果我們拿掉其中一個頂點,剩下的就是一條直線,如果我們再拿掉一個點,就隻剩下一個點了。

點和直線可以用于某些效果,但是,隻有三角形才能用來建構擁有複雜的對象和紋理的場景。在opengl裡,我們把單獨的點放在一個組裡建構出三角形,再告訴opengl如何連接配接這些點。我們想要建構的所有東西都要用點、直線和三角形定義;如果想建構更複雜的圖形,例如拱形,那我們就需要用足夠的點拟合這樣的曲線。

如果不能使用長方形,我們怎麼定義空氣曲棍球的桌子呢?事實上,我們可以認為桌子是由兩個三角形連接配接在一起的,如圖2-3所示。

《OpenGL ES應用開發實踐指南:Android卷》—— 2.3 定義空氣曲棍球桌子的結構

讓我們改變代碼以反映這一事實,我們現在使用兩個三角形而不是一個長方形:

《OpenGL ES應用開發實踐指南:Android卷》—— 2.3 定義空氣曲棍球桌子的結構

三角形的卷曲順序

你可能注意到了,當我們定義三角形的時候,我們總是以逆時針的順序排列頂點;這稱為卷曲順序(winding order)。因為在任何地方都使用這種一緻的卷曲順序,可以優化性能:使用卷曲順序可以指出一個三角形屬于任何給定物體的前面或者後面,opengl可以忽略那些無論如何都無法被看到的後面的三角形。

在12.5節中我們會學到更多内容。

這個數組表示用六個頂點表示兩個三角形;第一個三角形由(0, 0)、(9, 14)及(0, 14)連接配接組成,第二個三角形共用了其中的兩個點,它由(0, 0)、(9,0)及(9, 14)構成。

無論何時,如果我們想表示一個opengl中的物體,都要考慮如何用點、直線及三角形把它組合出來。

我們幾乎要完成所有頂點的定義了;我們隻需要為中間線和兩個木槌添加一些頂點。最後,會得到與圖2-4相似的圖形。

《OpenGL ES應用開發實踐指南:Android卷》—— 2.3 定義空氣曲棍球桌子的結構

我們将用一條直線定義中間線,并用一個點表示每個木槌。在數組的最後添加一個分号,然後加入下面這些新的

頂點:

《OpenGL ES應用開發實踐指南:Android卷》—— 2.3 定義空氣曲棍球桌子的結構

如你所見,由于這個數組由浮點值組合而成,我們可以使用帶小數的十進制坐标。為了讓java編譯器工作,需要在每個數的後面加上小寫f,它告訴java編譯器把這個數字解釋為浮點數(float),而不是雙精度浮點數(double);雙精度浮點數有大約兩倍的精度(這是其名字的由來),如果我們不加f,java編譯器會把它當作精度丢失的轉換,會要求增加顯式的類型轉換(cast)。

繼續閱讀