1. 程式人生 > >Android OpenGL ES正方體紋理貼圖(每個面一張)

Android OpenGL ES正方體紋理貼圖(每個面一張)

正方體的紋理貼圖步驟如下:

1.陣列

1.1:頂點陣列

1.2:三角形

1.3:貼圖陣列

2.onSurfaceChanged:與3D的一樣

3.onSurfaceCreated:需要新增東西

3.1允許2D貼圖gl.glEnable(GL10.GL_TEXTURE_2D);    

3.2生成幾個紋理,每個面都貼圖的話就要生成六個紋理,gl.glGenTextures(6, textureBuffer);  //一次性生成幾個                紋理,放到陣列中,但是這時紋理和圖片還沒結合在一起

3.3將紋理繫結到目標上gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[i]);

3.4載入檢視生成紋理GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp[i], 0);

3.5設定目標紋理屬性gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_LINEAR); 

注:3.3-3.5:生成幾個紋理就繫結幾個

4.onDrawFrame

4.1啟動紋理功能,與開啟顏色渲染一樣gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 

4.2設定貼圖座標資料 gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, BufferUtil.iBuffer(texCoords)); 

4.3繪製立方體並繫結紋理(繫結一個面的紋理對應的畫出那個面)
        

這是為正方體的每個面貼一張不同的圖片的程式,注意事項都在註釋中寫明,關於座標設定請看上篇

public void onDrawFrame(GL10 gl) {      
       // TODO Auto-generated method stub      
       //清楚螢幕和深度快取      
       gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);    
       //重置當前的觀察模型矩陣    
       gl.glLoadIdentity();    
       //現將螢幕向裡移動,用來畫正方體      
       gl.glTranslatef(0.0f, 0.0f, -6.0f);     
       
       if(bAutoRotate)
       {
        rotateX+=0.5;
        rotateY+=0.6;
        //rotateZ+=0.3;
       }
       
       //設定3個方向的旋轉    
       gl.glRotatef(rotateX, 1.0f, 0.0f, 0.0f);    
       gl.glRotatef(rotateY, 0.0f, 1.0f, 0.0f);    
       gl.glRotatef(rotateZ, 0.0f, 0.0f, 1.0f);    
          
       gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);     
       //紋理的使用與開啟顏色渲染一樣,需要開啟紋理功能    
       gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);    
           
       //設定正方體 各頂點 資料和貼圖座標陣列,第一個引數都是代表幾個元素設定一個頂點,頂點是三個xyz,貼圖是兩個xy(因為是二維貼圖
       gl.glVertexPointer(3, GL10.GL_FIXED, 0, BufferUtil.iBuffer(quarter));                //注意:這個地方的第二個引數是關於座標資料型別的,根據頂點資料和紋理資料座標的資料型別而改變,如果是FL_FLOAT的話資料型別就是float的,以前我寫的OpenGL版本都是float的


       gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, BufferUtil.iBuffer(texCoords)); 
       
       // 繪製立方體並繫結紋理  
       gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[0]);  
       gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4,  GL10.GL_UNSIGNED_BYTE, indices1);    
       gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[1]);  
       gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4,  GL10.GL_UNSIGNED_BYTE, indices2);    
       gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[2]);  
       gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4,  GL10.GL_UNSIGNED_BYTE, indices3);    
       gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[3]);  
       gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4,  GL10.GL_UNSIGNED_BYTE, indices4);    
       gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[4]);  
       gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4,  GL10.GL_UNSIGNED_BYTE, indices5);    
       gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[5]);  
       gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4,  GL10.GL_UNSIGNED_BYTE, indices6); 

       gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);    
       gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);     
   }      
 
   //當視窗改變時,呼叫,至少在建立視窗時呼叫一次,這邊設定下場景大小      
   @Override      
   public void onSurfaceChanged(GL10 gl, int width, int height) {      
       // TODO Auto-generated method stub      
       //設定OpenGL場景大小      
       float ratio = (float) width / height;      
       gl.glViewport(0, 0, width, height);      
       gl.glMatrixMode(GL10.GL_PROJECTION);//設定為投影矩陣模式      
       gl.glLoadIdentity();//重置      
       gl.glFrustumf(-ratio, ratio, -1, 1, 2, 10);//設定視角      
       gl.glMatrixMode(GL10.GL_MODELVIEW);      
       gl.glLoadIdentity();      
   }      
 
   //當視窗被建立時我們可以做些初始化工作      
   @Override      
   public void onSurfaceCreated(GL10 gl, EGLConfig config) {      
       // TODO Auto-generated method stub      
       //設定清除螢幕時所用的顏色,引數依次為紅、綠、藍、Alpha值      
       gl.glClearColor(0, 0, 0, 0);    
       gl.glEnable(GL10.GL_CULL_FACE);    
       //啟用陰影平滑      
       gl.glShadeModel(GL10.GL_SMOOTH);     
       gl.glEnable(GL10.GL_DEPTH_TEST);//啟用深度測試      
           
       //以下是關於深度快取的設定,非常重要      
       gl.glClearDepthf(1.0f);//設定深度快取      
       gl.glDepthFunc(GL10.GL_LEQUAL);//所做深度測試的型別      
           
       //告訴系統對透視進行修正      
       gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);      
       //允許2D貼圖    
       gl.glEnable(GL10.GL_TEXTURE_2D);    
       
   //gl.glGenTextures(6, tex_id, 0);
       IntBuffer textureBuffer = IntBuffer.allocate(6);  
       gl.glGenTextures(6, textureBuffer);  //一次性生成幾個紋理,放到陣列中,但是這時紋理和圖片還沒結合在一起
       tex_id = textureBuffer.array();  
       
       for(int i = 0; i < 6; i++)
       {
           //將紋理繫結到目標GL10.GL_TEXTURE_2D上
        gl.glBindTexture(GL10.GL_TEXTURE_2D, tex_id[i]);
        //為目標紋理GL10.GL_TEXTURE_2D放上圖片
           GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp[i], 0);
           //設定目標紋理屬性
       gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);    
       gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);  
       }  
         
   } 
}