本章介紹我們 的第一個項目:簡單的空氣曲棍球遊戲。(不懂事什麼的百度谷歌搜一搜)
1.定義空氣曲棍球桌子的結構
1.1 我們可以重用第一章的項目
- 把項目重命名爲AirHockey1
- 把FirstOpenGLProjectActivity重命名爲AirHockeyActivity
- 把FirstOpenGLProjectRenderer重命名爲AirHockeyRenderer
- 把strings.xml裏的app_name修改爲AirHockey
- 把包名com.firstopenglproject.android修改爲com.airhockey.android
1.2 在代碼中定義頂點
因爲這些頂點定義在二維二維座標系中,所以每個頂點要用兩個浮點數進行標記:一個標記x軸的位置,另外一個標記y軸的位置。
因爲一個頂點有兩個分量,.所以首先創建一個常量用來記住這一事實;打開AirHockeyRenderer類,並在它的頂端加入如下常量:
在onSurfaceCreated()的前面加入如下構造函數
2.使數據可以被OpenGL存取
在AirHockeyRenderer類的頂部,構造函數之前加入如下代碼:
那個FloatBuffer用來在本地內存中存儲數據
在構造函數體的結尾處加入如下代碼:
- ByteBuffer.allocateDirect()分配了一塊本地內存,這塊內存不會被垃圾回收器回收管理。因爲頂點都存儲在一個浮點數組裏,並且每個浮點數有4個字節,所以這塊內存的大小應該是tableVerticesWithTriangles.length * BYTES_PER_FLOAT。
- 下一行order(ByteOrder.nativeOrder())告訴字節緩衝區(byte buffer)按照本地字節序(native byte order)組織它的內容;
- 我們不願意直接操作單獨的字節,而是希望使用浮點數。所以調用asFloatBuffer()得到一個可以反映底層字節的FloatBuffer類實例;
- 然後就可以調用vertexData.put(tableVerticesWithTriangles)把數據從Dalvik的內存複製到本地內存了。當進程結束的時候,這塊內存就會被釋放掉,所以我們一般不用關心她。
3.引入OpenGL管道
我們定義了曲棍球桌子的結構,並且把這些數據複製到了OpenGL可以存取的本地內存;把曲棍球桌子畫到屏幕上之前,她需要在OpenGL的管道(pipeline)中傳遞,這就需要使用稱爲着色器(shader)的子例程。這些着色器會告訴圖形處理單元(GPU)如何繪製數據。有兩種着色器,在繪製任何內容到屏幕之前需要定義她們。
- 頂點着色器(vertex shader)生成每個頂點的最終位置,針對每個頂點,他都會執行一次;一旦最終位置確定了,OpenGL就可以把這些可見的頂點的集合組裝成點、直線以及三角形。
- 片段着色器(fragment shader)爲組成點、直線或者三角形的每個片段生成最終的顏色,針對每個片段,它都會執行一次;一個片段是一個小的、單一的顏色的長方形區域,類似於計算機屏幕上的一個像素。
一旦最後的顏色生成了,OpenGL就會把它們寫到一塊稱爲幀緩衝區(frame buffer)的內存塊中,然後,android會把這個幀緩衝區顯示到屏幕上。
3.1 創建第一個頂點着色器simple_vertex_shader.glsl
3.2 創建第一個片段着色器simple_fragment_shader.glsl
4.小結
- 首先,我們學習瞭如何定義一個頂點屬性數組,並把這個數組複製到本地內存裏,以便OpenGL存取她。
- 然後,我們寫了一個頂點着色器和一個片段着色器;並瞭解到一個着色器只是可以運行在GPU上的一個特殊類型的程序。