建立这样的顶点索引显然更加节约存储空间。
假设Indices:array of Integer是顶点索引数组,Vertices:array of TVertex是顶点数组,使用下面的代码段就可以把整个顶点索引对应的所有三角形绘制出来: procedure DrawIndex(Indices:array of Integer;Vertices:array of TVertex);
var i :Integer; begin
glBegin(GL_TRIANGLES);
for i := 0 to (High(Vertices)+1) div 3 -1 do begin
glVertex3fv(@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。
增加阅读:
OBJ文件 -- 基本结构
OBJ文件不需要任何种文件头(File Header),尽管经常使用几行文件信息的注释作为文件的开头。
OBJ文件由一行行文本组成,注释行以一个“井”号(#)为开头,空格和空行可以随意加到文件中以增加文件的可读性。有字的行都由一两个标记字母也就是关键字(Keyword)开头,关键字可以说明这一行是什么样的数据。多行可以逻辑地连接在一起表示一行,方法是在每一行最后添加一个连接符(\\)。
注意连接符(\\)后面不能出现空格或tab格,否则将导致文件出错。 下列关键字可以在OBJ文件使用。
在这个列表中, 关键字根据数据类型排列,每个关键字有一段简短描述。 顶点数据(Vertex data):
v 几何体顶点 (Geometric vertices) vt 贴图坐标点 (Texture vertices) vn 顶点法线 (Vertex normals)
vp 参数空格顶点 (Parameter space vertices)
自由形态曲线(Free-form curve)/表面属性(surface attributes): deg 度 (Degree)
bmat 基础矩阵 (Basis matrix) step 步尺寸 (Step size)
cstype 曲线或表面类型 (Curve or surface type) 元素(Elements): p 点 (Point) l 线 (Line) f 面 (Face) curv 曲线 (Curve) curv2 2D曲线 (2D curve) 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)
自由形态表面之间的连接(Connectivity between free-form surfaces): con 连接 (Connect) - 成组(Grouping): g 组名称 (Group name) s 光滑组 (Smoothing group) mg 合并组 (Merging group) o 对象名称 (Object name)
- 显示(Display)/渲染属性(render attributes): bevel 导角插值 (Bevel interpolation) c_interp 颜色插值 (Color interpolation) d_interp 溶解插值 (Dissolve interpolation) lod 细节层次 (Level of detail) usemtl 材质名称 (Material name) mtllib 材质库 (Material library) shadow_obj 投射阴影 (Shadow casting) trace_obj 光线跟踪 (Ray tracing)
ctech 曲线近似技术 (Curve approximation technique) stech 表面近似技术 (Surface approximation technique)
的确挺难理解,所以要用实例来说明。 OBJ文件 -- 实例: 下面通过实例来具体讲解。 OBJ文件记录一个四边形的代码: v -0.58 0.84 0 v 2.68 1.17 0 v 2.84 -2.03 0 v -1.92 -2.89 0 f 1 2 3 4
因篇幅问题不能全部显示,请点此查看更多更全内容