日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

《Android 应用案例开发大全(第3版)》——第2.4节壁纸的实现

發(fā)布時(shí)間:2024/3/26 Android 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《Android 应用案例开发大全(第3版)》——第2.4节壁纸的实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本節(jié)書摘來自異步社區(qū)《Android 應(yīng)用案例開發(fā)大全(第3版)》一書中的第2章,第2.4節(jié)壁紙的實(shí)現(xiàn),作者 吳亞峰 , 蘇亞光 , 于復(fù)興,更多章節(jié)內(nèi)容可以訪問云棲社區(qū)“異步社區(qū)”公眾號(hào)查看

2.4 壁紙的實(shí)現(xiàn)
上一節(jié)介紹了壁紙的框架,讓讀者對(duì)3D動(dòng)態(tài)壁紙的整體框架有了初步認(rèn)識(shí),本節(jié)將要對(duì)動(dòng)態(tài)壁紙的實(shí)現(xiàn)服務(wù)類GLWallpaperService和OpenGLES2WallpaperService以及自定義場(chǎng)景渲染器類MySurfaceView的開發(fā)進(jìn)行詳細(xì)介紹。

2.4.1 壁紙服務(wù)類——OpenGLES2WallpaperService
這兩個(gè)類是本項(xiàng)目中最基礎(chǔ)的類,沒有這兩個(gè)類就不可能使用壁紙。GLWallpaperService類為開發(fā)人員提供了壁紙服務(wù),OpenGLES2WallpaperService通過繼承GLWallpaperService類,重寫此類中的方法來實(shí)現(xiàn)壁紙的后續(xù)開發(fā)。下面著重介紹一下OpenGLES2WallpaperService類中的onCreate方法和GLWallpaperService類中的觸控響應(yīng)事件onTouchEvent。

(1)首先是OpenGLES2WallpaperService類中的onCreate方法,onCreate方法是OpenGLES2 WallpaperService類的核心部分,其中包括獲取當(dāng)前手機(jī)的配置信息,并且判斷其是否支持OPENGL ES2.0渲染技術(shù)等。具體代碼如下所示。

1 public void onCreate(SurfaceHolder surfaceHolder) { 2 super.onCreate(surfaceHolder); 3 final ActivityManager activityManager = //創(chuàng)建Activity管理器 4 (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 5 final ConfigurationInfo configurationInfo = //獲取當(dāng)前機(jī)器配置信息 6 activityManager.getDeviceConfigurationInfo(); 7 final boolean supportsEs2 = //獲取判斷結(jié)果 8 configurationInfo.reqGlEsVersion >= 0x20000; 9 if (supportsEs2) { 10 setEGLContextClientVersion(2); //設(shè)置使用OPENGL ES2.0 11 setPreserveEGLContextOnPause(true);//EGL跨越暫停/恢復(fù)界限來嘗試和保存環(huán)境 12 setRenderer(getNewRenderer()); //設(shè)置渲染器 13 } else {return;} 14 }

第3~8行用于創(chuàng)建Activity管理器,獲取配置信息,判斷當(dāng)前手機(jī)是否支持OPENGL ES2.0渲染技術(shù),并將結(jié)果存儲(chǔ)在supportsEs2中。
第9~13行用于判斷supportsEs2中的值,如果當(dāng)前手機(jī)支持OPENGL ES2.0渲染技術(shù),則設(shè)置使用OPENGL ES2.0進(jìn)行繪制,并且讓EGL跨越暫停或恢復(fù)界限來嘗試和保護(hù)環(huán)境,然后設(shè)置場(chǎng)景渲染器;如果不支持OPENGL ES2.0,則退出繪制。
(2)下面將對(duì)屏幕觸控的響應(yīng)事件進(jìn)行介紹。屏幕的觸控事件分為3部分:第一部分是滑動(dòng)屏幕使背景圖跟著屏幕左右移動(dòng),第二部分是點(diǎn)擊屏幕下方修改標(biāo)志位,最后一部分是手指抬起時(shí)判斷是否進(jìn)行喂食,具體代碼如下所示。

1 private float mPreviousY; //上次的觸控位置Y坐標(biāo) 2 private float mPreviousX; //上次的觸控位置X坐標(biāo) 3 @Override 4 public void onTouchEvent(MotionEvent e) { 5 float y = e.getY(); //獲取觸控點(diǎn)Y坐標(biāo) 6 float x = e.getX(); //獲取觸控點(diǎn)X坐標(biāo) 7 switch (e.getAction()) { 8 case MotionEvent.ACTION_DOWN: 9 Constant.feeding=true;break; //喂食標(biāo)志位設(shè)為true 10 case MotionEvent.ACTION_MOVE: 11 float dy = y - mPreviousY; //計(jì)算觸控筆Y位移 12 float dx = x - mPreviousX; //計(jì)算觸控筆X位移 13 if (dx < 0){ //摸左邊x為正,摸右邊x為負(fù) 14 if (Constant.CameraX <Constant.MaxCameraMove) { //判斷是否超出移動(dòng)范圍 15 if(dx<-Constant.Thold){ Constant.feeding = false; }//喂食標(biāo)志位置為false 16 Constant.CameraX = Constant.CameraX - dx / Constant.CameraMove_SCALE ; 17 Constant.TargetX=Constant.CameraX; //移動(dòng)攝像機(jī)的坐標(biāo) 18 }} else { 19 if (Constant.CameraX >-Constant.MaxCameraMove) { //判斷是否超出移動(dòng)范圍 20 if(dx>Constant.Thold){ Constant.feeding =false;} //喂食標(biāo)志位置為false 21 Constant.CameraX = Constant.CameraX - dx / Constant.CameraMove_SCALE ; 22 Constant.TargetX=Constant.CameraX; //移動(dòng)攝像機(jī)的坐標(biāo) 23 }} 24 MatrixState.setCamera( //將攝像機(jī)的位置信息存入到矩陣中 25 Constant.CameraX, Constant.CameraY, Constant.CameraZ,//攝像機(jī)的X、Y、Z位置 26 Constant.TargetX, Constant.TargetY, Constant.TargetZ,//觀測(cè)點(diǎn)的X、Y、Z位置 27 Constant.UpX, Constant.UpY, Constant.UpZ); //up向量的X、Y、Z分量 28 break; 29 case MotionEvent.ACTION_UP: 30 if (Constant.feeding) { //標(biāo)志位,開始喂食 31 if (Constant.isFeed) { 32 Constant.isFeed = false; //把標(biāo)志位置為false 33 float[] AB = IntersectantUtil.calculateABPosition( //通過矩陣變換獲取世界坐標(biāo)系中的點(diǎn) 34 x, y, //觸控點(diǎn)X、Y坐標(biāo) 35 Constant.SCREEN_WIDTH, Constant.SCREEN_HEGHT, //屏幕寬、長(zhǎng)度 36 Constant.leftABS, Constant.topABS, //視角left、top值 37 Constant.nearABS, Constant.farABS); //視角near、far值 38 Vector Start = new Vector(AB[0], AB[1], AB[2]); //起點(diǎn) 39 Vector End = new Vector(AB[3], AB[4], AB[5]); //終點(diǎn) 40 if (MySurfaceView.feedfish != null) { //判斷不為空啟動(dòng) 41 MySurfaceView.feedfish.startFeed(Start, End); //開始喂食 42 }}} 43 break; 44 } 45 mPreviousY = y; //記錄觸控筆Y位置 46 mPreviousX = x; //記錄觸控筆X位置 47 super.onTouchEvent(e); 48 }

第1~9行首先創(chuàng)建變量,用于記錄觸控筆上一次的觸控X位置和Y位置,然后獲取當(dāng)前觸控點(diǎn)的X坐標(biāo)和Y坐標(biāo),并且響應(yīng)屏幕的觸控事件,對(duì)ACTION_DOWN事件進(jìn)行監(jiān)聽,當(dāng)觸發(fā)時(shí)將喂食標(biāo)志位設(shè)為true。
第10~28行對(duì)ACTION_MOVE事件進(jìn)行監(jiān)聽,獲取手指在屏幕上的移動(dòng)距離,按照一定比例移動(dòng)攝像機(jī)X坐標(biāo),同時(shí),如果攝像機(jī)X坐標(biāo)達(dá)到閾值,則攝像機(jī)不會(huì)向滑動(dòng)方向移動(dòng);然后將攝像機(jī)的位置信息存入到矩陣中,設(shè)置攝像機(jī)的位置,觀測(cè)點(diǎn)的坐標(biāo)和up向量。
第30~37行是判斷喂食的標(biāo)志位,因?yàn)榛瑒?dòng)屏幕不能喂食,當(dāng)前喂的食物在沒有消失之前也不能喂食,所以需要兩個(gè)標(biāo)志位對(duì)其進(jìn)行控制。一個(gè)在點(diǎn)擊喂食的時(shí)候?yàn)閠rue,另一個(gè)在沒有喂食之前為true,然后通過矩陣變換獲取觸控點(diǎn)在世界坐標(biāo)系中的坐標(biāo)。
第38~47行通過拾取計(jì)算獲取觸控點(diǎn)在世界坐標(biāo)系中的起點(diǎn)(近平面點(diǎn))坐標(biāo)、終點(diǎn)(遠(yuǎn)平面點(diǎn))坐標(biāo),判斷feedfish不為空,則調(diào)用startFeed方法開始喂食;然后記錄觸控筆的X位置、Y位置,回調(diào)父類的方法。

2.4.2 自定義渲染器類——MySurfaceView
下面將詳細(xì)介紹自定義的場(chǎng)景渲染器代碼,在自定義的場(chǎng)景渲染器類里,可以進(jìn)行魚、魚群、烏龜、珍珠貝、氣泡、背景圖、魚食的初始化。初始化魚類和烏龜?shù)某跏妓俣取⒊跏嘉恢靡约凹虞d紋理等,并且設(shè)置光源位置,初始化矩陣等。

(1)由于MySurfaceView類中繪制代碼以及初始化代碼比較多,在此首先介紹該類的繪制代碼以及整體框架,使讀者對(duì)此類有一個(gè)大致的了解。具體代碼如下所示。

1 package wyf.lxg.mywallpaper; 2 .....//此處省略部分類和包的導(dǎo)入代碼,請(qǐng)讀者自行查閱隨書附帶光盤的源代碼 3 public class MySurfaceView extends GLSurfaceView 4 implements GLSurfaceView.Renderer,OpenGLES2WallpaperService.Renderer { 5 public MySurfaceView(Context context) { 6 super(context); //獲取上下文對(duì)象 7 this.setEGLContextClientVersion(2); //設(shè)置使用OPENGL ES2.0 8 } 9 .....//此處省略相關(guān)成員變量的聲明代碼,請(qǐng)讀者自行查閱隨書附帶光盤的源代碼 10 public void onDrawFrame(GL10 gl) { 11 GLES20.glClear( GLES20.GL_DEPTH_BUFFER_BIT //清除深度緩沖與顏色緩沖 12 | GLES20.GL_COLOR_BUFFER_BIT); 13 MatrixState.pushMatrix(); //保護(hù)矩陣 14 if(bg!=null){ bg.drawSelf(back); } //繪制背景圖 15 if(singlefood!=null) { singlefood.drawSelf();} //繪制魚食 16 if (fishControl != null) { fishControl.drawSelf();} //繪制單條魚和烏龜 17 if (fishSchool != null) { fishSchool.drawSelf();} //繪制魚群 18 .....//此處繪制其他魚群的代碼與上述相似,故省略,請(qǐng)讀者自行查閱隨書附帶光盤的源代碼 19 MatrixState.pushMatrix(); //保護(hù)矩陣 20 MatrixState.translate(,-16,); //平移到指定位置 21 this.haibei.animate(time,dpm); //繪制珍珠貝 22 MatrixState.popMatrix(); //恢復(fù)矩陣 23 time += ; 24 if(time > this.ms3d.getTotalTime()) { //若當(dāng)前播放時(shí)間大于總的動(dòng)畫時(shí)間 25 time = time - this.ms3d.getTotalTime();//則播放時(shí)間等于當(dāng)前播放時(shí)間減去總的動(dòng)畫時(shí)間 26 } 27 MatrixState.popMatrix(); //恢復(fù)矩陣 28 GLES20.glEnable(GLES20.GL_BLEND); //開啟混合 29 GLES20.glBlendFunc(GLES20.GL_SRC_COLOR, //設(shè)置混合因子c 30 GLES20.GL_ONE_MINUS_SRC_COLOR); 31 MatrixState.pushMatrix(); //保護(hù)矩陣 32 if(bubble!=null) { bubble.drawSelf();} //繪制氣泡 33 MatrixState.popMatrix(); //恢復(fù)矩陣 34 GLES20.glDisable(GLES20.GL_BLEND); //關(guān)閉混合 35 } 36 public void onSurfaceChanged(GL10 gl, int width, int height) { 37 .....//此處省略設(shè)置攝像機(jī)的代碼,將在后面詳細(xì)介紹 38 } 39 public void onSurfaceCreated(GL10 gl, EGLConfig config) { 40 .....//此處省略初始化的代碼,將在后面詳細(xì)介紹 41 } 42 public int initTexture(Resources res,String pname)//textureId{ 43 .....//此處省略加載紋理的代碼,將在后面詳細(xì)介紹 44 }}

第1~9行為聲明包名,其中部分類和包的導(dǎo)入代碼、相關(guān)成員變量的聲明代碼在此處省略,請(qǐng)讀者自行查閱隨書附帶的光盤代碼;然后創(chuàng)建構(gòu)造方法,獲取父類上下文對(duì)象,設(shè)置使用OPENGL ES2.0渲染技術(shù)進(jìn)行繪制。
第11~18行首先清除深度緩沖與顏色緩沖,進(jìn)行現(xiàn)場(chǎng)保護(hù),判斷背景、魚食、單條魚、烏龜以及魚群的引用若不為空,依次繪制背景圖、魚食、單條魚、烏龜以及魚群。這里只給出了黃色小丑魚群的繪制代碼,其他魚群繪制代碼與之相似,請(qǐng)讀者自行查閱隨書附帶光盤的源代碼。
第19~27行為繪制珍珠貝的代碼。首先保護(hù)現(xiàn)場(chǎng),然后平移到指定位置,繪制珍珠貝,恢復(fù)現(xiàn)場(chǎng)。并且不斷更新動(dòng)畫播放時(shí)間,若當(dāng)前播放時(shí)間大于總的動(dòng)畫時(shí)間,則實(shí)際播放時(shí)間等于當(dāng)前播放時(shí)間減去總的動(dòng)畫時(shí)間。
第28~34行為繪制氣泡的代碼。首先開啟混合,設(shè)置混合因子,保護(hù)現(xiàn)場(chǎng),判斷氣泡引用不為空,則進(jìn)行氣泡的繪制,然后恢復(fù)現(xiàn)場(chǎng),關(guān)閉混合。
(2)下面介紹上面省略的onSurfaceChanged方法。重寫該方法,主要作用是設(shè)置視口的大小及位置、計(jì)算GLSurfaceView的寬高比、通過計(jì)算產(chǎn)生投影矩陣以及攝像機(jī)9參數(shù)位置矩陣。該方法是場(chǎng)景渲染器類不可或缺的。具體代碼如下所示。

1 public void onSurfaceChanged(GL10 gl, int width, int height) { 2 GLES20.glViewport(0, 0, width, height); //設(shè)置視窗大小及位置 3 float ratio = (float) width / height; //計(jì)算GLSurfaceView的寬高比 4 Constant.SCREEN_HEGHT=height; //獲取屏幕高度 5 Constant.SCREEN_WIDTH=width; //獲取屏幕寬度 6 Constant.leftABS=ratio*Constant.View_SCALE; //設(shè)置left值 7 Constant.topABS=1 * Constant.View_SCALE; //設(shè)置top值 8 Constant.SCREEN_SCALEX=Constant.View_SCALE*((ratio>1)?ratio:(1/ratio)); //設(shè)置縮放比 9 MatrixState.setProjectFrustum(-Constant.leftABS, Constant.leftABS, //產(chǎn)生透視投影矩陣 10 -Constant.topABS, Constant.topABS, Constant.nearABS,Constant.farABS); 11 MatrixState.setCamera( //產(chǎn)生攝像機(jī)9參數(shù)位置矩陣 12 Constant.CameraX //攝像機(jī)的X位置 13 Constant.CameraY, //攝像機(jī)的Y位置 14 Constant.CameraZ, //攝像機(jī)的Z位置 15 Constant.TargetX, //觀測(cè)點(diǎn)的X位置 16 Constant.TargetY, //觀測(cè)點(diǎn)的Y位置 17 Constant.TargetZ, //觀測(cè)點(diǎn)的Z位置 18 Constant.UpX, //up向量的X分量 19 Constant.UpY, //up向量的Y分量 20 Constant.UpZ); //up向量的Z分量 21 }

第1~10行用于設(shè)置視窗大小及位置,獲取屏幕高度以及寬度,設(shè)置視角的left值以及top值,計(jì)算橫屏豎屏縮放比,產(chǎn)生透視投影矩陣。這里使用透視投影矩陣是為了更真實(shí)地模擬現(xiàn)實(shí)世界,產(chǎn)生近大遠(yuǎn)小的效果。
第11~20行用于產(chǎn)生攝像機(jī)的9參數(shù)位置矩陣,分別設(shè)置攝像機(jī)的XYZ位置、觀測(cè)點(diǎn)的XYZ位置以及up向量的XYZ分量,這里將攝像機(jī)位置矩陣的9參數(shù)都存放在Constant類中,是為了便于壁紙左右移動(dòng)時(shí)修改攝像機(jī)的位置。
(3)下面介紹上面省略的onSurfaceCreated方法。重寫該方法,主要作用是初始化光源位置,創(chuàng)建紋理管理器,加載紋理,獲取ms3d文件的輸入流,加載ms3d模型,創(chuàng)建魚類、烏龜、珍珠貝等對(duì)象,開啟深度檢測(cè)等。具體代碼如下所示。

1 public void onSurfaceCreated(GL10 gl, EGLConfig config){ 2 GLES20.glClearColor(,,, ); //設(shè)置屏幕背景色RGBA 3 MatrixState.setInitStack(); //初始化矩陣 4 MatrixState.setLightLocation(0,9,13); //初始化光源位置 5 manager = new TextureManager(getResources()); //創(chuàng)建紋理管理器對(duì)象 6 dpm=initTexture(MySurfaceView.this.getResources(),"dpm.png");//加載明暗紋理 7 String name="ms3d/"; //獲取ms3d文件的輸入流 8 InputStream in=null; 9 ......//此處其他輸入流的聲明與上述相同,故省略,請(qǐng)讀者自行查閱隨書附帶光盤的源代碼 10 try{in=getResources().getAssets().open(name+"fish0.ms3d");//鰩魚 12 ......//此處其他獲取輸入流與上述相同,故省略,請(qǐng)讀者自行查閱隨書附帶光盤的源代碼 13 } catch(Exception e){ 14 e.printStackTrace(); //打印異常棧信息 15 } 16 ms3d = MS3DModel.load(in,manager,MySurfaceView.this); //從輸入流加載模型 17 ......//此處加載模型代碼與上述相同,故省略,請(qǐng)讀者自行查閱隨書附帶光盤的源代碼 18 if(fishAl.size() ){ 19 fishAl.add(new SingleFish(ms3d,dpm, //位置、速度、力、吸引力、重力 20 new Vector(-7, 5, -7), new Vector(, , ), 21 new Vector(0, 0, 0), new Vector(0, 0, 0), 150)); 22 .....//此處添加魚的代碼與上述相同,故省略,請(qǐng)讀者自行查閱隨書附帶光盤的源代碼 23 } 24 back=initTexture(MySurfaceView.this.getResources(),"background.png"); //背景紋理 25 fishfood=initTexture(MySurfaceView.this.getResources(),"fishfood.png"); //魚食紋理 26 bubbles=initTexture(MySurfaceView.this.getResources(),"bubble.png");//氣泡紋理 27 GLES20.glEnable(GLES20.GL_DEPTH_TEST); //打開深度檢測(cè) 28 bg=new Background(MySurfaceView.this); //創(chuàng)建背景對(duì)象 29 bubble = new BubbleControl(MySurfaceView.this,bubbles); //創(chuàng)建氣泡對(duì)象 30 fishfoods=LoadUtil.loadFromFile("fishfood.obj", //魚食對(duì)象 31 MySurfaceView.this.getResources(),MySurfaceView.this); 32 singlefood=new SingleFood(fishfood,fishfoods, MySurfaceView.this);//單個(gè)魚食對(duì)象 33 feedfish=new FeedFish(MySurfaceView.this); //喂食 34 if (fishControl == null) { //創(chuàng)建對(duì)象魚類的Control對(duì)象 35 fishControl = new FishControl(fishAl, MySurfaceView.this); 36 } 37 if (fishSchool == null) { //創(chuàng)建魚群對(duì)象的Control 38 fishSchool = new FishSchoolControl(ms3d3,dpm,MySurfaceView.this, 39 new Vector(5, -2, 4),new Vector(, , ),50);//位置、速度、質(zhì)量 40 } 41 ......//此處添加魚群的代碼與上述相同,故省略,請(qǐng)讀者自行查閱隨書附帶光盤的源代碼 42 GLES20.glDisable(GLES20.GL_CULL_FACE); //關(guān)閉背面剪裁 43 }

第1~6行為設(shè)置背景色的RGBA通道,初始化矩陣,只有初始化矩陣之后,保護(hù)矩陣、恢復(fù)矩陣等才能起作用。初始化光源位置,將光源置于場(chǎng)景的正上方。創(chuàng)建紋理管理器對(duì)象,用于加載紋理圖,并且加載呈現(xiàn)明暗效果的紋理圖。
第7~23行為獲取ms3d文件的輸入流,從輸入流中加載ms3d模型,向魚類列表中添加單條魚、烏龜?shù)取_@里僅給出了fish0的加載代碼,其他種類魚、烏龜以及珍珠貝的加載代碼與此相似,故省略,請(qǐng)讀者自行查閱隨書附帶光盤的源代碼。
第24~42行為加載背景、魚食以及氣泡的紋理,打開深度檢測(cè),創(chuàng)建背景、氣泡、魚食、喂食、魚類以及魚群的對(duì)象。其中在創(chuàng)建魚群對(duì)象時(shí),只給出了創(chuàng)建黃色小丑魚魚群的代碼,其他魚群的創(chuàng)建代碼與此相似,故省略,請(qǐng)讀者自行查閱隨書附帶光盤的源代碼。
(4)下面詳細(xì)介紹上面省略的initTexture方法。該方法的主要作用是通過輸入流從assets中加載圖片,生成紋理ID,設(shè)置紋理的拉伸方式,設(shè)置紋理采樣方式等。具體代碼如下所示。

1 public int initTexture(Resources res,String pname){ //初始化紋理 2 int[] textures = new int[1]; //生成紋理ID 3 GLES20.glGenTextures( 4 1, //產(chǎn)生的紋理id的數(shù)量 5 textures, //紋理id的數(shù)組 6 0 //偏移量 7 ); 8 int textureId=textures[0]; 9 GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);//綁定紋理 10 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, //最近點(diǎn)采樣 11 GLES20.GL_TEXTURE_MIN_FILTER,GLES20.GL_NEAREST); 12 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, //線性紋理過濾 13 GLES20.GL_TEXTURE_MAG_FILTER,GLES20.GL_LINEAR); 14 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, //縱向拉伸方式 15 GLES20.GL_TEXTURE_WRAP_S,GLES20.GL_REPEAT); 16 GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, //橫向拉伸方式 17 GLES20.GL_TEXTURE_WRAP_T,GLES20.GL_REPEAT); 18 InputStream is = null; //創(chuàng)建輸入流 19 String name="pic/"+pname; 20 try { 21 is = res.getAssets().open(name); //加載紋理圖片 22 } catch (IOException e1) { 23 e1.printStackTrace(); //異常處理 24 } 25 Bitmap bitmapTmp; //創(chuàng)建Bitmap對(duì)象 26 try { 27 bitmapTmp = BitmapFactory.decodeStream(is); //對(duì)獲取的圖片解碼 28 } finally { 29 try { 30 is.close(); //關(guān)閉輸入流 31 }catch(IOException e) { 32 e.printStackTrace(); //異常處理 33 }} 34 GLUtils.texImage2D( 35 GLES20.GL_TEXTURE_2D, //紋理類型 36 0, //紋理的層次 37 bitmapTmp, //紋理圖像 38 0 //紋理邊框尺寸 39 ); 40 bitmapTmp.recycle(); //釋放Bitmap 41 return textureId; 42 }

第2~17行為定義紋理ID、生成紋理ID數(shù)組、以及綁定紋理。同時(shí)設(shè)置紋理的過濾方式分別為最近點(diǎn)采樣過濾和線性紋理過濾,設(shè)置紋理的拉伸方式為縱向拉伸方式和橫向拉伸方式并且都為重復(fù)拉伸方式。
第18~33行為創(chuàng)建輸入流,從assets中加載紋理圖片,創(chuàng)建Bitmap對(duì)象,對(duì)獲取的圖片進(jìn)行解碼,然后關(guān)閉輸入流。其中關(guān)閉輸入流是非常重要的,加載完圖片,一定要記得關(guān)閉輸入流,否則會(huì)造成資源浪費(fèi)。
第34~41行為指定紋理。首先是紋理類型,在OpenGL ES中必須為GLES20.GL_ TEXTURE_2D;其次是紋理的層次,0表示基本圖像層,可以理解為直接貼圖;然后是紋理的圖像以及邊框尺寸;最后釋放Bitmap,返回紋理ID。

總結(jié)

以上是生活随笔為你收集整理的《Android 应用案例开发大全(第3版)》——第2.4节壁纸的实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。