android為openGL ES支持提供了GLSurfaceView組件, 這個(gè)組件用于顯示3D圖形,。GLSufaceView本身并不提供繪制3D圖形的功能,,而是由GLSurfaceView.Renderer來完成了SurfaceView中3D圖形的繪制。 歸納起來,在android中使用openGl ES需要三個(gè)步驟: 1,,創(chuàng)建GLSurfaceView組件,,使用activity來顯示GlSufaceView組件 2. 為GLSufaceView組件創(chuàng)建GLSufaceView.Renderer實(shí)例,實(shí)現(xiàn)GLSurfaceView.Renderer類時(shí)需要實(shí)現(xiàn)接口里的三個(gè)方法,。 (1) abstract void onDrawFrame(GL10 gl): Renderer對(duì)象調(diào)用該方法繪制GLSurfaceView的當(dāng)前幀,。 (2)abstract void onSurfaceChanged(GL10 gl, int width, int height):當(dāng)GLSurfaceView的大小改變時(shí)回調(diào)該方法。 (3)abstract void onSufaceCreated(GL10 gl, EGLConfig config):當(dāng)GLSurfaceView被創(chuàng)建時(shí)回調(diào)該方法,。 3.調(diào)用GLSurfaceView組件的setRender()方法指定Renderer對(duì)象,。該Renderer對(duì)象完成GLSurfaceView里3D圖形的繪制。 從上面的介紹不難看出,,實(shí)際上繪制3D圖像的難點(diǎn)不是如何使用GLSurface組件,而是如何實(shí)現(xiàn)Renderer類,。是想Renderer類時(shí)需要三個(gè)方法,。這三個(gè)方法都有一個(gè)GL10形參,他就代表了GLOpen ES的“繪制畫筆”,, 讀者可以把它想象成Swing 2D繪圖中的Graphics,,也就是想象成android2D繪圖中的Canvas組件-當(dāng)我們希望Renderer繪制3D圖像時(shí),實(shí)際上是調(diào)用GL10的方法來進(jìn)行繪制的,。 當(dāng)SurfaceView被創(chuàng)建時(shí),,系統(tǒng)會(huì)回調(diào)Rnderer對(duì)象的onSurfaceCreated()方法,該方法可以對(duì)OpenGL ES執(zhí)行一些無須任何改變的初始化,,例如如下代碼: @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { //關(guān)閉抗抖動(dòng) gl.glDisable(GL10.GL_DITHER); //設(shè)置系統(tǒng)對(duì)透視進(jìn)行修正 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST); gl.glClearColor(0, 0, 0, 0); //設(shè)置陰影平滑模式 gl.glShadeModel(GL10.GL_SMOOTH); //啟用深度測(cè)試 gl.glEnable(GL10.GL_DEPTH_TEST); //設(shè)置深度測(cè)試的類型 gl.glDepthFunc(GL10.GL_LEQUAL); }Gl10就是OpenGL ES的繪圖接口,,雖然這里看到的是一個(gè)GL10,但實(shí)際上它也是GL11的實(shí)例,,讀者可通過(gl instandeof GL11)判斷他是否為GL11接口的實(shí)例,。 上面的方法中用到了一些初始化方法,關(guān)于這些方法的說明如下: (1)glDisable(int cap) : 該方法用于禁用OpenGL ES某個(gè)方面的特性,。 該方法中第一行代碼用于關(guān)閉抗抖動(dòng),,這樣可以提高性能。 (2)glHint(int target, int mode):該方法用于對(duì)OpenGL ES某方面進(jìn)行校正,。 (3)clearColor(float red, float green, float alpha):該方法設(shè)置OpenGl ES"清屏"所用的顏色,,四個(gè)參數(shù)分別設(shè)置紅、綠,、藍(lán),、透明值:0為最小值,1為最大值,。例如gl.glClearColor(0, 0, 0, 0);就是用黑色“清屏”,。 (4) glShadeModel(int mode): 該方法用于設(shè)置OpenGl ES的陰影模式。此處設(shè)置為平滑模式。 (5) glEnable(int cap): 該方法與glDisable(int cap)方法相對(duì),, 用于啟用OpenGL ES某些特性,。此處用于啟動(dòng)OpenGL ES的深度測(cè)試。所謂深度測(cè)試,。就是讓OpenGL ES負(fù)責(zé)跟蹤每個(gè)物體在Z軸的深度,,這樣就可避免后面的物體遮擋前面的物體。 當(dāng)SurfaceView組件的大小發(fā)生改變時(shí),,系統(tǒng)會(huì)回調(diào)Renderer對(duì)象的onSurfaceChanged()方法,, 因此該方法通常用于初始化3D場(chǎng)景,例如如下初始化代碼: @Override public void onSurfaceChanged(GL10 gl, int width, int height) { //設(shè)置3D視窗的大小及位置 gl.glViewport(0, 0, width, height); //將當(dāng)前矩陣模式設(shè)置為投影矩陣 gl.glMatrixMode(GL10.GL_PROJECTION); //初始化單位矩陣 gl.glLoadIdentity(); //計(jì)算透視視窗的高度,、高度比 float ratio = (float)width / height; //調(diào)用此方法設(shè)置透視窗視窗的空間大小 gl.glFrustumf(-ratio, ratio, -1, 0, 1, 10); }上面的方法中用到了GL10的一些初始化方法,,關(guān)于這些方法的說明如下。 (1) glViewport(int x, int y, int width, int height): 設(shè)置3D視窗的位置與大小,,其中前兩個(gè)參數(shù)指定該視窗的位置,,后面兩個(gè)參數(shù)指定該視窗的寬、高,。 (2) glMatrixMode(int mode): 設(shè)置視窗的矩陣模型,,通常可接受GL10.GL_PROJECTION,、 GL10.GL_MODELVIEW兩個(gè)常量值,。 當(dāng)調(diào)用gl.glMatrixMode(GL10.GL_PROJECTION);代碼后,指定將屏幕設(shè)為透視圖(要想看到逼真的三維物體,,這是必要的),, 這意味著越遠(yuǎn)的東西看起來越小,;當(dāng)調(diào)用gl.glMatrixMode(GL10.GL_MODELVIEW);代碼后,,即將當(dāng)前矩陣模式設(shè)為模型視圖矩陣,這意味著任何新的變換都會(huì)影響該矩陣的所有物體,。 (3)glLoaddentity():相當(dāng)于reset()方法,,用于初始化單位矩陣。 (4)glFrustumfglFrustumf(float left, float right, float bottom, float top, float zNear, float zFar): 用于設(shè)置透視投影的空間大小,,前面兩個(gè)參數(shù)用于設(shè)置X軸上的最小坐標(biāo)值,、最大坐標(biāo)值,中間的兩個(gè)參數(shù)用于設(shè)置Y軸的最小坐標(biāo)值,、最大坐標(biāo)值,; 后面兩個(gè)參數(shù)用于設(shè)置Z軸上所能繪制的場(chǎng)景的深度的最小值、最大值,。 例如我們調(diào)用如下代碼: gl.glFrustumf(-0.8f, 0.8f, -1f, 1f, 1f, 10f);這意味著如果有一個(gè)二維矩形,,它的四個(gè)頂點(diǎn)的坐標(biāo)分別為:(-0.8,, 1)、 (0.8,,1),、(0.8, -1),、(-0.8,, -1),這個(gè)矩形將會(huì)占滿整個(gè)視窗,。 提示:前面已經(jīng)指出:三維坐標(biāo)系統(tǒng)與二維坐標(biāo)系統(tǒng)并不相同,,二維坐標(biāo)系統(tǒng)上的坐標(biāo)值通常就直接使用系統(tǒng)的像素?cái)?shù)量;但三維坐標(biāo)系統(tǒng)的坐標(biāo)值則取決于glFrustumf()方法的設(shè)置,,當(dāng)我們調(diào)用gl.glFrustumf(-0.8f, 0.8f, -1f, 1f, 1f, 10f);方法時(shí),,意味著該三維坐標(biāo)系統(tǒng)的最左邊的坐標(biāo)值為-0.8,最右邊的坐標(biāo)值為0.8,;Y軸最上面的坐標(biāo)值為1.0,,最下面的坐標(biāo)值為-1.0 GlSurfaceView上的所有3D圖形都是由Renderer的onDrawFrame(GL10 gl)方法繪制出來的,重寫該方法時(shí)就要把所有的3D圖形都繪制出來,,該方法通常如下形式開始: gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); ...接下來在onDrawFrame方法中就可以調(diào)用GL10的方法開始繪制了。 繪制平面上的多邊形 調(diào)用GL10圖形繪制2D圖形的步驟如下: (1)調(diào)用GL10的glEnableClientState(GL10.GL_VERTEX_ARRAY),;方法啟用頂點(diǎn)坐標(biāo)數(shù)組,。 (2)調(diào)用GL10的glEnableClientState(GL10.GL_COLOR_ARRAY);方法啟用頂點(diǎn)顏色數(shù)組,。 (3)調(diào)用GL10的glVertexPointer(int size, int type, int stride, Buffer pointer)方法 設(shè)置頂點(diǎn)的位置數(shù)據(jù),。這個(gè)方法中pointer參數(shù)用于指定頂點(diǎn)坐標(biāo)值,但這里并未使用三維數(shù)組來指定每個(gè)頂點(diǎn)X,、Y,、Z坐標(biāo)值,point依然是一個(gè)一維數(shù)組,,也就是該數(shù)組將會(huì)包含3N個(gè)數(shù)值,,每三個(gè)值指定一個(gè)頂點(diǎn)的X、Y,、Z坐標(biāo)值,。 第一個(gè)參數(shù)size指定多少個(gè)元素指定一個(gè)頂點(diǎn)位置,該size參數(shù)通??偸?,;type參數(shù)指定頂點(diǎn)值的類型,如果頂點(diǎn)坐標(biāo)值為float類型,,則指定為GL10.GL_FLOAT,;如果頂點(diǎn)坐標(biāo)值為整數(shù),則指定為GL10.GL_FIXED. (4)調(diào)用GL10的glColorPoint(int size, int type, int stride, Buffer pointer)方法設(shè)置頂點(diǎn)的顏色數(shù)據(jù)。 point依然是一維數(shù)組,,每四個(gè)值指定一個(gè)頂點(diǎn)的紅,、綠、藍(lán),、透明度的顏色值,。第一個(gè)參數(shù)size指定多少個(gè)元素指定一個(gè)頂點(diǎn)位置,該size參數(shù)通??偸?,, type參數(shù)指定頂點(diǎn)坐標(biāo)值的類型,如果頂點(diǎn)坐標(biāo)值為float類型,,則指定為GL10.GL_FLOAT,;如果頂點(diǎn)坐標(biāo)值為整數(shù),則指定為GL10.GL_FIXED. (5),調(diào)用GL10的glDrawArrays(int mode, int first, int count)方法繪制平面,,該方法第一個(gè)參數(shù)用于指定繪制圖形的類型,,第二個(gè)參數(shù)指定從哪個(gè)頂點(diǎn)開始繪制,第三個(gè)參數(shù)指定總共繪制的頂點(diǎn)數(shù)量,。 (6),,繪制完成后,調(diào)用GL10的glFinish()方法結(jié)束繪制,;并調(diào)用glDisableClientState(int)方法來停用頂點(diǎn)坐標(biāo)數(shù)據(jù),、頂點(diǎn)顏色數(shù)據(jù)。 http://www./topics/0/203/203273.html |
|