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;//圓柱長(zhǎng)度 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;//圓柱每塊所占的長(zhǎng)度 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);//模長(zhǎng) 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);//模長(zhǎng) 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);//模長(zhǎng) 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);//模長(zhǎng) 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)對(duì)應(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);//打開(kāi)頂點(diǎn)緩沖 gl.glVertexPointer(3,?GL10.GL_FLOAT,?0,?myVertexBuffer);//指定頂點(diǎn)緩沖 gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);//打開(kāi)法向量緩沖 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ī)格化,求模長(zhǎng)度 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; } ????//自動(dòng)切分紋理產(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;//場(chǎng)景渲染器 ????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)建場(chǎng)景渲染器 ????????setRenderer(mRenderer); //設(shè)置渲染器 ????????setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//設(shè)置渲染模式為主動(dòng)渲染??? ????}??? ??? ????//觸摸事件回調(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();//重繪畫(huà)面 ????????} ????????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)場(chǎng) ???????????? ???????? 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);//開(kāi)燈 ????????????cylinder.drawSelf(gl);//繪制 ????????????closeLight(gl);//關(guān)燈 ???????????? ????????????gl.glPopMatrix();//恢復(fù)變換矩陣現(xiàn)場(chǎng) ????????} ????????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)閉抗抖動(dòng)? ???????? 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); ????????????//啟用深度測(cè)試 ????????????gl.glEnable(GL10.GL_DEPTH_TEST); ????????????? ????????????textureId=initTexture(gl,R.drawable.stone);//紋理ID ????????????cylinder=new?DrawCylinder(10f,2f,18f,textureId);//創(chuàng)建圓柱體 ???????????? //????????????//開(kāi)啟一個(gè)線程自動(dòng)旋轉(zhuǎn)光源 //????????????new?Thread() //????????????{ //?????????? ??public?void?run() //?????????? ??{ //?????????? ??while(true) //?????????? ??{ //?????????? lightAngle+=5;//轉(zhuǎn)動(dòng)燈 //?????????? mRenderer.cylinder.mAngleY+=2*TOUCH_SCALE_FACTOR;//球沿Y軸轉(zhuǎn)動(dòng) //????????????????????requestRender();//重繪畫(huà)面 //????????????????????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);//打開(kāi)1號(hào)燈?? ???????? ????????//環(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; } }