Android應(yīng)用:3D圓柱體
總共三個(gè)類
package?wyf.lgz;
import?java.nio.ByteBuffer;
import?java.nio.ByteOrder;
import?java.nio.FloatBuffer;
import?java.util.ArrayList;
import?javax.microedition.khronos.opengles.GL10;
public?class?DrawCylinder
{
private?FloatBuffer?myVertexBuffer;//頂點(diǎn)坐標(biāo)緩沖?
private?FloatBuffer?myNormalBuffer;//法向量緩沖
private?FloatBuffer?myTexture;//紋理緩沖
int?textureId;
int?vCount;//頂點(diǎn)數(shù)量
float?length;//圓柱長度
float?circle_radius;//圓截環(huán)半徑
float?degreespan;??//圓截環(huán)每一份的度數(shù)大小
public?float?mAngleX;
public?float?mAngleY;
public?float?mAngleZ;
public?DrawCylinder(float?length,float?circle_radius,float?degreespan,int?textureId)
{
this.circle_radius=circle_radius;
this.length=length;
this.degreespan=degreespan;
this.textureId=textureId;
float?collength=(float)length;//圓柱每塊所占的長度
int?spannum=(int)(360.0f/degreespan);
ArrayListval=new?ArrayList();//頂點(diǎn)存放列表
ArrayListial=new?ArrayList();//法向量存放列表
for(float?circle_degree=180.0f;circle_degree>0.0f;circle_degree-=degreespan)//循環(huán)行
{
float?x1?=(float)(-length/2);
float?y1=(float)?(circle_radius*Math.sin(Math.toRadians(circle_degree)));
float?z1=(float)?(circle_radius*Math.cos(Math.toRadians(circle_degree)));
float?a1=0;
float?b1=y1;
float?c1=z1;
float?l1=getVectorLength(a1,?b1,?c1);//模長
a1=a1/l1;//法向量規(guī)格化
b1=b1/l1;
c1=c1/l1;
float?x2?=(float)(-length/2);
float?y2=(float)?(circle_radius*Math.sin(Math.toRadians(circle_degree-degreespan)));
float?z2=(float)?(circle_radius*Math.cos(Math.toRadians(circle_degree-degreespan)));
float?a2=0;
float?b2=y2;
float?c2=z2;
float?l2=getVectorLength(a2,?b2,?c2);//模長
a2=a2/l2;//法向量規(guī)格化
b2=b2/l2;
c2=c2/l2;
float?x3?=(float)(length/2);
float?y3=(float)?(circle_radius*Math.sin(Math.toRadians(circle_degree-degreespan)));
float?z3=(float)?(circle_radius*Math.cos(Math.toRadians(circle_degree-degreespan)));
float?a3=0;
float?b3=y3;
float?c3=z3;
float?l3=getVectorLength(a3,?b3,?c3);//模長
a3=a3/l3;//法向量規(guī)格化
b3=b3/l3;
c3=c3/l3;
float?x4?=(float)(length/2);
float?y4=(float)?(circle_radius*Math.sin(Math.toRadians(circle_degree)));
float?z4=(float)?(circle_radius*Math.cos(Math.toRadians(circle_degree)));
float?a4=0;
float?b4=y4;
float?c4=z4;
float?l4=getVectorLength(a4,?b4,?c4);//模長
a4=a4/l4;//法向量規(guī)格化
b4=b4/l4;
c4=c4/l4;
val.add(x1);val.add(y1);val.add(z1);//兩個(gè)三角形,共6個(gè)頂點(diǎn)的坐標(biāo)
val.add(x2);val.add(y2);val.add(z2);
val.add(x4);val.add(y4);val.add(z4);
val.add(x2);val.add(y2);val.add(z2);
val.add(x3);val.add(y3);val.add(z3);
val.add(x4);val.add(y4);val.add(z4);
ial.add(a1);ial.add(b1);ial.add(c1);//頂點(diǎn)對應(yīng)的法向量
ial.add(a2);ial.add(b2);ial.add(c2);
ial.add(a4);ial.add(b4);ial.add(c4);
ial.add(a2);ial.add(b2);ial.add(c2);
ial.add(a3);ial.add(b3);ial.add(c3);
ial.add(a4);ial.add(b4);ial.add(c4);
}
?
vCount=val.size()/3;//確定頂點(diǎn)數(shù)量
//頂點(diǎn)
float[]?vertexs=new?float[vCount*3];
for(int?i=0;i<vCount*3;i++)
{
vertexs[i]=val.get(i);
}
ByteBuffer?vbb=ByteBuffer.allocateDirect(vertexs.length*4);
vbb.order(ByteOrder.nativeOrder());
myVertexBuffer=vbb.asFloatBuffer();
myVertexBuffer.put(vertexs);
myVertexBuffer.position(0);
//法向量
float[]?normals=new?float[vCount*3];
for(int?i=0;i<vCount*3;i++)
{
normals[i]=ial.get(i);
}
ByteBuffer?ibb=ByteBuffer.allocateDirect(normals.length*4);
ibb.order(ByteOrder.nativeOrder());
myNormalBuffer=ibb.asFloatBuffer();
myNormalBuffer.put(normals);
myNormalBuffer.position(0);
//紋理
float[]?textures=generateTexCoor(spannum);
ByteBuffer?tbb=ByteBuffer.allocateDirect(textures.length*4);
tbb.order(ByteOrder.nativeOrder());
myTexture=tbb.asFloatBuffer();
myTexture.put(textures);
myTexture.position(0);
}
public?void?drawSelf(GL10?gl)
{
gl.glRotatef(mAngleX,?1,?0,?0);//旋轉(zhuǎn)
gl.glRotatef(mAngleY,?0,?1,?0);
gl.glRotatef(mAngleZ,?0,?0,?1);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//打開頂點(diǎn)緩沖
gl.glVertexPointer(3,?GL10.GL_FLOAT,?0,?myVertexBuffer);//指定頂點(diǎn)緩沖
gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);//打開法向量緩沖
gl.glNormalPointer(GL10.GL_FLOAT,?0,?myNormalBuffer);//指定法向量緩沖
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexCoordPointer(2,?GL10.GL_FLOAT,?0,?myTexture);
gl.glBindTexture(GL10.GL_TEXTURE_2D,?textureId);
gl.glDrawArrays(GL10.GL_TRIANGLES,?0,?vCount);//繪制圖像
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);//關(guān)閉緩沖
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GL10.GL_NORMAL_ARRAY);
}
//法向量規(guī)格化,求模長度
public?float?getVectorLength(float?x,float?y,float?z)
{
float?pingfang=x*x+y*y+z*z;
float?length=(float)?Math.sqrt(pingfang);
return?length;
}
????//自動切分紋理產(chǎn)生紋理數(shù)組的方法
????public?float[]?generateTexCoor(int?bh)
????{
???? float[]?result=new?float[bh*6*2];?
???? float?REPEAT=2;
???? float?sizeh=1.0f/bh;//行數(shù)
???? int?c=0;
???? for(int?i=0;i<bh;i++)
???? {
???? //每行列一個(gè)矩形,由兩個(gè)三角形構(gòu)成,共六個(gè)點(diǎn),12個(gè)紋理坐標(biāo)
???? float?t=i*sizeh;
????
???? result[c++]=0;
???? result[c++]=t;
????
???? result[c++]=0;
???? result[c++]=t+sizeh;?
????
???? result[c++]=REPEAT;
???? result[c++]=t;
???? ???
???? result[c++]=0;
???? result[c++]=t+sizeh;
????
???? result[c++]=REPEAT;
???? result[c++]=t+sizeh;???
????
???? result[c++]=REPEAT;
???? result[c++]=t;
???? }
???? return?result;
????}
}package?wyf.lgz;
import?android.app.Activity;
import?android.content.pm.ActivityInfo;
import?android.os.Bundle;
import?android.view.Window;
import?android.view.WindowManager;
public?class?Activity_GL_Cylinder?extends?Activity?{
private?MyGLSurfaceView?mGLSurfaceView;
????/**?Called?when?the?activity?is?first?created.?*/
????@Override
????public?void?onCreate(Bundle?savedInstanceState)?{
????????super.onCreate(savedInstanceState);
????????
????????requestWindowFeature(Window.FEATURE_NO_TITLE);
????????getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,?WindowManager.LayoutParams.FLAG_FULLSCREEN);
????????setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
????????
????????mGLSurfaceView?=?new?MyGLSurfaceView(this);
????????setContentView(mGLSurfaceView);
????????mGLSurfaceView.setFocusableInTouchMode(true);//設(shè)置為可觸控
????????mGLSurfaceView.requestFocus();//獲取焦點(diǎn)
????}
????
????@Override
????protected?void?onResume()?{
????????super.onResume();
????????mGLSurfaceView.onResume();
????}
????@Override
????protected?void?onPause()?{
????????super.onPause();
????????mGLSurfaceView.onPause();
????}???
}package?wyf.lgz;
import?java.io.IOException;
import?java.io.InputStream;
import?android.opengl.GLSurfaceView;
import?android.opengl.GLUtils;
import?javax.microedition.khronos.egl.EGLConfig;
import?javax.microedition.khronos.opengles.GL10;
import?javax.microedition.khronos.opengles.GL11;
import?android.content.Context;
import?android.graphics.Bitmap;
import?android.graphics.BitmapFactory;
import?android.view.MotionEvent;
public?class?MyGLSurfaceView?extends?GLSurfaceView?{
????private?final?float?TOUCH_SCALE_FACTOR?=?180.0f/320;//角度縮放比例
????private?SceneRenderer?mRenderer;//場景渲染器
????private?float?mPreviousY;//上次的觸控位置Y坐標(biāo)
????private?float?mPreviousX;//上次的觸控位置Y坐標(biāo)
private?int?lightAngle=90;//燈的當(dāng)前角度
public?MyGLSurfaceView(Context?context)?{
????????super(context);
????????mRenderer?=?new?SceneRenderer(); //創(chuàng)建場景渲染器
????????setRenderer(mRenderer); //設(shè)置渲染器
????????setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//設(shè)置渲染模式為主動渲染???
????}???
???
????//觸摸事件回調(diào)方法?
????@Override?
????public?boolean?onTouchEvent(MotionEvent?e)?{
????????float?y?=?e.getY();
????????float?x?=?e.getX();
????????switch?(e.getAction())?{
????????case?MotionEvent.ACTION_MOVE:
????????????float?dy?=?y?-?mPreviousY;//計(jì)算觸控筆Y位移
????????????float?dx?=?x?-?mPreviousX;//計(jì)算觸控筆Y位移
????????????mRenderer.cylinder.mAngleX?+=?dy?*?TOUCH_SCALE_FACTOR;//設(shè)置沿x軸旋轉(zhuǎn)角度
????????????mRenderer.cylinder.mAngleZ?+=?dx?*?TOUCH_SCALE_FACTOR;//設(shè)置沿z軸旋轉(zhuǎn)角度
????????????requestRender();//重繪畫面
????????}
????????mPreviousY?=?y;//記錄觸控筆位置
????????mPreviousX?=?x;//記錄觸控筆位置
????????return?true;
????}
private?class?SceneRenderer?implements?GLSurfaceView.Renderer?
????{???
int?textureId;//紋理名稱ID
???? DrawCylinder?cylinder;//創(chuàng)建圓柱體
???? public?SceneRenderer()
???? {
???? }
????
????????public?void?onDrawFrame(GL10?gl)?{????????????????
???????? //清除顏色緩存
???????? gl.glClear(GL10.GL_COLOR_BUFFER_BIT?|?GL10.GL_DEPTH_BUFFER_BIT);
???????? //設(shè)置當(dāng)前矩陣為模式矩陣
????????????gl.glMatrixMode(GL10.GL_MODELVIEW);
????????????//設(shè)置當(dāng)前矩陣為單位矩陣
????????????gl.glLoadIdentity();?????
??????????????????
????????????gl.glPushMatrix();//保護(hù)變換矩陣現(xiàn)場
????????????
???????? float?lx=0;?//設(shè)定光源的位置
????????????float?ly=(float)(7*Math.cos(Math.toRadians(lightAngle)));
???????? float?lz=(float)(7*Math.sin(Math.toRadians(lightAngle)));
????????????float[]?positionParamsRed={lx,ly,lz,0};
????????????gl.glLightfv(GL10.GL_LIGHT1,?GL10.GL_POSITION,?positionParamsRed,0);????
????????????
????????????initMaterial(gl);//初始化紋理
????????????gl.glTranslatef(0,?0,?-10f);//平移
????????????initLight(gl);//開燈
????????????cylinder.drawSelf(gl);//繪制
????????????closeLight(gl);//關(guān)燈
????????????
????????????gl.glPopMatrix();//恢復(fù)變換矩陣現(xiàn)場
????????}
????????public?void?onSurfaceChanged(GL10?gl,?int?width,?int?height)?{
????????????//設(shè)置視窗大小及位置?
???????? gl.glViewport(0,?0,?width,?height);
???????? //設(shè)置當(dāng)前矩陣為投影矩陣
????????????gl.glMatrixMode(GL10.GL_PROJECTION);
????????????//設(shè)置當(dāng)前矩陣為單位矩陣
????????????gl.glLoadIdentity();
????????????//計(jì)算透視投影的比例
????????????float?ratio?=?(float)?width?/?height;
????????????//調(diào)用此方法計(jì)算產(chǎn)生透視投影矩陣
????????????gl.glFrustumf(-ratio,?ratio,?-1,?1,?1,?100);
????????}
????????public?void?onSurfaceCreated(GL10?gl,?EGLConfig?config)?{
????????????//關(guān)閉抗抖動?
???????? gl.glDisable(GL10.GL_DITHER);
???????? //設(shè)置特定Hint項(xiàng)目的模式,這里為設(shè)置為使用快速模式
????????????gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);
????????????//設(shè)置屏幕背景色黑色RGBA
????????????gl.glClearColor(0,0,0,0);
????????????//設(shè)置著色模型為平滑著色???
????????????gl.glShadeModel(GL10.GL_SMOOTH);
????????????//啟用深度測試
????????????gl.glEnable(GL10.GL_DEPTH_TEST);
?????????????
????????????textureId=initTexture(gl,R.drawable.stone);//紋理ID
????????????cylinder=new?DrawCylinder(10f,2f,18f,textureId);//創(chuàng)建圓柱體
????????????
//????????????//開啟一個(gè)線程自動旋轉(zhuǎn)光源
//????????????new?Thread()
//????????????{
//?????????? ??public?void?run()
//?????????? ??{
//?????????? ??while(true)
//?????????? ??{
//?????????? lightAngle+=5;//轉(zhuǎn)動燈
//?????????? mRenderer.cylinder.mAngleY+=2*TOUCH_SCALE_FACTOR;//球沿Y軸轉(zhuǎn)動
//????????????????????requestRender();//重繪畫面
//????????????????????try
//????????????????????{
//?????????????????? ??Thread.sleep(50);//休息10ms再重繪
//????????????????????}
//????????????????????catch(Exception?e)
//????????????????????{
//?????????????????? ??e.printStackTrace();
//????????????????????}???????? ??
//?????????? ??}
//?????????? ??}
//????????????}.start();
????????}
????}
//初始化白色燈
private?void?initLight(GL10?gl)
{????
????????gl.glEnable(GL10.GL_LIGHTING);//允許光照????
????????gl.glEnable(GL10.GL_LIGHT1);//打開1號燈??
????????
????????//環(huán)境光設(shè)置
????????float[]?ambientParams={0.2f,0.2f,0.2f,1.0f};//光參數(shù)?RGBA
????????gl.glLightfv(GL10.GL_LIGHT1,?GL10.GL_AMBIENT,?ambientParams,0);????????????
????????
????????//散射光設(shè)置
????????float[]?diffuseParams={1f,1f,1f,1.0f};//光參數(shù)?RGBA
????????gl.glLightfv(GL10.GL_LIGHT1,?GL10.GL_DIFFUSE,?diffuseParams,0);?
????????
????????//反射光設(shè)置
????????float[]?specularParams={1f,1f,1f,1.0f};//光參數(shù)?RGBA
????????gl.glLightfv(GL10.GL_LIGHT1,?GL10.GL_SPECULAR,?specularParams,0);?
}
//關(guān)閉燈
private?void?closeLight(GL10?gl)
{
gl.glDisable(GL10.GL_LIGHT1);
gl.glDisable(GL10.GL_LIGHTING);
}
//初始化材質(zhì)
private?void?initMaterial(GL10?gl)
{
????????//環(huán)境光
????????float?ambientMaterial[]?=?{248f/255f,?242f/255f,?144f/255f,?1.0f};
????????gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,?GL10.GL_AMBIENT,?ambientMaterial,0);
????????//散射光
????????float?diffuseMaterial[]?=?{248f/255f,?242f/255f,?144f/255f,?1.0f};
????????gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,?GL10.GL_DIFFUSE,?diffuseMaterial,0);
????????//高光材質(zhì)
????????float?specularMaterial[]?=?{248f/255f,?242f/255f,?144f/255f,?1.0f};
????????gl.glMaterialfv(GL10.GL_FRONT_AND_BACK,?GL10.GL_SPECULAR,?specularMaterial,0);
????????gl.glMaterialf(GL10.GL_FRONT_AND_BACK,?GL10.GL_SHININESS,?100.0f);
}
//初始化紋理
public?int?initTexture(GL10?gl,int?drawableId)//textureId
{
//生成紋理ID
int[]?textures?=?new?int[1];
gl.glGenTextures(1,?textures,?0);????
int?currTextureId=textures[0];????
gl.glBindTexture(GL10.GL_TEXTURE_2D,?currTextureId);
gl.glTexParameterf(GL10.GL_TEXTURE_2D,?GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR_MIPMAP_NEAREST);
????????gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR_MIPMAP_LINEAR);
????????((GL11)gl).glTexParameterf(GL10.GL_TEXTURE_2D,?GL11.GL_GENERATE_MIPMAP,?GL10.GL_TRUE);
????????gl.glTexParameterf(GL10.GL_TEXTURE_2D,?GL10.GL_TEXTURE_WRAP_S,GL10.GL_REPEAT);
????????gl.glTexParameterf(GL10.GL_TEXTURE_2D,?GL10.GL_TEXTURE_WRAP_T,GL10.GL_REPEAT);
????????
????????
????????
????????InputStream?is?=?this.getResources().openRawResource(drawableId);
????????Bitmap?bitmapTmp;?
????????try?
????????{
???????? bitmapTmp?=?BitmapFactory.decodeStream(is);
????????}?
????????finally?
????????{
????????????try?
????????????{
????????????????is.close();
????????????}?
????????????catch(IOException?e)?
????????????{
????????????????e.printStackTrace();
????????????}
????????}
????????GLUtils.texImage2D(GL10.GL_TEXTURE_2D,?0,?bitmapTmp,?0);
????????bitmapTmp.recycle();?
????????
????????return?currTextureId;
}
}




