編輯:關於Android編程
之前的博客中,我們繪制了三角形、正方形、圓形、立方體,今天我們將繪制圓錐、圓柱和球體。能夠繪制這些基本的常規幾何形體後,其他的常見幾何形體的繪制對於我們來說就基本沒問題了。
由之前的博客,我們大家也應該都知道了,OpenGL ES2.0中物體的繪制重點就是在於把這個物體表面分解成三角形,分解成功後,繪制自然就不成問題了。圓錐我們很容易就能想到把它拆解成一個圓形和一個錐面,錐面的頂點與圓形的頂點,除了錐面的中心點的坐標有了“高度”,其他的完全相同。圓形在Android OpenGLES2.0(四)——正方形和圓形中我們已經繪制過,那麼錐面其實對於我們來說也是小case了:
ArrayList<float> pos=new ArrayList<>(); pos.add(0.0f); pos.add(0.0f); pos.add(height); //給圓心相對圓邊增加高度,使之形成錐面 float angDegSpan=360f/n; for(float i=0;i<360+angDegSpan;i+=angDegSpan){ pos.add((float) (radius*Math.sin(i*Math.PI/180f))); pos.add((float)(radius*Math.cos(i*Math.PI/180f))); pos.add(0.0f); } float[] d=new float[pos.size()]; //所有的頂點 for (int i=0;i<d.length;i++){ pre="">
我們按照繪制圓形的方式,繪制出錐面,然後再在這個錐面的底部繪制一個圓形,這樣我們就得到了一個圓錐了:
從圖中我們可以看到,我們繪制的並不是同樣的顏色,如果使用同樣的顏色,很難看出圓錐的立體效果。這種顏色怎麼實現的呢?我們來看它的頂點著色器(片元著色器和之前相同):
uniform mat4 vMatrix; varying vec4 vColor; attribute vec4 vPosition; void main(){ gl_Position=vMatrix*vPosition; if(vPosition.z!=0.0){ vColor=vec4(0.0,0.0,0.0,1.0); }else{ vColor=vec4(0.9,0.9,0.9,1.0); } }
在頂點著色器中,並沒有傳入顏色,而是在程序中直接判斷進行賦值的,當然也有可以頂點顏色和定邊顏色由外面傳入。在著色器中,我們不再是簡單的賦值,而是加入了流程控制。在下一篇博客中將會專門講解我們使用的著色器語言GLSL——Android OpenGLES 2.0(七)——著色器語言GLSL。
圓柱的與圓錐類似,我們可以把圓柱拆解成上下兩個圓面,加上一個圓筒。圓筒我們之前也沒畫過,它怎麼拆解成三角形呢?我們可以如同拆圓的思路來理解圓柱,想想正三菱柱、正八菱柱、正一百菱柱……菱越多,就越圓滑與圓柱越接近了,然後再把每個菱面(矩形)拆解成兩個三角形就OK了,拆解的頂點為:
ArrayListpos=new ArrayList<>(); float angDegSpan=360f/n; for(float i=0;i<360+angDegSpan;i+=angDegSpan){ pos.add((float) (radius*Math.sin(i*Math.PI/180f))); pos.add((float)(radius*Math.cos(i*Math.PI/180f))); pos.add(height); pos.add((float) (radius*Math.sin(i*Math.PI/180f))); pos.add((float)(radius*Math.cos(i*Math.PI/180f))); pos.add(0.0f); } float[] d=new float[pos.size()]; for (int i=0;i 這樣我們就可以繪制出一個圓筒了,只需要在頂部繪制一個圓,底部繪制一個圓,就得到了一個圓柱了:
繪制球體
相對於圓錐圓柱來說,球體的拆解就復雜了許多,比較常見的拆解方法是將按照經緯度拆解和按照正多面體拆解,下圖分別為正多面體示意和經緯度拆解示意:
正多面體的方法拆解: 經緯度的方法拆解(每一個小塊看做一個矩形,再拆成三角形。PS:人懶,不想做圖。):由圖我們也能看出來,多面體雖然看起來好看點,但是還是按照經緯度的方式來拆解計算容易點,畢竟規律那麼明顯。
球上點的坐標
無論是按照經緯度拆還是按照多面體拆,都需要知道球上面點的坐標,這算是基本的幾何知識了。以球的中心為坐標中心,球的半徑為R的話,那麼球上點的坐標則為:
(R?cos(ψ)?sin(λ),R?sin(ψ),R?cos(ψ)?cos(λ)) 其中,ψ為圓心到點的線段與xz平面的夾角,λ為圓心到點的線段在xz平面的投影與z軸的夾角。用圖形表示如下:拆解頂點
按照經緯度方式拆解球體,得到球體的頂點數組:
ArrayList<float> data=new ArrayList<>(); float r1,r2; float h1,h2; float sin,cos; for(float i=-90;i<90+step;i+=step){ r1 = (float)Math.cos(i * Math.PI / 180.0); r2 = (float)Math.cos((i + step) * Math.PI / 180.0); h1 = (float)Math.sin(i * Math.PI / 180.0); h2 = (float)Math.sin((i + step) * Math.PI / 180.0); // 固定緯度, 360 度旋轉遍歷一條緯線 float step2=step*2; for (float j = 0.0f; j <360.0f+step; j +=step2 ) { cos = (float) Math.cos(j * Math.PI / 180.0); sin = -(float) Math.sin(j * Math.PI / 180.0); data.add(r2 * cos); data.add(h2); data.add(r2 * sin); data.add(r1 * cos); data.add(h1); data.add(r1 * sin); } } float[] f=new float[data.size()]; for(int i=0;i<f.length;i++){ pre=""
得到頂點後,剩下的工作就和之前繪制其他圖形一樣了。
如果繼續使用圓錐的著色器,我們會得到這樣一個球:
看起來都不太像個球了,要不是有條白線,這是不是個球就不好說了。我們需要修改下頂點著色器,讓它有立體感。把頂點著色器修改為:
uniform mat4 vMatrix; varying vec4 vColor; attribute vec4 vPosition; void main(){ gl_Position=vMatrix*vPosition; float color; if(vPosition.z>0.0){ color=vPosition.z; }else{ color=-vPosition.z; } vColor=vec4(color,color,color,1.0); }
運行一下,我們得到的運行結果如下,這樣才好意思說是個球嘛。
OK,繪制各種簡單的幾何物體到這裡就結束了,現在應該各種常規的幾何形體都攔不到我們了。後面開始講解其他內容了。 所有的代碼全部在一個項目中,托管在Github上——Android OpenGLES 2.0系列博客的Demo
android 在網絡上下載文件步驟 : 1.使用HTTP協議下載文件- 創建一個HttpURLConnection對象 : HttpURLConnection urlC
由於一個項目的需要,我研究了一下android的網絡通信方式,大體和java平台的很相似! android平台也提供了很多的API供開發者使用,請按示例圖:
1. 設置 2.定義變量 3.生成Setter/Getter 4.生成 5.結果
使用Eclipse開發Android已經有些年頭了,然而Android Studio(後面簡稱AS)為谷歌自己推的IDE。現在AS已經出了2.0版本,其功能的確要比Ecl