Android平台3D引擎研究4

OpenGL ES纹理处理

使用OpenGL ES的纹理可以将图片贴到3D模型上,从而生成逼真的3D场景。纹理是以图片文件形式存在的,图片被归一化为(0.0, 0.0)到(1.0, 1.0)的矩形区域,通常一个3D物体具有一个纹理文件即可,每处三角片所使用的纹理可以通过uv坐标来指定。通过三角片每个顶点在归一化后图片中的坐标,可以从纹理图片中取出相应的三角形区域,OpenGL ES将该区域进行放缩旋转后绘制到三角片上。具体处理代码如下所示:

obj = new MgnavObject(true, true, false); // 第一个参数表示使用纹理坐标,第三个参数表示不使用颜色

下面代码导入纹理:


// 装入纹理数据
Bitmap bmp = null;
bmp = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory() + "/building/L6HF2703.JPG");
String textureId = "cube";
if (bmp != null) {
Shared.textureManager().addTextureId(bmp, textureId, false);
bmp.recycle();
TextureVo tvo = new TextureVo(textureId);
obj.textures().add(tvo);
}
scene.lightingEnabled(false);

从上面的代码中可以看出,是读取SD卡中的一个文件作为纹理图片。

下面为立方体正面赋给纹理坐标:

// 1. front
normalX = 0f; normalY = 0f; normalZ = 1.0f;
// 1.1. 加入前面右上部三角片
textureU = 0.0f; textureV = 0.0f;
short f1p1Idx = vertices().addVertex(-width, height, deepth,
textureU, textureV,
normalX, normalY, normalZ,
colorR, colorG, colorB, colorA);
textureU = 1.0f; textureV = 1.0f;
short f1p3Idx = vertices().addVertex(width, -height, deepth,
textureU, textureV,
normalX, normalY, normalZ,
colorR, colorG, colorB, colorA);
textureU = 1.0f; textureV = 0.0f;
short f1p2Idx = vertices().addVertex(width, height, deepth,
textureU, textureV,
normalX, normalY, normalZ,
colorR, colorG, colorB, colorA);
faces().add(f1p1Idx, f1p3Idx, f1p2Idx);
// 1.2. 加入前面的左下部三角片
textureU = 0.0f; textureV = 1.0f;
short f1p4Idx = vertices().addVertex(-width, -height, deepth,
textureU, textureV,
normalX, normalY, normalZ,
colorR, colorG, colorB, colorA);
faces().add(f1p1Idx, f1p4Idx, f1p3Idx);

对于上面的纹理坐标比较难以理解,下面通过图形来加以说明:

图1

上面是立方体正面顶点编号,上面代码加入了1、3、2及1、4、3这两个三角片。

本来的纹理坐标如下图所示:

图2

其坐标原点在左下角,与OpenGL ES几何元素的坐标是上下颠倒的。在从其他3D软件导出时,这些软件将自动将图片进行上下颠倒。但是我们这里直接用图片贴图时,我们需要人工将纹理图片颠倒一下,在这里将纹理坐标进行上下颠倒:

图3

这时与顶点所对就的纹理坐标就是代码中所设置的值。

 

注:由于不能将图片贴上,请看本博文新浪博客上的完整版:http://blog.sina.com.cn/s/blog_5d8486b40100q2vc.html

posted @ 2011-08-09 07:24  java中文技术  阅读(214)  评论(0编辑  收藏  举报