初学Android OpenGL ES之使用纹理 八十三

在网上发现这些讲纹理的文章,非常不错

android 游戏导引(4. 简单纹理贴图)

http://www.cnblogs.com/shengdoushi/archive/2011/01/13/1934181.html

Android OpenGL es 纹理坐标设定与贴图规则

http://blog.csdn.net/cjkwin/article/details/6016224

Android OpenGL | ES给立方体进行纹理映射

http://www.ourunix.org/android/post/34.html

这篇的例子也是立方体的纹理,不过是用手指划过让立方体旋转

使用纹理的重要代码如下

		private void loadTexture(GL10 gl)
		{
			Bitmap bitmap = null;
			try
			{
				// 加载位图
				bitmap = BitmapFactory.decodeResource(context.getResources(),
					R.drawable.sand);
				int[] textures = new int[1];
				// 指定生成N个纹理(第一个参数指定生成1个纹理),
				// textures数组将负责存储所有纹理的代号。
				gl.glGenTextures(1, textures, 0);
				// 获取textures纹理数组中的第一个纹理
				texture = textures[0];
				// 通知OpenGL将texture纹理绑定到GL10.GL_TEXTURE_2D目标中
				gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
				// 设置纹理被缩小(距离视点很远时被缩小)时候的滤波方式
				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);
				// 加载位图生成纹理
				GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
			}
			finally
			{
				// 生成纹理之后,回收位图
				if (bitmap != null)
					bitmap.recycle();
			}
		}

纹理的装载则是在方法void onSurfaceCreated(GL10 gl, EGLConfig config) 中

在Renderer的 void onDrawFrame(GL10 gl)方法中要启用纹理的数组数据,坐标数据,执行纹理贴图

			// 启用贴图座标数组数据
			gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
			// 设置贴图的的座标数据
			gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, cubeTexturesBuffer);
			// 执行纹理贴图
			gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);

完整代码如下

public class Texture3D extends Activity
	implements OnGestureListener
{
	// 定义旋转角度
	private float anglex = 0f;
	private float angley = 0f;
	static final float ROTATE_FACTOR = 60;
	// 定义手势检测器实例
	GestureDetector detector;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		// 创建一个GLSurfaceView,用于显示OpenGL绘制的图形
		GLSurfaceView glView = new GLSurfaceView(this);
		// 创建GLSurfaceView的内容绘制器
		MyRenderer myRender = new MyRenderer(this);
		// 为GLSurfaceView设置绘制器
		glView.setRenderer(myRender);
		setContentView(glView);
		// 创建手势检测器
		detector = new GestureDetector(this);
	}

	@Override
	public boolean onTouchEvent(MotionEvent me)
	{
		// 将该Activity上的触碰事件交给GestureDetector处理
		return detector.onTouchEvent(me);
	}

	@Override
	public boolean onFling(MotionEvent event1, MotionEvent event2,
		float velocityX, float velocityY)
	{
		velocityX = velocityX > 4000 ? 4000 : velocityX;
		velocityX = velocityX < -4000 ? -4000 : velocityX;
		velocityY = velocityY > 4000 ? 4000 : velocityY;
		velocityY = velocityY < -4000 ? -4000 : velocityY;
		// 根据横向上的速度计算沿Y轴旋转的角度
		angley += velocityX * ROTATE_FACTOR / 4000;
		// 根据纵向上的速度计算沿X轴旋转的角度
		anglex += velocityY * ROTATE_FACTOR / 4000;
		return true;
	}

	@Override
	public boolean onDown(MotionEvent arg0)
	{
		return false;
	}

	@Override
	public void onLongPress(MotionEvent event)
	{
	}

	@Override
	public boolean onScroll(MotionEvent event1, MotionEvent event2,
		float distanceX, float distanceY)
	{
		return false;
	}

	@Override
	public void onShowPress(MotionEvent event)
	{
	}

	@Override
	public boolean onSingleTapUp(MotionEvent event)
	{
		return false;
	}

	public class MyRenderer implements Renderer
	{
		// 立方体的顶点座标(一共是36个顶点,组成12个三角形)
		private float[] cubeVertices = { -0.6f, -0.6f, -0.6f, -0.6f, 0.6f,
			-0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, -0.6f, -0.6f,
			-0.6f, -0.6f, -0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f,
			0.6f, 0.6f, 0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, -0.6f,
			0.6f, -0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, 0.6f,
			0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, -0.6f, 0.6f,
			-0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, 0.6f, 0.6f, 0.6f,
			0.6f, 0.6f, -0.6f, 0.6f, 0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f,
			-0.6f, 0.6f, -0.6f, -0.6f, 0.6f, 0.6f, -0.6f, 0.6f, 0.6f, 0.6f,
			0.6f, 0.6f, 0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, -0.6f,
			-0.6f, -0.6f, -0.6f, 0.6f, -0.6f, -0.6f, 0.6f, -0.6f, 0.6f, 0.6f,
			-0.6f, 0.6f, -0.6f, };
		// 定义立方体所需要的6个面(一共是12个三角形所需的顶点)
		private byte[] cubeFacets = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
			13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
			30, 31, 32, 33, 34, 35, };
		// 定义纹理贴图的座标数据
		private float[] cubeTextures = { 1.0000f, 1.0000f, 1.0000f, 0.0000f,
			0.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 1.0000f,
			1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f,
			1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f,
			1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f,
			0.0000f, 0.0000f, 0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f,
			1.0000f, 1.0000f, 0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f,
			0.0000f, 1.0000f, 0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f,
			0.0000f, 1.0000f, 0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f,
			0.0000f, 1.0000f, 1.0000f, 1.0000f, 1.0000f, 0.0000f, 1.0000f,
			0.0000f, 0.0000f, 0.0000f, 0.0000f, 1.0000f };

		private Context context;
		private FloatBuffer cubeVerticesBuffer;
		private ByteBuffer cubeFacetsBuffer;
		private FloatBuffer cubeTexturesBuffer;
		// 定义本程序所使用的纹理
		private int texture;

		public MyRenderer(Context main)
		{
			this.context = main;
			// 将立方体的顶点位置数据数组包装成FloatBuffer;
			cubeVerticesBuffer = FloatBuffer.wrap(cubeVertices);
			// 将立方体的6个面(12个三角形)的数组包装成ByteBuffer
			cubeFacetsBuffer = ByteBuffer.wrap(cubeFacets);
			// 将立方体的纹理贴图的座标数据包装成FloatBuffer
			cubeTexturesBuffer = FloatBuffer.wrap(cubeTextures);
		}

		@Override
		public void onSurfaceCreated(GL10 gl, EGLConfig config)
		{
			// 关闭抗抖动
			gl.glDisable(GL10.GL_DITHER);
			// 设置系统对透视进行修正
			gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
			gl.glClearColor(0, 0, 0, 0);
			// 设置阴影平滑模式
			gl.glShadeModel(GL10.GL_SMOOTH);
			// 启用深度测试
			gl.glEnable(GL10.GL_DEPTH_TEST);
			// 设置深度测试的类型
			gl.glDepthFunc(GL10.GL_LEQUAL);
			// 启用2D纹理贴图
			gl.glEnable(GL10.GL_TEXTURE_2D);
			// 装载纹理
			loadTexture(gl);
		}

		@Override
		public void onSurfaceChanged(GL10 gl, int width, int height)
		{
			// 设置3D视窗的大小及位置
			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 onDrawFrame(GL10 gl)
		{
			// 清除屏幕缓存和深度缓存
			gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
			// 启用顶点座标数据
			gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
			// 启用贴图座标数组数据
			gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
			// 设置当前矩阵模式为模型视图。
			gl.glMatrixMode(GL10.GL_MODELVIEW);
			// --------------------绘制第一个图形---------------------
			gl.glLoadIdentity();
			// 把绘图中心移入屏幕2个单位
			gl.glTranslatef(0f, 0.0f, -2.0f);
			// 旋转图形
			gl.glRotatef(angley, 0, 1, 0);
			gl.glRotatef(anglex, 1, 0, 0);
			// 设置顶点的位置数据
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeVerticesBuffer);
			// 设置贴图的的座标数据
			gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, cubeTexturesBuffer);
			// 执行纹理贴图
			gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
			// 按cubeFacetsBuffer指定的面绘制三角形
			gl.glDrawElements(GL10.GL_TRIANGLES, cubeFacetsBuffer.remaining(),
				GL10.GL_UNSIGNED_BYTE, cubeFacetsBuffer);
			// 绘制结束
			gl.glFinish();
			// 禁用顶点、纹理座标数组
			gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
			gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
			// 递增角度值以便每次以不同角度绘制
		}

		private void loadTexture(GL10 gl)
		{
			Bitmap bitmap = null;
			try
			{
				// 加载位图
				bitmap = BitmapFactory.decodeResource(context.getResources(),
					R.drawable.sand);
				int[] textures = new int[1];
				// 指定生成N个纹理(第一个参数指定生成1个纹理),
				// textures数组将负责存储所有纹理的代号。
				gl.glGenTextures(1, textures, 0);
				// 获取textures纹理数组中的第一个纹理
				texture = textures[0];
				// 通知OpenGL将texture纹理绑定到GL10.GL_TEXTURE_2D目标中
				gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);
				// 设置纹理被缩小(距离视点很远时被缩小)时候的滤波方式
				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);
				// 加载位图生成纹理
				GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
			}
			finally
			{
				// 生成纹理之后,回收位图
				if (bitmap != null)
					bitmap.recycle();
			}
		}
	}
}

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

原文地址:https://www.cnblogs.com/swdhywhd/p/10311812.html

时间: 2024-10-13 20:25:34

初学Android OpenGL ES之使用纹理 八十三的相关文章

对Android opengl ES世界坐标系和纹理坐标系的理解

初学opengl ES,每一个教你在屏幕上贴图的opengl版hello world都有这么两数组: static final float COORD[] = { -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, }; static final float TEXTURE_COORD[] = { 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, }; 但是几乎都不解释,所以我学的时候都不明白这些点

Android OpenGL ES(七)----理解纹理与纹理过滤

1.理解纹理 OpenGL中的纹理可以用来表示图像,照片,甚至由一个数学算法生成的分形数据.每个二维的纹理都由许多小的纹理元素组成,它们是小块的数据,类似于我们前面讨论过的片段和像素.要使用纹理,最常用的方式是直接从一个图像文件加载数据. 每个二维纹理都有其自己的坐标空间,其范围是从一个拐角的(0,0)到另一个拐角的(1,1).按照惯例,一个维度叫做S,而另一个称为T.当我们想要把一个纹理应用于一个三角形或一组三角形的时候,我们要为每个顶点指定一组ST纹理坐标,以便OpenGL知道需要用那个纹理

Android OpenGL ES 应用(二) 纹理

上一篇讲了基础入门 OpenGL (一) ,这一次主要学习OpenGL 纹理基本学习总结 要是做复杂的OpenGL应用程序,一定会用到纹理技术.纹理说白了就是把图片或者视频图像绘制到OpenGL空间中. 因此纹理也有坐标系,称ST坐标,或者UV 上面是纹理坐标空间,但没有固定的方向 下面演示加载一张image作为纹理贴图. public class TextureUtils { public static int createTexture(InputStream ins) { int[] te

Android OpenGL ES零基础系列(一):理解GLSurfaceView,GLSurfaceView.Render的基本用法

转载请注明出处 前言 OpenGL ES是OpenGL的一个子集,是针对手机.PDA和游戏主机等嵌入式设备而设计的.该API由Khronos集团定义推广,Khronos是一个图形软硬件行业协会,该协会主要关注图形和多媒体方面的开放标准. 因此OpenGL ES作为第三方库被应用在android中. 到目前为止,OpenGL ES已经发展有了3个版本,OpenGL ES 1.0 , OpenGL ES 2.0 , OpenGL ES 3.0.其中OpenGL ES 1.0 是以OpenGL 1.3

Android OpenGL ES(八)绘制点Point ..

上一篇介绍了OpenGL ES能够绘制的几种基本几何图形:点,线,三角形.将分别介绍这几种基本几何图形的例子.为方便起见,暂时在同一平面上绘制这些几何图形,在后面介绍完OpenGL ES的坐标系统和坐标变换后,再介绍真正的3D图形绘制方法. 在Android OpenGL ES(六):创建实例应用OpenGLDemos程序框架 创建了示例应用的程序框架,并提供了一个“Hello World”示例. 为避免一些重复代码,这里定义一个所有示例代码的基类OpenGLESActivity,其定义如下:

[工作记录] Android OpenGL ES 2.0: square texture not supported on some device

npot texture: non-power-of-two texture.rectangle texture: non-square (height != wdith) 在测试Samsumg Galaxy S4的时候, 发现rectangle texture支持不好, 虽然创建成功, 但是绘制有问题. 不同的模块出现类似的情况: 纹理采样出的颜色是(0,0,0,1). 在排除了所有可能的runtime问题以后, 尝试性改了纹理格式无果, 又尝试性的改了下尺寸, 竟然好了. 我擦... 而Ga

Android OpenGL ES零基础系列(三):OpenGL ES的渲染管道及VertexShader与FragmentShader

前言 在前2篇文章中,我们都说到着色器,且在第二篇中正式说到,这着色器只能用在OpenGL ES2.x等可编程管道里面,而在OpenGL ES1.x是不能用的.但我们一直没有说这是为什么,两者有什么区别.那这篇我们就一起来学习下OpenGL ES中的渲染管道. 正文 管道,英文名叫Pipeline,相信用过FaceBook图片加载库的同学对这个管道并不陌生,因为SimpleImageDrawee里面也是用的管道来对图片进行的一个处理.由于其底层也是C,因此我可以大胆的猜想,FaceBook图片加

Android OpenGL ES

1.Android OpenGL ES 简明开发教程3D 坐标变换: http://www.linuxidc.com/Linux/2011-10/45756p4.htm

[工作记录] Android OpenGL ES: non-square texture - continue

previous: [工作记录] Android OpenGL ES 2.0: square texture not supported on some device recently I found that it is the mipmap of a non-square texture that cause the black texture problem: http://stackoverflow.com/questions/5052762/using-mipmaps-results-