天天看點

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

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

随着完成這些最後的連接配接,我們現在就準備好開始在螢幕上繪制了!我們将先畫桌子,然後畫分隔線和木槌。

3.5.1 繪制桌子

在ondrawframe()結尾處,讓我們在glclear()調用之後加入如下代碼:

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

我們首先通過調用gluniform4f()更新着色器代碼中的u_color的值。與屬性不同,uniform的分量沒有預設值,是以,如果一個uniform在着色器中被定義為vec4類型,我們需要提供所有四個分量的值。我們想要以畫一張白桌子作為開始,是以,我們把紅色、綠色和藍色的值設定為代表完全亮度的值1.0f;阿爾法的值無關緊要,但是我們還是要指定它,因為一個顔色有四個分量。

一旦指定了顔色,接下來就可以用gldrawarrays(gles20.gl_triangles, 0, 6)繪制桌子了;第一個參數告訴opengl,我們想要畫三角形。而要畫三角形,我們需要給每個三角形傳遞進去至少三個頂點;第二個參數告訴opengl從頂點數組的開頭處開始讀頂點;而第三個參數是告訴opengl讀入六個頂點。因為每個三角形有三個頂點,這個調用最終會畫出兩個三角形。

讓我們快速看一下本章起始處定義的頂點數組:

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制
《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

當我們調用glvertexattribpointer()方法的時候,記得我們曾告訴opengl每個頂點的位置包含兩個浮點數分量。gldrawarrays()調用讓opengl使用前六個頂點繪制三角形,是以,opengl會使用下面這些位置繪制它們:

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

第一個被繪制的三角形由點(0, 0)、(9, 14)和(0, 14)圍成,而第二個由點(0, 0)、(9, 0)及(9, 14)圍成。

下一步是繪制跨越桌子中間的中心分隔線。

在ondrawframe()方法的結尾處加入如下代碼:

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

通過傳遞1.0f給第一個分量(紅色)及傳遞0.0f給綠色和藍色,我們把顔色設為紅色;但這次需要opengl畫線;我們從六個頂點後的第一個頂點開始讀入兩個頂點,opengl就可以畫出線了。正如java數組一樣,這裡使用基于0的編号規則:0、1、2、3、4、5、6,數字6就是六個頂點後的第一個頂點,或者是第七個頂點。因為每條線有兩個頂點,最終用這些位置可以畫出一條線:

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

opengl會從(0, 7)到(9, 7)畫一條線。

最後要做的就是畫兩個木槌;在ondrawframe()結尾處加入如下代碼:

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

通過傳遞gl_points給gldrawarrays()方法,我們讓opengl繪制點。對于第一個木槌,我們設定其顔色為藍色,從偏移位置8開始,并用一個頂點繪制一個點;對于第二個木槌,我們設定其顔色為紅色,以偏移位置9開始,并用一個頂點繪制一個點。我們将使用下面這些位置繪制這兩個點:

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

opengl會在(4.5, 2)繪制第一個點,在(4.5, 12)繪制第二個點。

讓我們運作這個程式,看看螢幕上會出現什麼。按“ctrl+f11”鍵讓程式運作,觀察裝置上或模拟器裡會顯示什麼。你的螢幕看起來應該與圖3-1相似。如果碰到了什麼問題,首先在eclipse裡嘗試選擇“project->clean”,清理這個程式。

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

哦,看起來,哪裡不太對!這個背景還是我們在第1章中使用的紮眼的紅色,對于那個空氣曲棍球桌子,我們為什麼隻看到一個角呢?在讨論這個之前,讓我們來修複這個清屏用的顔色。在onsurface-created()方法的開始處,找到glclearcolor()的調用,把它更新成如下代碼:

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

當glclear()方法被調用的時候,這會告訴opengl把螢幕清除成黑色,而不是紅色。現在我們已經修複了那個紮眼的紅顔色,需要看一下為什麼我們隻能看見空氣曲棍球桌子的一個角了。

目前為止,我們還沒有解決的一個大問題就是:opengl是怎樣把我們已經定義的坐标映射到螢幕上的實際實體坐标的?

這個問題的答案很複雜,随着後面章節的講解,我們會了解到更多有關的内容;目前,我們隻需要知道,無論是x還是y坐标,opengl都會把螢幕映射到[-1,1]的範圍内。這就意味着螢幕的左邊對應x軸的-1,而螢幕的右邊對應+1;螢幕的底邊會對應y軸的-1,而螢幕的頂邊就對應+1,如圖3-2所示。

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

不管螢幕是什麼形狀和大小,這個坐标範圍都是一樣的,如果我們需要在螢幕上顯示任何東西,都需要在這個範圍内繪制它們。讓我們回到構造函數,把tablevertices-withtriangles中定義的坐标更新為如下值:

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

讓我們再次運作這個應用,我們應該看到與圖3-3類似的螢幕:

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

這看起來好多了,但是木槌哪去了?事實證明,對于點來說,opengl需要我們指定在螢幕上所顯示的點的大小,但我們還沒指定這個大小呢。

我們可以更新代碼,告訴opengl那些點在螢幕上所顯示的大小。在simple_vertex_shader.glsl檔案裡,在gl_position指派後面,我們可以加入如下代碼行指定其大小:

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

通過給另外一個特殊的輸出變量gl_pointsize指派,我們告訴opengl這些點的大小應該是10。你可能會問,10個什麼?當opengl把一個點分解為片段的時候,它會生成一些片段,它們是以gl_position為中心的四邊形,這個四邊形的每條邊的長度與gl_pointsize相等。gl_pointsize值越大,螢幕上繪出的點越大。

讓我們再運作一次這個應用。我們應該能看到如圖3-4所示的木槌,每個木槌都被渲染為單個的點。

《OpenGL ES應用開發實踐指南:Android卷》—— 3.5 在螢幕上繪制

我們終于把它畫出來了!休息一下,坐下來,回憶一下你在本章學過的内容。本章的内容很多,但是我們還是把它講完了,而且想辦法得到了我們要在螢幕上顯示的東西。

如果你準備好了,讓我們回顧一下學過的内容,再做兩個後續的練習。

繼續閱讀