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(跳過)記憶體。
[java] view plain copy
- package com.waitingfy.android.glbasics;
- import java.io.IOException;
- import java.nio.ByteBuffer;
- import java.nio.ByteOrder;
- import java.nio.FloatBuffer;
- import java.nio.ShortBuffer;
- import javax.microedition.khronos.egl.EGLConfig;
- import javax.microedition.khronos.opengles.GL10;
- import android.app.Activity;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.opengl.GLSurfaceView;
- import android.opengl.GLUtils;
- import android.opengl.GLSurfaceView.Renderer;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.Window;
- import android.view.WindowManager;
- public class TexturedRectangleTest extends Activity {
- public GLSurfaceView glView;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 去掉activity的标題,全屏顯示
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
- glView = new GLSurfaceView(this);
- glView.setRenderer(new SimpleRenderer());
- setContentView(glView);
- }
- @Override
- public void onResume() {
- super.onPause();
- glView.onResume();
- }
- @Override
- public void onPause() {
- super.onPause();
- glView.onPause();
- }
- class SimpleRenderer implements Renderer {
- FloatBuffer vertices;
- FloatBuffer texture;
- ShortBuffer indices;
- int textureId;
- public SimpleRenderer() {
- ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * 2 * 4);
- byteBuffer.order(ByteOrder.nativeOrder());
- vertices = byteBuffer.asFloatBuffer();
- // vertices.put( new float[] { -80f, -120f,0,1f,
- // 80f, -120f, 1f,1f,
- // -80f, 120f, 0f,0f,
- // 80f,120f, 1f,0f});
- vertices.put( new float[] { -80f, -120f,
- 80f, -120f,
- -80f, 120f,
- 80f, 120f});
- ByteBuffer indicesBuffer = ByteBuffer.allocateDirect(6 * 2);
- indicesBuffer.order(ByteOrder.nativeOrder());
- indices = indicesBuffer.asShortBuffer();
- indices.put(new short[] { 0, 1, 2,1,2,3});
- ByteBuffer textureBuffer = ByteBuffer.allocateDirect(4 * 2 * 4);
- textureBuffer.order(ByteOrder.nativeOrder());
- texture = textureBuffer.asFloatBuffer();
- texture.put( new float[] { 0,1f,
- 1f,1f,
- 0f,0f,
- 1f,0f});
- indices.position(0);
- vertices.position(0);
- texture.position(0);
- }
- @Override
- public void onSurfaceCreated(GL10 gl, EGLConfig config) {
- Log.d("GLSurfaceViewTest", "surface created");
- }
- @Override
- public void onSurfaceChanged(GL10 gl, int width, int height) {
- Log.d("GLSurfaceViewTest", "surface changed: " + width + "x"
- + height);
- }
- @Override
- public void onDrawFrame(GL10 gl) {
- textureId = loadTexture("bobrgb888.png",gl);
- //定義顯示在螢幕上的什麼位置(opengl 自動轉換)
- gl.glViewport(0, 0, glView.getWidth(), glView.getHeight());
- gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
- gl.glMatrixMode(GL10.GL_PROJECTION);
- gl.glLoadIdentity();
- gl.glOrthof(-160, 160, -240, 240, 1, -1);
- gl.glEnable(GL10.GL_TEXTURE_2D);
- //綁定紋理ID
- gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
- gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
- gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
- gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices);
- gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texture);
- // gl.glRotatef(1, 0, 1, 0);
- gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 6,
- GL10.GL_UNSIGNED_SHORT, indices);
- }
- public int loadTexture(String fileName,GL10 gl) {
- try {
- Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open(
- fileName));
- int textureIds[] = new int[1];
- gl.glGenTextures(1, textureIds, 0);
- int textureId = textureIds[0];
- gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
- GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
- 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_NEAREST);
- gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);
- bitmap.recycle();
- return textureId;
- } catch (IOException e) {
- Log.d("TexturedRectangleTest",
- "couldn't load asset 'bobrgb888.png'!");
- throw new RuntimeException("couldn't load asset '" + fileName
- + "'");
- }
- }
- }
- }
注意下我們這裡用到的圖檔"bobrgb888.png"是png格式,存放在/assets/下,長寬是128*128,好像紋理圖檔最好是2的n次方大小,而且是正方形。
原文連結: http://www.waitingfy.com/?p=66
源碼下載下傳 gl-basics