【OpenGL实践06】如何读入模型文件obj数据

发布于:2024-03-28 ⋅ 阅读:(31) ⋅ 点赞:(0)

一、说明

   OBJ文件是Wavefront公司为它的一套基于工作站的3D建模和动画软件"Advanced Visualizer"开发的一种文件格式,这种格式同样也以通过Maya读写。OBJ文件是一种文本文件,可以直接用写字板打开进行查看和编辑修改。

二、OBJ文件

2.1基础-- 概念

   3D文件格式,常见的有几种 “.3ds",".max”,“.lw",".mb”,“.dxf",".obj”。
   OBJ(或 .OBJ)是一种几何定义文件格式,最初由Wavefront Technologies为其高级可视化器动画包开发。该文件格式是开放的,已被其他 3D 图形应用程序供应商采用。

   OBJ 文件格式是一种简单的数据格式,仅表示 3D 几何体 - 即每个顶点的位置、每个纹理坐标顶点的UV 位置、顶点法线以及使每个多边形定义为顶点列表的面,和纹理顶点。默认情况下,顶点按逆时针顺序存储,因此无需显式声明面法线。 OBJ 坐标没有单位,但 OBJ 文件可以在人类可读的注释行中包含比例信息。

   OBJ 格式支持多边形(Polygon),直线(Lines),表面(Surfaces),和自由形态曲线(Free-form Curves)。直线和多角形通过它们的点来描述,曲线和表面则根据于它们的控制点和依附于曲线类型的额外信息来定义。这些信息支持规则和不规则的曲线,包括那些基于贝塞尔(Bezier)曲线,B样条(B-spline),基数(Cardinal/Catmull-Rom样条),和泰勒方程(Taylor equations)的曲线。

2.2 OBJ文件特点

   (1)OBJ是一种3D模型文件,因此不包含动画、材质特性、贴图路径、动力学、粒子等信息。
   (2) OBJ文件主要支持多边形(Polygons)模型。虽然OBJ文件也支持曲线(Curves)、表面(Surfaces)、点组材质(Point Group Materials),但Maya导出的OBJ文件并不包括这些信息。

   (3)OBJ文件支持三个点以上的面。

   很多其它的模型文件格式只支持三个点的面,所以我们导入Maya的模型经常被三角化了,这对于我们对模型的再加工甚为不利。

   (4)OBJ文件支持法线和贴图坐标。

   在其它软件中调整好贴图后,贴图坐标信息可以存入OBJ文件中,这样文件导入Maya后只需指定一下贴图文件路径就行了,不需要再调整贴图坐标

三、OBJ文件 – 基本结构

3.1 文件内注释

   哈希字符 (#) :后面的任何内容都是注释。

3.2 文件内容示例

   OBJ 文件可以包含顶点数据、自由形式曲线/曲面属性、元素、自由形式曲线/曲面主体语句、自由形式曲面之间的连接性、分组和显示/渲染属性信息。最常见的元素是几何顶点、纹理坐标、顶点法线和多边形面:

# List of geometric vertices, with (x, y, z, [w]) coordinates, w is optional and defaults to 1.0.
v 0.123 0.234 0.345 1.0
v ...
...
# List of texture coordinates, in (u, [v, w]) coordinates, these will vary between 0 and 1. v, w are optional and default to 0.
vt 0.500 1 [0]
vt ...
...
# List of vertex normals in (x,y,z) form; normals might not be unit vectors.
vn 0.707 0.000 0.707
vn ...
...
# Parameter space vertices in (u, [v, w]) form; free form geometry statement (see below)
vp 0.310000 3.210000 2.100000
vp ...
...
# Polygonal face element (see below)
f 1 2 3
f 3/1 4/2 5/3
f 6/4/1 3/5/3 7/6/5
f 7//1 8//2 9//3
f ...
...
# Line element (see below)
l 5 8 1 2 4 9

3. 3 几何顶点列表

  • 几何顶点
       顶点通过以字母 v 开头的线指定。后面是 (x,y,z[,w]) 坐标。 W 是可选的,默认为 1.0。右手坐标系用于指定坐标位置。某些应用程序通过在 x y 和 z 之后放置红色、绿色和蓝色值来支持顶点颜色(这会排除指定 w)。颜色值范围从 0 到 1。[2]
v  0.123 0.234 0.345 1.0

3. 4 纹理坐标列表

   纹理描述以vt开头,用 (u, [v, w]) 坐标表示,这些坐标在 0 到 1 之间变化。 v、w 是可选的,默认为 0。

vt 0.500 1 [0]
vt...

3.5 (x,y,z) 形式的顶点法线列表

   法线向量可能不是单位向量。标识符为vn,后面紧跟(x,y,z)的向量,法向量(normals)不能是单位向量。

vn 0.707 0.000 0.707
vn ...

3.6 (u, [v, w]) 形式的参数空间顶点

   可以在以字符串 vp 开头的行中指定自由格式的几何语句。在曲线或曲面的参数空间中定义点。曲线点只需u,曲面点和非有理修剪曲线控制点需要u 和v,有理修剪曲线控制点需要u、v 和w(权重)。

vp 0.310000 3.210000 2.100000
vp...

3.7 多边形面元素(见下文)

   面用face的第一个字符f标识。面是使用顶点、纹理和法线索引列表定义的,格式为 v e r t e x i n d e x / t e x t u r e i n d e x / n o r m a l i n d e x vertex_index/texture_index/normal_index vertexindex/textureindex/normalindex
   每个索引从 1 开始,并根据引用元素的定义顺序递增。诸如四边形之类的多边形可以使用三个以上的索引来定义。

   OBJ 文件还支持使用曲线和曲面来定义对象的自由形式几何体,例如 NURBS 曲面。

f 1 2 3
f 3/1 4/2 5/3
f 6/4/1 3/5/3 7/6/5
f 7//1 8//2 9//3
f ...

3.8 线元素(见下文)

   线元素以字母“l”(小写 L)开头的记录指定构建多段线的顶点的顺序。

l 5 8 1 2 4 9

   其中,5 8 1 2 4 9 是符号为5 8 1 2 4 9的六个顶点序列号。

3.9 顶点索引

   有效的顶点索引与先前定义的顶点列表的相应顶点元素相匹配。如果索引为正,则它引用该顶点列表中的偏移量,从 1 开始。如果索引为负,则它相对引用顶点列表的末尾,-1 引用最后一个元素。

   参数空间顶点
   可以在以字符串 开头的行中指定自由格式的几何语句vp。在曲线或曲面的参数空间中定义点。u仅需要曲线点、非有理修剪曲线的曲面点和控制点,以及u有理修剪曲线的控制点 和(权重)。vuvw

四、面部元素

   面是使用顶点、纹理和法线索引列表定义的,格式为 vertex_index/texture_index/normal_index,每个索引从 1 开始,并根据引用元素的定义顺序递增。诸如四边形之类的多边形可以使用三个以上的索引来定义。

   OBJ 文件还支持使用曲线和曲面来定义对象的自由形式几何体,例如NURBS曲面。

每个面可以包含三个或更多顶点。

f v1 v2 v3 ....

   顶点纹理坐标索引
   可选地,纹理坐标索引可用于在定义面时指定纹理坐标。要在定义面时将纹理坐标索引添加到顶点索引,必须在顶点索引后紧接着放置斜线,然后放置纹理坐标索引。斜杠前后不允许有空格。有效的纹理坐标索引从 1 开始,与先前定义的纹理坐标列表中的相应元素匹配。每个面可以包含三个或更多元素。

f v1/vt1 v2/vt2 v3/vt3 ...

   顶点法线索引
   或者,在定义面时,可以使用法线索引来指定顶点的法线向量。要在定义面时将法线索引添加到顶点索引,必须在纹理坐标索引后放置第二个斜杠,然后放置法线索引。有效的法线索引从 1 开始,并与先前定义的法线列表中的相应元素匹配。每个面可以包含三个或更多元素。

f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ...

   没有纹理坐标索引的顶点法线索引
   由于纹理坐标是可选的,因此可以在没有纹理坐标的情况下定义几何体,但在放置法线索引之前必须在顶点索引后面放置两个斜杠。

f v1//vn1 v2//vn2 v3//vn3 ...

五、OBJ文件更高级标识语句

   OBJ文件不需要任何种文件头(File Header),尽管经常使用几行文件信息的注释作为文件的开头。OBJ文件由一行行文本组成,注释行以一个“井”号(#)为开头,空格和空行可以随意加到文件中以增加文件的可读性。有字的行都由一两个标记字母也就是关键字(Keyword)开头,关键字可以说明这一行是什么样的数据。多行可以逻辑地连接在一起表示一行,方法是在每一行最后添加一个连接符()。

   注意连接符()后面不能出现空格或tab格,否则将导致文件出错。

   下列关键字可以在OBJ文件使用,在这个列表中, 关键字根据数据类型排列,每个关键字有一段简短描述。

   1) 顶点数据(Vertex data):
   v 几何体顶点 (Geometric vertices)
   vt 贴图坐标点 (Texture vertices)
   vn 顶点法线 (Vertex normals)
   vp 参数空格顶点 (Parameter space vertices)

   2)自由形态曲线(Free-form curve)/表面属性(surface attributes):
   deg 度 (Degree)
   bmat 基础矩阵 (Basis matrix)
   step 步尺寸 (Step size)
   cstype 曲线或表面类型 (Curve or surface type)
   3)元素(Elements):
   p 点 (Point)
   l 线 (Line)
   f 面 (Face)
   curv 曲线 (Curve)
   curv2 2D曲线 (2D curve)

   4)surf 表面 (Surface)
   自由形态曲线(Free-form curve)/表面主体陈述(surface body statements):
   parm 参数值 (Parameter values )
   trim 外部修剪循环 (Outer trimming loop)
   hole 内部整修循环 (Inner trimming loop)
   scrv 特殊曲线 (Special curve)
   sp 特殊的点 (Special point)
   end 结束陈述 (End statement)

   5)自由形态表面之间的连接(Connectivity between free-form surfaces):

   con 连接 (Connect)
   成组(Grouping):
   g 组名称 (Group name)
   s 光滑组 (Smoothing group)
   mg 合并组 (Merging group)
   o 对象名称 (Object name)

六、一些obj文件实例:

6.1 示例01

# The units used in this file are centimeters.

g default
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000

vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000
vt 0.000000 2.000000
vt 1.000000 2.000000
vt 0.000000 3.000000
vt 1.000000 3.000000
vt 0.000000 4.000000
vt 1.000000 4.000000
vt 2.000000 0.000000
vt 2.000000 1.000000
vt -1.000000 0.000000
vt -1.000000 1.000000

vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 -1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000

s off

g pCube1

usemtl initialShadingGroup

f 1/1/1 2/2/2 4/4/3 3/3/4
f 3/3/5 4/4/6 6/6/7 5/5/8
f 5/5/9 6/6/10 8/8/11 7/7/12
f 7/7/13 8/8/14 2/10/15 1/9/16
f 2/2/17 8/11/18 6/12/19 4/4/20
f 7/13/21 1/1/22 3/3/23 5/14/24

6.2 示例02

   贝塞尔片面(Bezier Patch)

# 3.0 Bezier patch

v -5.000000 -5.000000 0.000000
v -5.000000 -1.666667 0.000000
v -5.000000 1.666667 0.000000
v -5.000000 5.000000 0.000000
v -1.666667 -5.000000 0.000000
v -1.666667 -1.666667 0.000000
v -1.666667 1.666667 0.000000
v -1.666667 5.000000 0.000000
v 1.666667 -5.000000 0.000000
v 1.666667 -1.666667 0.000000
v 1.666667 1.666667 0.000000
v 1.666667 5.000000 0.000000
v 5.000000 -5.000000 0.000000
v 5.000000 -1.666667 0.000000
v 5.000000 1.666667 0.000000
v 5.000000 5.000000 0.000000

# 16 vertices
cstype bezier

deg 3 3

# Example of line continuation

surf 0.000000 1.000000 0.000000 1.000000 13 14 \
15 16 9 10 11 12 5 6 7 8 1 2 3 4
parm u 0.000000 1.000000
parm v 0.000000 1.000000
end
# 1 element

6.3 示例03

   基数曲线(Cardinal Curve)

# 3.0 Cardinal curve
v 0.940000 1.340000 0.000000
v -0.670000 0.820000 0.000000
v -0.770000 -0.940000 0.000000
v 1.030000 -1.350000 0.000000
v 3.070000 -1.310000 0.000000
# 6 vertices

cstype cardinal

deg 3
curv 0.000000 3.000000 1 2 3 4 5 6
parm u 0.000000 1.000000 2.000000 3.000000 end
# 1 element

   贴图映射(Texture-Mapped)

# A 2 x 2 square mapped with a 1 x 1 square
# texture stretched to fit the square exactly.

mtllib master.mtl

v 0.000000 2.000000 0.000000
v 0.000000 0.000000 0.000000
v 2.000000 0.000000 0.000000
v 2.000000 2.000000 0.000000
vt 0.000000 1.000000 0.000000
vt 0.000000 0.000000 0.000000
vt 1.000000 0.000000 0.000000
vt 1.000000 1.000000 0.000000

# 4 vertices
usemtl wood
# The first number is the point,
# then the slash,
# and the second is the texture point
f 1/1 2/2 3/3 4/4
# 1 element
本文含有隐藏内容,请 开通VIP 后查看