Android開發(fā)之繪制平面上的多邊形功能分析
本文實(shí)例講述了Android開發(fā)之繪制平面上的多邊形功能。分享給大家供大家參考,具體如下:
計(jì)算機(jī)里的3D圖形其實(shí)是由很多個(gè)平面組合而成的。所謂“繪制3D”圖形,其實(shí)是通過多個(gè)平面圖形形成的。調(diào)用GL10圖形繪制2D圖形的步驟如下:
i. 調(diào)用GL10的glEnableClientState(GL10.GL_VERTEX_ARRAY);方法啟用頂點(diǎn)坐標(biāo)數(shù)組。
ii. 調(diào)用GL10的glEnableClientState(GL10.GL_COLOR_ARRAY);方法啟用頂點(diǎn)顏色數(shù)組。
iii. 調(diào)用GL10的glVertex (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)的值,pointer依然是一個(gè)一維數(shù)組,其格式為(x1,y1,z1,x2,y2,z2,x3,y3,z3…xN,yN,zN);也就是說該數(shù)組里將會(huì)包含3N個(gè)數(shù)值,每三個(gè)值指定一個(gè)頂點(diǎn)的X、Y、Z坐標(biāo)值的類型,如果頂點(diǎn)坐標(biāo)值為float類型,則指定為GL10.GL_FLOAT;如果頂點(diǎn)坐標(biāo)值為整數(shù),則指定為GL10.GL_FIXED。
iv. 調(diào)用GL10的glColorPointer(int size,int type,int stride,Buffer pointer)方法設(shè)置頂點(diǎn)的顏色數(shù)據(jù)。這個(gè)方法中pointer參數(shù)用于指定頂點(diǎn)的顏色值,pointer依然是一個(gè)一維數(shù)組,,其格式為(r1,g1,b1,a1,x2,y2,z2,a2,x3,y3,z3,a3…xN,yN,zN,aN);也就是該數(shù)組里將會(huì)包含4N個(gè)數(shù)值,每4個(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。
v. 調(diào)用GL10的glDrawArrays(int mode,int first,int count)方法繪制平面。該方法的第一個(gè)參數(shù)用于指定繪制圖形類型,第二個(gè)參數(shù)指定從哪個(gè)頂點(diǎn)開始繪制,第三個(gè)參數(shù)指定總共繪制的定點(diǎn)數(shù)量。
vi. 繪制完成后,調(diào)用GL10的glFinish()方法結(jié)束繪制;并調(diào)用glDisableClientState(int)方法來停用頂點(diǎn)坐標(biāo)數(shù)據(jù),頂點(diǎn)顏色數(shù)據(jù)。
掌握上面的步驟之后,接下來通過示例程序來繪制幾個(gè)簡(jiǎn)單的圖形。
public class MyRenderer implements Renderer
{
float[] triangleData = new float []{
0.1f,0.6f,0.0f,//上頂點(diǎn)
-0.3f,0.0f,0.0f,//左頂點(diǎn)
0.3f,0.1f,0.0f//右頂點(diǎn)
};
int[] triangleColor = new int []{
65535,0,0,0,//上頂點(diǎn)紅色
0,65535,0,0,//左頂點(diǎn)綠色
0,0,65535,0//右頂點(diǎn)藍(lán)色
};
float[] rectData = new float[]{
0.4f,0.4f,0.0f,//右上頂點(diǎn)
0.4f,-0.4f,0.0f,//右下頂點(diǎn)
-0.4f,0.4f,0.0f,//左上頂點(diǎn)
-0.4f,-0.4f,0.0f//左下頂點(diǎn)
};
int[] rectColor = new int []{
0,65535,0,0,//右上頂點(diǎn)綠色
0,0,65535,0,//右下頂點(diǎn)藍(lán)色
65535,0,0,0,//左上頂點(diǎn)紅色
65535,65535,0,0//左下頂點(diǎn)黃色
};
float[] rectData2 = new float[]{
-0.4f,0.4f,0.0f,//左上頂點(diǎn)
0.4f,0.4f,0.0f,
0.4f,-0.4f,0.0f,
-0.4f,-0.4f,0.0f
rectColorBuffer };
float[] pentacle = new float[]{
0.4f,0.4f,0.0f,
-0.2f,0.3f,0.0f,
0.5f,0.0f,0f,
-0.4f,0.0f,0f
-0.1f,-0.3f,0f
};
FloatBuffer triangleDataBuffer;
IntBuffer triangleColorBuffer;
FloatBuffer rectDataBuffer;
FloatBuffer rectDataBuffer2;
FloatBuffer pentacleBuffer;
IntBuffer rectDataBuffer;
public MyRenderer()
{
//將頂點(diǎn)位置數(shù)據(jù)數(shù)組包裝成FloatBuffer;
triangleDataBuffer = FloatBuffer.wrap(triangleData);
rectDataBuffer =FloatBuffer.wrap(rectData);
rectDataBuffer2 =FloatBuffer.wrap(rectData2);
pentacleBuffer = FloatBuffer.wrap(pentacle);
//將頂點(diǎn)顏色數(shù)據(jù)數(shù)組包裝成IntBuffer;
triangleColorBuffer=IntBuffer.wrap(triangleColor);
rectColorBuffer= IntBuffer.wrap(rectColor);
};
//關(guān)閉抗抖動(dòng)
gl.glDisable(GL10.GL_DITHER);
//設(shè)置系對(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);
}
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,1,1,10);
}
public void onDrawFrame(GL10 gl)
{
//清除屏幕緩存和深度緩存
gl.glClear(GL10.GL_COLOR_BUFFER_BIT|GL10.GL_DEPTH_BUFFER_BIT);
//啟用頂點(diǎn)坐標(biāo)數(shù)據(jù)
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
//啟用頂點(diǎn)顏色數(shù)據(jù)
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
//設(shè)置當(dāng)前矩陣堆棧為模型堆棧
gl.glMatrixMode(GL10.GL_MODELVIEW);
//繪制第一個(gè)圖形,重置當(dāng)前的模型視圖矩陣
gl.glLoadIdentity();
gl.glTranslatef(-0.32f, 0.35f, -1f);
//設(shè)置頂點(diǎn)的位置數(shù)據(jù)
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleDataBuffer);
//設(shè)置頂點(diǎn)的顏色數(shù)據(jù)
gl.glColorPointer(4, GL10.GL_FIXED, 0, triangleColorBuffer);
//根據(jù)頂點(diǎn)數(shù)據(jù)繪制平面圖形
gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
//繪制第二個(gè)圖形
gl.glLoadIdentity();
gl.glTranslatef(0.6f, 0.8f, -1.5f);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, rectDataBuffer);
gl.glColorPointer(4, GL10.GL_FIXED, 0, rectColorBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4);
//繪制第三個(gè)圖形
gl.glLoadIdentity();
gl.glTranslatef(-0.4f, -0.5f, -1.5f);
gl.glVertexPointer(3,GL10.GL_FLOAT, 0, rectDataBuffer2);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,4);
//
gl.glLoadIdentity();
gl.glTranslatef(0.4f, -0.5f, -1.5f);
//設(shè)置使用純色填充
gl.glColor4f(1.0f,0.2f,0.2f,0.0f);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0,penTacleBuffer);
gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP,0,5);
//繪制結(jié)束
gl.glFinish();
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
}
上面的程序使用GL10繪制圖形的關(guān)鍵代碼:加載頂點(diǎn)位置數(shù)據(jù);加載頂點(diǎn)顏色數(shù)據(jù);調(diào)用GL10的glDrawArrays繪制。
在Activity中定義一個(gè)GLSurfaceView,并使用上面的Renderer進(jìn)行繪制,程序如下:
public void Polygon extends Activity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//創(chuàng)建一個(gè)GLSurfaceView,用于顯示OpenGL繪制的圖形
GLSurfaceView glView = new GLSurfaceView(this);
//創(chuàng)建GLSurfaceView的內(nèi)容繪制器
MyRenderer myRender = new MyRenderer();
//為GLSurfaceView設(shè)置繪制器
glView.setRenderer(myRender);
setContentView(glView);
}
}
可能大家會(huì)覺得奇怪,為什么第二個(gè)和第三個(gè)圖形只是定義4個(gè)坐標(biāo)點(diǎn)的順序略有不同,為什么圖形的差異這么大呢?應(yīng)為glDrawArrays方法第一個(gè)參數(shù)指定繪制的模式,GL10.GL_TRIANGLES是繪制三角形, GL10.GL_TRIANGLE_STRIP是用多個(gè)三角形來繪制多邊形。
對(duì)于第2個(gè)圖形,當(dāng)調(diào)用glDrawArrays(int mode,int first,int count )方法時(shí),若指定第一個(gè)參數(shù)是GL10.GL_TRIANGLE_STRIP時(shí),系統(tǒng)總會(huì)從first個(gè)頂點(diǎn)開始,每3個(gè)頂點(diǎn)繪制一個(gè)三角形。
更多關(guān)于Android相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Android圖形與圖像處理技巧總結(jié)》、《Android開發(fā)入門與進(jìn)階教程》、《Android調(diào)試技巧與常見問題解決方法匯總》、《Android基本組件用法總結(jié)》、《Android視圖View技巧總結(jié)》、《Android布局layout技巧總結(jié)》及《Android控件用法總結(jié)》
希望本文所述對(duì)大家Android程序設(shè)計(jì)有所幫助。
相關(guān)文章
Android應(yīng)用中使用ListView來分頁(yè)顯示刷新的內(nèi)容
這篇文章主要介紹了Android應(yīng)用中使用ListView來分頁(yè)顯示刷新的內(nèi)容的方法,展示了一個(gè)點(diǎn)擊按鈕進(jìn)行刷新的實(shí)例以及下拉刷新分頁(yè)顯示的要點(diǎn)解析,需要的朋友可以參考下2016-04-04
AndroidStudio接入U(xiǎn)nity工程并實(shí)現(xiàn)相互跳轉(zhuǎn)的示例代碼
這篇文章主要介紹了AndroidStudio接入U(xiǎn)nity工程并實(shí)現(xiàn)相互跳轉(zhuǎn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
Android 簡(jiǎn)單實(shí)現(xiàn)一個(gè)流式布局的示例
本篇文章主要介紹了Android 簡(jiǎn)單實(shí)現(xiàn)一個(gè)流式布局的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02
Android5.x中的陰影效果elevation和translationZ的實(shí)現(xiàn)方法
這篇文章主要介紹了 android5.x中的陰影效果elevation和translationZ的相關(guān)資料,需要的朋友可以參考下2016-12-12
關(guān)于Android高德地圖的簡(jiǎn)單開發(fā)實(shí)例代碼(DEMO)
高德地圖在日常生活中經(jīng)常會(huì)用到,那么基于代碼如何實(shí)現(xiàn)高德地圖呢?下面小編給大家分享一個(gè)demo幫助大家學(xué)習(xí)android高德地圖的簡(jiǎn)單開發(fā),需要的朋友參考下2016-11-11
android尺子的自定義view——RulerView詳解
這篇文章主要介紹了android尺子的自定義view——RulerView詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Android通過AIDL在兩個(gè)APP之間Service通信
這篇文章主要為大家詳細(xì)介紹了Android通過AIDL在兩個(gè)APP之間Service通信,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Android獲取點(diǎn)擊屏幕的位置坐標(biāo)
這篇文章主要為大家詳細(xì)介紹了Android獲取點(diǎn)擊屏幕的位置坐標(biāo),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Android Activity與Service通信(不同進(jìn)程之間)詳解
這篇文章主要介紹了Android Activity與Service通信(不同進(jìn)程之間)的相關(guān)資料,這里提供了三種方法,需要的朋友可以參考下2016-10-10

