android 3D-紋理——球的紋理

來源:互聯網
上載者:User
   看了幾天3D這些天才弄懂些畫圖,現在弄這個紋理煩得很,半懂半不懂的,這個例子是我到網站下載的,感覺不錯,先給大家看看,下期我再和大家討論討論。

 
package wyf.sj;import android.app.Activity;import android.os.Bundle;import android.widget.CompoundButton;import android.widget.LinearLayout;import android.widget.ToggleButton;import android.widget.CompoundButton.OnCheckedChangeListener;public class Sample6_2 extends Activity {    /** Called when the activity is first created. */ MySurfaceView mGLSurfaceView;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        mGLSurfaceView = new MySurfaceView(this);        mGLSurfaceView.requestFocus();//擷取焦點        mGLSurfaceView.setFocusableInTouchMode(true);//設定為可觸控                LinearLayout ll=(LinearLayout)findViewById(R.id.main_liner);         ll.addView(mGLSurfaceView);                ToggleButton tb=(ToggleButton)this.findViewById(R.id.ToggleButton01);        tb.setOnCheckedChangeListener(            new OnCheckedChangeListener()            {     @Override     public void onCheckedChanged(CompoundButton buttonView,boolean isChecked)      {      mGLSurfaceView.setSmoothFlag(!mGLSurfaceView.isSmoothFlag());
package wyf.sj;import java.io.IOException;import java.io.InputStream;import javax.microedition.khronos.egl.EGLConfig;import javax.microedition.khronos.opengles.GL10;import android.content.Context;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.opengl.GLSurfaceView;import android.opengl.GLUtils;import android.view.MotionEvent;public class MySurfaceView extends GLSurfaceView {private final float TOUCH_SCALE_FACTOR = 180.0f/320;//角度縮放比例    private SceneRenderer mRenderer;//情境渲染器    private float mPreviousY;//上次的觸控位置Y座標    private float mPreviousX;//上次的觸控位置Y座標private boolean smoothFlag=true;//是否進行平滑著色private int lightAngleGreen=0;//綠光燈的當前角度private int lightAngleRed=90;//紅光燈的當前角度int textureId;//紋理名稱IDpublic MySurfaceView(Context context) {super(context);mRenderer = new SceneRenderer();//建立情境渲染器    setRenderer(mRenderer);//設定渲染器    setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);//設定渲染模式為主動渲染   } @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;//計算觸控筆Y位移            float dx = x - mPreviousX;//計算觸控筆Y位移            mRenderer.ball.mAngleX += dy * TOUCH_SCALE_FACTOR;//設定沿x軸旋轉角度            mRenderer.ball.mAngleZ += dx * TOUCH_SCALE_FACTOR;//設定沿z軸旋轉角度            requestRender();//重繪畫面        }        mPreviousY = y;//記錄觸控筆位置        mPreviousX = x;//記錄觸控筆位置        return true;    }    public void setSmoothFlag(boolean smoothFlag) {this.smoothFlag = smoothFlag;}public boolean isSmoothFlag() {return smoothFlag;}private class SceneRenderer implements GLSurfaceView.Renderer {   Ball ball;public SceneRenderer(){        //開啟一個線程自動旋轉球體        new Thread()        {        public void run()        {      try            {            Thread.sleep(1000);//休息1000ms再開始繪製            }            catch(Exception e)            {            e.printStackTrace();            }         while(true)        {      lightAngleGreen+=5;//轉動綠燈      lightAngleRed+=5;//轉動紅燈                requestRender();//重繪畫面                try                {                Thread.sleep(50);//休息10ms再重繪                }                catch(Exception e)                {                e.printStackTrace();                }                  }        }        }.start();}    public void onDrawFrame(GL10 gl) {                if(smoothFlag)    {//進行平滑著色    gl.glShadeModel(GL10.GL_SMOOTH);    }    else    {//不進行平滑著色    gl.glShadeModel(GL10.GL_FLAT);    }        //設定綠色光源的位置    float lxGreen=(float)(7*Math.cos(Math.toRadians(lightAngleGreen)));    float lzGreen=(float)(7*Math.sin(Math.toRadians(lightAngleGreen)));    float[] positionParamsGreen={lxGreen,0,lzGreen,1};//最後的1表示使用定位光        gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, positionParamsGreen,0);                 //設定紅色光源的位置        float lyRed=(float)(7*Math.cos(Math.toRadians(lightAngleRed)));    float lzRed=(float)(7*Math.sin(Math.toRadians(lightAngleRed)));        float[] positionParamsRed={0,lyRed,lzRed,1};//最後的1表示使用定位光        gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_POSITION, positionParamsRed,0);                //清除顏色緩衝    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);    //設定當前矩陣為模式矩陣        gl.glMatrixMode(GL10.GL_MODELVIEW);        //設定當前矩陣為單位矩陣        gl.glLoadIdentity();                     gl.glTranslatef(0, 0f, -1.8f);                  gl.glPushMatrix();//保護變換矩陣現場        ball.drawSelf(gl);//繪製球        gl.glPopMatrix();//恢複變換矩陣現場    }    public void onSurfaceChanged(GL10 gl, int width, int height) {        //設定視窗大小及位置     gl.glViewport(0, 0, width, height);    //設定當前矩陣為投影矩陣        gl.glMatrixMode(GL10.GL_PROJECTION);        //設定當前矩陣為單位矩陣        gl.glLoadIdentity();        //計算透視投影的比例        float ratio = (float) width / height;        //調用此方法計算產生透視投影矩陣        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);    }    public void onSurfaceCreated(GL10 gl, EGLConfig config) {        //關閉抗抖動     gl.glDisable(GL10.GL_DITHER);    //設定特定Hint項目的模式,這裡為設定為使用快速模式        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST);        //設定螢幕背景色黑色RGBA        gl.glClearColor(0,0,0,0);        //設定著色模型為平滑著色           gl.glShadeModel(GL10.GL_SMOOTH);//GL10.GL_SMOOTH  GL10.GL_FLAT        //啟用深度測試        gl.glEnable(GL10.GL_DEPTH_TEST);                gl.glEnable(GL10.GL_LIGHTING);//允許光照                    initGreenLight(gl);//初始化綠色燈        initRedLight(gl);//初始化紅色燈        initMaterial(gl);//初始化材質                textureId=initTexture(gl,R.drawable.duke);//初始化紋理        ball=new Ball(4,textureId);    }}//初始化綠色燈private void initGreenLight(GL10 gl){    gl.glEnable(GL10.GL_LIGHT0);//開啟0號燈          //環境光線設定    float[] ambientParams={0.1f,0.1f,0.1f,1.0f};//光參數 RGBA    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, ambientParams,0);                    //散射光設定    float[] diffuseParams={0f,1f,0f,1.0f};//光參數 RGBA    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, diffuseParams,0);         //反射光設定    float[] specularParams={1f,1f,1f,1.0f};//光參數 RGBA    gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_SPECULAR, specularParams,0);     }//初始化紅色燈private void initRedLight(GL10 gl){        gl.glEnable(GL10.GL_LIGHT1);//開啟1號燈          //環境光線設定    float[] ambientParams={0.2f,0.2f,0.2f,1.0f};//光參數 RGBA    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_AMBIENT, ambientParams,0);                    //散射光設定    float[] diffuseParams={1f,0f,0f,1.0f};//光參數 RGBA    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_DIFFUSE, diffuseParams,0);         //反射光設定    float[] specularParams={1f,1f,1f,1.0f};//光參數 RGBA    gl.glLightfv(GL10.GL_LIGHT1, GL10.GL_SPECULAR, specularParams,0); }//初始化材質private void initMaterial(GL10 gl){//材質為白色時什麼顏色的光照在上面就將體現出什麼顏色    //環境光線為白色材質    float ambientMaterial[] = {1.0f, 1.0f, 1.0f, 1.0f};    gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_AMBIENT, ambientMaterial,0);    //散射光為白色材質    float diffuseMaterial[] = {1.0f, 1.0f, 1.0f, 1.0f};    gl.glMaterialfv(GL10.GL_FRONT_AND_BACK, GL10.GL_DIFFUSE, diffuseMaterial,0);    //高光材質為白色    float specularMaterial[] = {1f, 1f, 1f, 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 textureId)//textureId{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_NEAREST);    gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR);    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(textureId);    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;}}

package wyf.sj;import java.nio.ByteBuffer;import java.nio.ByteOrder;import java.nio.FloatBuffer;import java.nio.IntBuffer;import java.util.ArrayList;import javax.microedition.khronos.opengles.GL10;public class Ball {private IntBuffer   mVertexBuffer;//頂點座標資料緩衝private IntBuffer   mNormalBuffer;//頂點法向量資料緩衝    private FloatBuffer mTextureBuffer;//頂點紋理資料緩衝    public float mAngleX;//沿x軸旋轉角度    public float mAngleY;//沿y軸旋轉角度     public float mAngleZ;//沿z軸旋轉角度     int vCount=0;//頂點數量    int textureId;//紋理ID        public Ball(int scale,int textureId)    {    this.textureId=textureId;    final int UNIT_SIZE=10000;            //實際頂點座標資料的初始化================begin============================        ArrayList<Integer> alVertix=new ArrayList<Integer>();//存放頂點座標的ArrayList    final int angleSpan=18;//將球進行單位切分的角度        for(int vAngle=-90;vAngle<=90;vAngle=vAngle+angleSpan)//垂直方向angleSpan度一份        {        for(int hAngle=0;hAngle<360;hAngle=hAngle+angleSpan)//水平方向angleSpan度一份        {//縱向橫向各到一個角度後計算對應的此點在球面上的座標        double xozLength=scale*UNIT_SIZE*Math.cos(Math.toRadians(vAngle));        int x=(int)(xozLength*Math.cos(Math.toRadians(hAngle)));        int z=(int)(xozLength*Math.sin(Math.toRadians(hAngle)));        int y=(int)(scale*UNIT_SIZE*Math.sin(Math.toRadians(vAngle)));        //將計算出來的XYZ座標加入存放頂點座標的ArrayList        alVertix.add(x);alVertix.add(y);alVertix.add(z);        }        }         vCount=alVertix.size()/3;//頂點的數量為座標值數量的1/3,因為一個頂點有3個座標            //將alVertix中的座標值轉存到一個int數組中        int vertices[]=new int[vCount*3];    for(int i=0;i<alVertix.size();i++)    {    vertices[i]=alVertix.get(i);    }        //實際頂點座標資料的初始化================end============================                               //三角形構造頂點、紋理、法向量資料初始化==========begin==========================    alVertix.clear();        ArrayList<Float> alTexture=new ArrayList<Float>();//紋理                  int row=(180/angleSpan)+1;//球面切分的行數        int col=360/angleSpan;//球面切分的列數        for(int i=0;i<row;i++)//對每一行迴圈        {        if(i>0&&i<row-1)        {//中間行        for(int j=-1;j<col;j++){//中間行的兩個相鄰點與下一行的對應點構成三角形int k=i*col+j;//第1個三角形頂點alVertix.add(vertices[(k+col)*3]);alVertix.add(vertices[(k+col)*3+1]);alVertix.add(vertices[(k+col)*3+2]);alTexture.add(0.0f);alTexture.add(0.0f);//第2個三角形頂點alVertix.add(vertices[(k+1)*3]);alVertix.add(vertices[(k+1)*3+1]);alVertix.add(vertices[(k+1)*3+2]);alTexture.add(1.0f);alTexture.add(1.0f);//第3個三角形頂點alVertix.add(vertices[k*3]);alVertix.add(vertices[k*3+1]);alVertix.add(vertices[k*3+2]);alTexture.add(1.0f);alTexture.add(0.0f);}        for(int j=0;j<col+1;j++){//中間行的兩個相鄰點與上一行的對應點構成三角形int k=i*col+j;//第1個三角形頂點alVertix.add(vertices[(k-col)*3]);alVertix.add(vertices[(k-col)*3+1]);alVertix.add(vertices[(k-col)*3+2]);alTexture.add(1f);alTexture.add(1f);//第2個三角形頂點alVertix.add(vertices[(k-1)*3]);alVertix.add(vertices[(k-1)*3+1]);alVertix.add(vertices[(k-1)*3+2]);alTexture.add(0.0f);alTexture.add(0.0f);//第3個三角形頂點alVertix.add(vertices[k*3]);alVertix.add(vertices[k*3+1]);alVertix.add(vertices[k*3+2]);alTexture.add(0f);alTexture.add(1f);    }        }        }                vCount=alVertix.size()/3;//頂點的數量為座標值數量的1/3,因為一個頂點有3個座標            //將alVertix中的座標值轉存到一個int數組中        vertices=new int[vCount*3];    for(int i=0;i<alVertix.size();i++)    {    vertices[i]=alVertix.get(i);    }                //建立繪製頂點資料緩衝        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);        vbb.order(ByteOrder.nativeOrder());//設定位元組順序        mVertexBuffer = vbb.asIntBuffer();//轉換為int型緩衝        mVertexBuffer.put(vertices);//向緩衝區中放入頂點座標資料        mVertexBuffer.position(0);//設定緩衝區起始位置                     //建立頂點法向量資料緩衝        ByteBuffer nbb = ByteBuffer.allocateDirect(vertices.length*4);        nbb.order(ByteOrder.nativeOrder());//設定位元組順序        mNormalBuffer = vbb.asIntBuffer();//轉換為int型緩衝        mNormalBuffer.put(vertices);//向緩衝區中放入頂點座標資料        mNormalBuffer.position(0);//設定緩衝區起始位置                //建立紋理座標緩衝        float textureCoors[]=new float[alTexture.size()];//頂點紋理值數組        for(int i=0;i<alTexture.size();i++)         {        textureCoors[i]=alTexture.get(i);        }                ByteBuffer cbb = ByteBuffer.allocateDirect(textureCoors.length*4);        cbb.order(ByteOrder.nativeOrder());//設定位元組順序        mTextureBuffer = cbb.asFloatBuffer();//轉換為int型緩衝        mTextureBuffer.put(textureCoors);//向緩衝區中放入頂點著色資料        mTextureBuffer.position(0);//設定緩衝區起始位置                //三角形構造頂點、紋理、法向量資料初始化==========end==============================    }    public void drawSelf(GL10 gl)    {    gl.glRotatef(mAngleZ, 0, 0, 1);//沿Z軸旋轉    gl.glRotatef(mAngleX, 1, 0, 0);//沿X軸旋轉        gl.glRotatef(mAngleY, 0, 1, 0);//沿Y軸旋轉                //允許使用頂點數組        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);//為畫筆指定頂點座標資料        gl.glVertexPointer        (        3,//每個頂點的座標數量為3  xyz         GL10.GL_FIXED,//頂點座標值的類型為 GL_FIXED        0, //連續頂點座標資料之間的間隔        mVertexBuffer//頂點座標資料        );                //允許使用法向量數組        gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);        //為畫筆指定頂點法向量資料        gl.glNormalPointer(GL10.GL_FIXED, 0, mNormalBuffer);        //開啟紋理        gl.glEnable(GL10.GL_TEXTURE_2D);           //允許使用紋理ST座標緩衝        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);        //為畫筆指定紋理ST座標緩衝        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);        //綁定當前紋理        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);                //繪製圖形        gl.glDrawArrays        (        GL10.GL_TRIANGLES, //以三角形方式填充        0,  //開始點編號        vCount//頂點數量        );     }}

} } ); } @Override protected void onResume() { super.onResume(); mGLSurfaceView.onResume(); } @Override protected void onPause() { super.onPause(); mGLSurfaceView.onPause(); } }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.