android 3dmax

简介: 引用:http://www.eoeandroid.com/thread-67201-1-1.html 原文:http://www.javaworld.com.tw/jute/post/view?bid=26&id=282225一、 在Android显示3D模型,用obj文件 利用网络上找到的obj文件,自行写了一个objLoader类,并分析他的obj文件和结构,最后解析出data文件。

引用:http://www.eoeandroid.com/thread-67201-1-1.html

原文:http://www.javaworld.com.tw/jute/post/view?bid=26&id=282225
一、 在Android显示3D模型,用obj文件
1278472039630.png 


利用网络上找到的obj文件,自行写了一个objLoader类,并分析他的obj文件和结构,最后解析出data文件。

必须确认obj文件的f 参数下必须有
f 1137/1/1 1212/2/2 1115/3/3
对应顶点座标、材质座标、法向量座标
大部分的obj文件可能只有对应的顶点座标
这样的模型就没有材质跟灯光可以使用

附档有范例
objLoader一般java专案用于分析出OPGL需要的vertices、texture、normals、indices
OpglTest3模型测试 :源码:  OpglTest.rar (847.1 KB, 下载次数: 554) 





二、 OBJ文件格式(转http://www.ategpu.com/2009/06/25/%E4%BD%BF%E7%94%A83d%E6%A8%A1%E5%9E%8B.html


   1. 使用建模工具创建模型并导出obj文件

要渲染一个模型,首先要有一个模型文件。目前绝大多数流行的建模软件都支持将模型输出为OBJ文件。这里以3DS Max为例,介绍创建OBJ模型的方法。

首先,启动3DS Max,并向往常一样创建模型。如图
所示。

graph711.jpg


 

模型创建完后,执行文件(File)菜单->导出(Export)命令。在弹出的保存对话框中,输入文件名,并在”保存类型”项中,选则”Wavefront Object (*.obj)”项。

如图
所示。

Graph712.gif


 

 

单击”保存”按钮后,会弹出如图
所示的选项对话框。

 

 

Graph713.gif


 

在这里,请注意在Faces栏中,选择Triangles以使用三角形作为基本图元。还要注意钩去Relative Vertex一项,禁止使用相对顶点索引。这是因为在后面的程序中,我们将不考虑相对顶点索引以简化代码。

单击”OK”按钮后,会紧接着弹出另一个选项对话框,如图
所示。

 

Graph714.gif


 

这一步是在设置与此OBJ文件对应的MTL文件(用于保存材质信息),注意要选择”Scene”并勾选”Export”复选框。然后单击”OK”按钮完成设置。这样,在指定的文件夹下,我们得到了两个文件:一个*.OBJ文件,存储了模型的顶点、法线和纹理坐标信息;一个*.MTL文件,存储了该模型所用的材质信息。
  2
.OBJ文件格式OBJ文件格式是非常简单的。这种文件以纯文本的形式存储了模型的顶点、法线和纹理坐标和材质使用信息。OBJ文件的每一行,都有极其相似的格式。在OBJ文件中,每行的格式如下:

 

前缀 参数1 参数2 参数3 …

 


其中,前缀标识了这一行所存储的信息类型。参数则是具体的数据。OBJ文件的前缀可以有:

 

表7.2-1 OBJ文件中的前缀

前缀

说明

v

表示本行指定一个顶点。 
此前缀后跟着3个单精度浮点数,分别表示该定点的X、Y、Z坐标值

vt

表示本行指定一个纹理坐标。 
此前缀后跟着两个单精度浮点数。分别表示此纹理坐标的U、V值

vn

表示本行指定一个法线向量。 
此前缀后跟着3个单精度浮点数,分别表示该法向量的X、Y、Z坐标值

f

表示本行指定一个表面(Face)。 
一个表面实际上就是一个三角形图元。此前缀行的参数格式后面将详细介绍。

usemtl

此前缀后只跟着一个参数。该参数指定了从此行之后到下一个以usemtl开头的行之间的所有表面所使用的材质名称。该材质可以在此OBJ文件所附属的MTL文件中找到具体信息。

mtllib

此前缀后只跟着一个参数。该参数指定了此OBJ文件所使用的材质库文件(*.mtl)的文件路径

 


我们使用3DS Max创建了一个长方体,并保存为OBJ格式。用写字板打开这个OBJ文件,可以看到如下内容:

 

# Max2Obj Version 4.0 Mar 10th, 2001 

mtllib ./Box.mtl 

# object (null) to come … 

v -46.508743 -45.052959 50.796341 
v 49.442947 -45.052959 50.796341 
v -46.508743 -45.052959 -48.019585 
v 49.442947 -45.052959 -48.019585 
v -46.508743 48.034504 50.796341 
v 49.442947 48.034504 50.796341 
v -46.508743 48.034504 -48.019585 
v 49.442947 48.034504 -48.019585 
# 8 vertices 

vt 0.000000 0.000000 0.000000 
vt 1.000000 0.000000 0.000000 
vt 0.000000 1.000000 0.000000 
vt 1.000000 1.000000 0.000000 
vt 0.000000 0.000000 0.000000 
vt 1.000000 0.000000 0.000000 
vt 0.000000 1.000000 0.000000 
vt 1.000000 1.000000 0.000000 
vt 0.000000 0.000000 0.000000 
vt 1.000000 0.000000 0.000000 
vt 0.000000 1.000000 0.000000 
vt 1.000000 1.000000 0.000000 
# 12 texture vertices 

g (null) 
s 2 
f 1/10 3/12 4/11 
f 4/11 2/9 1/10 
s 4 
f 5/9 6/10 8/12 
f 8/12 7/11 5/9 
s 8 
f 1/5 2/6 6/8 
f 6/8 5/7 1/5 
s 16 
f 2/1 4/2 8/4 
f 8/4 6/3 2/1 
s 32 
f 4/5 3/6 7/8 
f 7/8 8/7 4/5 
s 64 
f 3/1 1/2 5/4 
f 5/4 7/3 3/1 
# 12 faces 

g

 


仔细观察,你会发现这个文件中包含了一些我们没有提到的前缀,如以”#”开头的注释,以g开头的表示组的前缀等等。但这些前缀并不影响模型的外观,因此我们可以忽略它们。在解释以f为前缀的行的格式之前,我们不得不提一个新的概念,这就是顶点索引(Vertex Indices)。我们知道,对于每一个三角形,都需要用3个顶点来表示。例如在上面的立方体模型中,一共有6×2×3=36个顶点。仔细想想就会知道,在这36个顶点中,又相当数量的顶点是重合的。如果把这些重合的顶点都一一表示出来,就太浪费存储空间了。于是,我们提出了顶点索引的想法,解决空间占用问题。顶点索引的思想是建立两个数组,一个数组用于存储模型中所有的顶点坐标值,另一个数组则存储每一个表面所对应的三个顶点在第一个数组中的索引。图 7.2-1显示了这种一一对应的关系。
graph721.gif 
建立这样的顶点索引显然更加节约存储空间。假设Indices:array of Integer是顶点索引数组,Vertices:array of TVertex是顶点数组,使用下面的代码段就可以把整个顶点索引对应的所有三角形绘制出来:procedure DrawIndex(Indices:array of Integer;Vertices:array of TVertex);var i :Integer;beginglBegin(GL_TRIANGLES);for i := 0 to (High(Vertices)+1) div 3 -1 dobeginglVertex3fv(@Vertices[Indices[i*3]]);glVertex3fv(@Vertices[Indices[i*3+1]]);glVertex3fv(@Vertices[Indices[i*3+2]]);end;glEnd;end;以此类推,我们可以为模型中所有的法线、纹理坐标都建立起相应的索引,以节省更多的空间。而事实上,OBJ文件就是这么做的。现在,我们再来看一下OBJ文件的结构。在一个OBJ文件中,首先有一些以v、vt或vn前缀开头的行指定了所有的顶点、纹理坐标、法线的坐标。然后再由一些以f开头的行指定每一个三角形所对应的顶点、纹理坐标和法线的索引。在顶点、纹理坐标和法线的索引之间,使用符号”/”隔开的。一个f行可以以下面几种格式出现:f 1 2 3这样的行表示以第1、2、3号顶点组成一个三角形。f 1/3 2/5 3/4这样的行表示以第1、2、3号顶点组成一个三角形,其中第一个顶点的纹理坐标的索引值为3,第二个顶点的纹理坐标的索引值为5,第三个顶点的纹理坐标的索引值为4。f 1/3/4 2/5/6 3/4/2这样的行表示以第1、2、3号顶点组成一个三角形,其中第一个顶点的纹理坐标的索引值为3,其法线的索引值是4;第二个顶点的纹理坐标的索引值为5,其法线的索引值是6;第三个顶点的纹理坐标的索引值为6,其法线的索引值是2。f 1//4 2//6 3//2这样的行表示以第1、2、3号顶点组成一个三角形,且忽略纹理坐标。其中第一个顶点的法线的索引值是4;第二个顶点的法线的索引值是6;第三个顶点的法线的索引值是2。值得注意的是文件中的索引值是以1作为起点的,这一点与Delphi中以0作为起点有很大的不同。在渲染的时候应注意将从文件中读取的坐标值减去1。7.3 用于存储材质信息的MTL文件MTL文件与OBJ文件极其相似。只是用于标识行的前缀有所不同。这些前缀的意义如表7.3-1所示。

 

表7.3-1 MTL文件中的前缀

前缀

说明

newmtl

表示新建一个材质。 
此前缀后跟一个字符串,表示此材质的名称。 
此行之后的信息都是对这个材质进行设定。

Ka

指定最后建立的材质的环境光成分。此行包含3个单精度浮点参数。

Kd

指定最后建立的材质的漫射光成分。此行包含3个单精度浮点参数。

Ks

指定最后建立的材质的镜面光成分。此行包含3个单精度浮点参数。

map_Kd

指定最后建立的材质的反射贴图。如果此行的第一个参数为字符串”-s”,则此行将包括5个参数。其中第二、第三和第四个参数为此纹理贴图在U、V、W方向的缩放值,第五个参数为纹理图片的文件名。如果第一个字符串不是”-s”,那么第一个参数就是此纹理图片的文件名。

map_Ks

指定最后建立的材质的镜面贴图。如果此行的第一个参数为字符串”-s”,则此行将包括5个参数。其中第二、第三和第四个参数为此纹理贴图在U、V、W方向的缩放值,第五个参数为纹理图片的文件名。如果第一个字符串不是”-s”,那么第一个参数就是此纹理图片的文件名。

 


由这些信息,我们就足以写一个类,用于读取和渲染OBJ模型了。
相关文章
|
Android开发
android:excludeFromRecents="true"
 android:excludeFromRecents="true",设置为true后,当用户按了“最近任务列表”时候,该Task不会出现在最近任务列表中,可达到隐藏应用的目的。
1559 0
|
Android开发 数据格式 XML
Android属性设置android:noHistory="true"
 设置 android:noHistory="true"后,该Activity在statck中不留历史痕迹。默认的值是false。
1057 0
|
安全 Java API
Android Strongbox( Android Ready SE)
Android Strongbox( Android Ready SE)
799 0
|
Java 测试技术 开发工具
从0系统学Android--1.3创建你的第一个 Android 项目
从0系统学Android--1.3创建你的第一个 Android 项目1.3 创建你的第一个 Android 项目环境搭建完成后,我们就可以写下我们的第一个项目了。 1.3.1 创建 HelloWorld 项目在 Android Studio 的欢迎页面点击 Start a new Android Studio project 就会自动为我们创建一个项目。
1261 0
|
Android开发
android islibaray libaray 的创建和使用
今天在读源码的时候发现,一个android项目A作为另一个android项目B的子项目,B中可以使用A中的类以及方法。自己没尝试过,下面就是我实践记录。 1.创建子项目A,命名为MyAndroidLib。
705 0
|
Android开发 数据格式 XML
Android设置Settings:PreferenceFragment【4】
Android设置Settings:PreferenceFragment【4】 最新的android谷歌官方设计文档指出,在后续的Android开发中,应尽量使用PreferenceFragment而不是PreferenceActivity,与时俱进,需要把过去的PreferenceActivity迁移到PreferenceFragment。
1139 0
|
XML Android开发 数据格式
Android设置Settings:ListPreference【3】
 Android设置Settings:ListPreference【3】 Android的Settings实现中,ListPreference使用稍微复杂些,ListPreference使用两个数据源:entries和entryValues,entries和entryValues存在对应关系,可以这么简单理解,entries是人类可读的有意义的内容,而entryValues则是用来为机器或代码使用的具体的值,在前面文章【1】和【2】的基础写一个ListPreference的使用加以说明。
1225 0
|
9月前
|
开发工具 Android开发
Unknown android attribute android:popupPromptView under SherlockSpinner UnknownProjectException
Unknown android attribute android:popupPromptView under SherlockSpinner UnknownProjectException
69 1
|
Android开发
Android书页翻页设计:android-flip
 Android书页翻页设计:android-flip 在一些常见的电子书或者内容阅读类的Android项目中,会实现一种效果:比如,用户在屏幕左翻右翻时候,电子书就像真实的纸质书籍一样翻页(不同于普通的Android ViewPager那样的切换)。
1320 0
|
Android开发 数据安全/隐私保护 安全
SEAndroid和普通android的区别
版权声明:您好,转载请留下本人博客的地址,谢谢 https://blog.csdn.net/hongbochen1223/article/details/46929811 首先我们需要知道,在普通android中使用的是DAC访问方式,即 Discretionary Access Control,顾名思义,该访问方式是自由的访问控制,由此,他有一些本身自有的缺点。
911 0

热门文章

最新文章