1. 程式人生 > >Android 中使用OpenGL ES進行2D開發(紋理Texture使用)

Android 中使用OpenGL ES進行2D開發(紋理Texture使用)

OpenGL紋理是一種點陣圖,可以把它貼上到OpenGL物體的表面上。比如可以獲取一張郵票的影象貼上到正方形中,使正方形看起來像一張郵票。要使郵票保持合適的方向,以便影象井然有序地排列,則必須獲得形狀的每個頂點並在正方形上標記出來,以便郵票和正方形的形狀保持一致。在OpenGL中引入了紋理座標。

OpenGL 假設紋理圖始終為1x1的正方形,其原點位於(0.0)處,右下角為(1,1)。如下圖。


紋理座標與頂點座標之間的對映如下圖:

所以我們用的浮點陣列不只是要儲存4個點的位置,還要儲存紋理座標值
vertices.put( new float[] {   -80f,   -120f,
0.0f, 1.0f,
                                           80f,   -120f,1.0f, 1.0f,                                            -80f, 120f,0.0f, 0.0f,                                             80f,  120f, 1.0f,  0.0f});
處理完紋理座標與頂點座標之間的對映關係後,剩餘工作包括將紋理點陣圖載入到記憶體,為它分配紋理ID,以便重用此紋理。
來看下完整程式碼吧,注意我們程式碼中紋理座標和頂點座標分開存放了,這樣更加清晰點,不然還要stride(跳過)記憶體。
  1. package com.waitingfy.android.glbasics;  
  2. import java.io.IOException;  
  3. import java.nio.ByteBuffer;  
  4. import java.nio.ByteOrder;  
  5. import java.nio.FloatBuffer;  
  6. import java.nio.ShortBuffer;  
  7. import javax.microedition.khronos.egl.EGLConfig;  
  8. import javax.microedition.khronos.opengles.GL10;  
  9. import android.app.Activity;  
  10. import android.graphics.Bitmap;  
  11. import android.graphics.BitmapFactory;  
  12. import android.opengl.GLSurfaceView;  
  13. import android.opengl.GLUtils;  
  14. import android.opengl.GLSurfaceView.Renderer;  
  15. import android.os.Bundle;  
  16. import android.util.Log;  
  17. import android.view.Window;  
  18. import android.view.WindowManager;  
  19. publicclass TexturedRectangleTest extends Activity {  
  20.     public GLSurfaceView glView;  
  21.     @Override
  22.     protectedvoid onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         // 去掉activity的標題,全屏顯示
  25.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  26.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  27.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  28.         glView = new GLSurfaceView(this);  
  29.         glView.setRenderer(new SimpleRenderer());  
  30.         setContentView(glView);  
  31.     }  
  32.     @Override
  33.     publicvoid onResume() {  
  34.         super.onPause();  
  35.         glView.onResume();  
  36.     }  
  37.     @Override
  38.     publicvoid onPause() {  
  39.         super.onPause();  
  40.         glView.onPause();  
  41.     }  
  42.     class SimpleRenderer implements Renderer {  
  43.         FloatBuffer vertices;  
  44.         FloatBuffer texture;  
  45.         ShortBuffer indices;  
  46.         int textureId;  
  47.         public SimpleRenderer() {  
  48.             ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * 2 * 4);  
  49.             byteBuffer.order(ByteOrder.nativeOrder());              
  50.             vertices = byteBuffer.asFloatBuffer();  
  51. //            vertices.put( new float[] {  -80f,   -120f,0,1f,
  52. //                                         80f,  -120f, 1f,1f,
  53. //                                         -80f, 120f, 0f,0f,
  54. //                                         80f,120f,   1f,0f});
  55.             vertices.put( newfloat[] {  -80f,   -120f,  
  56.                                          80f,  -120f,   
  57.                                          -80f, 120f,  
  58.                                          80f,  120f});  
  59.             ByteBuffer indicesBuffer = ByteBuffer.allocateDirect(6 * 2);  
  60.             indicesBuffer.order(ByteOrder.nativeOrder());   
  61.             indices = indicesBuffer.asShortBuffer();  
  62.             indices.put(newshort[] { 012,1,2,3});  
  63.             ByteBuffer textureBuffer = ByteBuffer.allocateDirect(4 * 2 * 4);  
  64.             textureBuffer.order(ByteOrder.nativeOrder());              
  65.             texture = textureBuffer.asFloatBuffer();  
  66.             texture.put( newfloat[] { 0,1f,  
  67.                                         1f,1f,  
  68.                                         0f,0f,  
  69.                                         1f,0f});  
  70.             indices.position(0);  
  71.             vertices.position(0);  
  72.             texture.position(0);  
  73.         }  
  74.         @Override
  75.         publicvoid onSurfaceCreated(GL10 gl, EGLConfig config) {  
  76.             Log.d("GLSurfaceViewTest""surface created");  
  77.         }  
  78.         @Override
  79.         publicvoid onSurfaceChanged(GL10 gl, int width, int height) {  
  80.             Log.d("GLSurfaceViewTest""surface changed: " + width + "x"
  81.                     + height);  
  82.         }  
  83.         @Override
  84.         publicvoid onDrawFrame(GL10 gl) {  
  85.             textureId = loadTexture("bobrgb888.png",gl);  
  86.             //定義顯示在螢幕上的什麼位置(opengl 自動轉換)
  87.             gl.glViewport(00, glView.getWidth(), glView.getHeight());  
  88.             gl.glClear(GL10.GL_COLOR_BUFFER_BIT);  
  89.             gl.glMatrixMode(GL10.GL_PROJECTION);  
  90.             gl.glLoadIdentity();  
  91.             gl.glOrthof(-160160, -2402401, -1);  
  92.             gl.glEnable(GL10.GL_TEXTURE_2D);  
  93.                         //繫結紋理ID
  94.                         gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);  
  95.             gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
  96.             gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);  
  97.             gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices);  
  98.             gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texture);  
  99.             // gl.glRotatef(1, 0, 1, 0);
  100.             gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 6,  
  101.                     GL10.GL_UNSIGNED_SHORT, indices);  
  102.         }  
  103.         publicint loadTexture(String fileName,GL10 gl) {  
  104.             try {  
  105.                 Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open(  
  106.                         fileName));  
  107.                 int textureIds[] = newint[1];  
  108.                 gl.glGenTextures(1, textureIds, 0);  
  109.                 int textureId = textureIds[0];  
  110.                 gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);  
  111.                 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);  
  112.                 gl.glTexParameterf(GL10.GL_TEXTURE_2D,  
  113.                         GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);  
  114.                 gl.glTexParameterf(GL10.GL_TEXTURE_2D,  
  115.                         GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);  
  116.                 gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);  
  117.                 bitmap.recycle();  
  118.                 return textureId;  
  119.             } catch (IOException e) {  
  120.                 Log.d("TexturedRectangleTest",  
  121.                         "couldn't load asset 'bobrgb888.png'!");  
  122.                 thrownew RuntimeException("couldn't load asset '" + fileName  
  123.                         + "'");  
  124.             }  
  125.         }  
  126.     }  
  127. }  

注意下我們這裡用到的圖片"bobrgb888.png"是png格式,存放在/assets/下,長寬是128*128,好像紋理圖片最好是2的n次方大小,而且是正方形。