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.   
  3. import java.io.IOException;  
  4. import java.nio.ByteBuffer;  
  5. import java.nio.ByteOrder;  
  6. import java.nio.FloatBuffer;  
  7. import java.nio.ShortBuffer;  
  8.   
  9. import javax.microedition.khronos.egl.EGLConfig;  
  10. import javax.microedition.khronos.opengles.GL10;  
  11.   
  12.   
  13.   
  14. import android.app.Activity;  
  15. import android.graphics.Bitmap;  
  16. import android.graphics.BitmapFactory;  
  17. import android.opengl.GLSurfaceView;  
  18. import android.opengl.GLUtils;  
  19. import android.opengl.GLSurfaceView.Renderer;  
  20. import android.os.Bundle;  
  21. import android.util.Log;  
  22. import android.view.Window;  
  23. import android.view.WindowManager;  
  24.   
  25.   
  26. public class TexturedRectangleTest extends Activity {  
  27.     public GLSurfaceView glView;  
  28.   
  29.     @Override  
  30.     protected void onCreate(Bundle savedInstanceState) {  
  31.         super.onCreate(savedInstanceState);  
  32.         // 去掉activity的标题,全屏显示   
  33.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  34.         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,  
  35.                 WindowManager.LayoutParams.FLAG_FULLSCREEN);  
  36.         glView = new GLSurfaceView(this);  
  37.         glView.setRenderer(new SimpleRenderer());  
  38.         setContentView(glView);  
  39.     }  
  40.   
  41.     @Override  
  42.     public void onResume() {  
  43.         super.onPause();  
  44.         glView.onResume();  
  45.     }  
  46.   
  47.     @Override  
  48.     public void onPause() {  
  49.         super.onPause();  
  50.         glView.onPause();  
  51.     }  
  52.   
  53.     class SimpleRenderer implements Renderer {  
  54.   
  55.         FloatBuffer vertices;  
  56.         FloatBuffer texture;  
  57.         ShortBuffer indices;  
  58.         int textureId;  
  59.   
  60.         public SimpleRenderer() {  
  61.   
  62.             ByteBuffer byteBuffer = ByteBuffer.allocateDirect(4 * 2 * 4);  
  63.             byteBuffer.order(ByteOrder.nativeOrder());              
  64.             vertices = byteBuffer.asFloatBuffer();  
  65. //            vertices.put( new float[] {  -80f,   -120f,0,1f,   
  66. //                                         80f,  -120f, 1f,1f,   
  67. //                                         -80f, 120f, 0f,0f,   
  68. //                                         80f,120f,   1f,0f});   
  69.             vertices.put( new float[] {  -80f,   -120f,  
  70.                                          80f,  -120f,   
  71.                                          -80f, 120f,  
  72.                                          80f,  120f});  
  73.               
  74.             ByteBuffer indicesBuffer = ByteBuffer.allocateDirect(6 * 2);  
  75.             indicesBuffer.order(ByteOrder.nativeOrder());   
  76.             indices = indicesBuffer.asShortBuffer();  
  77.             indices.put(new short[] { 012,1,2,3});  
  78.               
  79.             ByteBuffer textureBuffer = ByteBuffer.allocateDirect(4 * 2 * 4);  
  80.             textureBuffer.order(ByteOrder.nativeOrder());              
  81.             texture = textureBuffer.asFloatBuffer();  
  82.             texture.put( new float[] { 0,1f,  
  83.                                         1f,1f,  
  84.                                         0f,0f,  
  85.                                         1f,0f});  
  86.               
  87.             indices.position(0);  
  88.             vertices.position(0);  
  89.             texture.position(0);  
  90.               
  91.         }  
  92.   
  93.         @Override  
  94.         public void onSurfaceCreated(GL10 gl, EGLConfig config) {  
  95.             Log.d("GLSurfaceViewTest""surface created");  
  96.         }  
  97.   
  98.         @Override  
  99.         public void onSurfaceChanged(GL10 gl, int width, int height) {  
  100.             Log.d("GLSurfaceViewTest""surface changed: " + width + "x"  
  101.                     + height);  
  102.         }  
  103.   
  104.         @Override  
  105.         public void onDrawFrame(GL10 gl) {  
  106.             textureId = loadTexture("bobrgb888.png",gl);  
  107.             //定义显示在屏幕上的什么位置(opengl 自动转换)   
  108.             gl.glViewport(00, glView.getWidth(), glView.getHeight());  
  109.             gl.glClear(GL10.GL_COLOR_BUFFER_BIT);  
  110.             gl.glMatrixMode(GL10.GL_PROJECTION);  
  111.             gl.glLoadIdentity();  
  112.             gl.glOrthof(-160160, -2402401, -1);  
  113.   
  114.             gl.glEnable(GL10.GL_TEXTURE_2D);  
  115.                         //绑定纹理ID   
  116.                         gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);  
  117.   
  118.             gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);  
  119.             gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);  
  120.   
  121.             gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices);  
  122.   
  123.             gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, texture);  
  124.             // gl.glRotatef(1, 0, 1, 0);   
  125.             gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 6,  
  126.                     GL10.GL_UNSIGNED_SHORT, indices);  
  127.         }  
  128.   
  129.         public int loadTexture(String fileName,GL10 gl) {  
  130.             try {  
  131.                 Bitmap bitmap = BitmapFactory.decodeStream(getAssets().open(  
  132.                         fileName));  
  133.                 int textureIds[] = new int[1];  
  134.                 gl.glGenTextures(1, textureIds, 0);  
  135.                 int textureId = textureIds[0];  
  136.                 gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);  
  137.                 GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);  
  138.                 gl.glTexParameterf(GL10.GL_TEXTURE_2D,  
  139.                         GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);  
  140.                 gl.glTexParameterf(GL10.GL_TEXTURE_2D,  
  141.                         GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);  
  142.                 gl.glBindTexture(GL10.GL_TEXTURE_2D, 0);  
  143.                 bitmap.recycle();  
  144.                 return textureId;  
  145.             } catch (IOException e) {  
  146.                 Log.d("TexturedRectangleTest",  
  147.                         "couldn't load asset 'bobrgb888.png'!");  
  148.                 throw new RuntimeException("couldn't load asset '" + fileName  
  149.                         + "'");  
  150.             }  
  151.         }  
  152.     }  
  153. }  
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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值