首先看一下obj文件格式:
obj文件中可以有v(顶点位置)、vt(顶点纹理坐标)、vn(顶点法向量)、f(面)开头的四种类型数据。
所有的obj文件中都有v型数据。格式如下:
v 0.437500 0.164062 0.765625
v -0.437500 0.164062 0.765625
v 0.500000 0.093750 0.687500
- vt(顶点纹理坐标),格式如下:
vt 0.651583 0.342268
vt 0.652889 0.355515
vt 0.641220 0.366408
vt 0.628246 0.364052
vt 0.654194 0.368763
- 2. vn(顶点法向量坐标),格式如下:
vn 0.837179 -0.311379 0.449639
vn 0.878055 0.385575 0.283465
vn 0.276184 0.130417 0.952215
vn 0.287141 -0.526486 0.800227
vn 0.255366 0.316928 0.913425
- 3.f(面),格式如下:
f 6203/4489/4130 1062/4483/4124 6215/4510/4151 3078/4513/4154
f 5471/2749/2665 3078/4513/4154 6216/4514/4155 710/2752/2668
f 3078/4513/4154 6215/4510/4151 1067/4512/4153 6216/4514/4155
f 1006/3940/3718 6008/3937/3734 3079/4515/4156 6218/4516/4157
f 6008/3937/3734 714/2761/2677 5476/2760/2676 3079/4515/4156
- 现一一分析介绍:
1.v(顶点坐标位置):
可以看到v后面有三个参数,分别代表该顶点的x、y、z三个坐标值。
2.vt(顶点纹理坐标):
vt后面两个参数,分别代表纹理的U、V值。
3.vn(顶点法向量):
vn后面三个参数,分别代表法向量的x、y、z值。
对于顶点法向量想说的是:我们向opengl中导入3D模型时,如果obj文件中没有vn,就需要我们手动计算面片的法向量,
否则显示出来的图形可能不正确。如果obj文件中有vn,那么,我们就一个点一个点进行绘制,不需要计算面的法向量。
vn表示的是顶点的法向量,不是面的法向量。
举个例子:如果绘制的是四角面片(网上太多例子是三角面片了)
VN[0] = (vnSets[firstVertexIndexf])[0];//第一个点的法向量的x
VN[1] = (vnSets[firstVertexIndexf])[1];//第一个点的法向量的y
VN[2] = (vnSets[firstVertexIndexf])[2];//第一个点的法向量的z
glNormal3f(VN[0], VN[1], VN[2]);
glVertex3f(V1[0], V1[1], V1[2]);
VN[0] = (vnSets[secondVertexIndexf])[0];//第二个点的法向量的x
VN[1] = (vnSets[secondVertexIndexf])[1];//第二个点的法向量的y
VN[2] = (vnSets[secondVertexIndexf])[2];//第二个点的法向量的z
glNormal3f(VN[0], VN[1], VN[2]);
glVertex3f(V2[0], V2[1], V2[2]);
VN[0] = (vnSets[thirdVertexIndexf])[0];//第三个点的法向量的x
VN[1] = (vnSets[thirdVertexIndexf])[1];//第三个点的法向量的y
VN[2] = (vnSets[thirdVertexIndexf])[2];//第三个点的法向量的z
glNormal3f(VN[0], VN[1], VN[2]);
glVertex3f(V3[0], V3[1], V3[2]);
VN[0] = (vnSets[fourthVertexIndexf])[0];//第四个点的法向量的x
VN[1] = (vnSets[fourthVertexIndexf])[1];//第四个点的法向量的y
VN[2] = (vnSets[fourthVertexIndexf])[2];//第四个点的法向量的z
glNormal3f(VN[0], VN[1], VN[2]);
glVertex3f(V4[0], V4[1], V4[2]);
这样就可以绘制出四边形了。
4.f(面):
面较为复杂,如果是简单的obj文件,面的格式可以为:
f 47 1 3
f 4 2 48
f 45 3 5
f 6 4 46
复杂的可以为:
f 3643/6900/6406 7305/6826/6332 1602/6797/6303 7332/6880/6386
f 1592/6749/6259 7343/6901/6407 3644/6902/6408 7269/6750/6260
f 7343/6901/6407 1631/6903/6409 7344/6904/6410 3644/6902/6408
f 7269/6750/6260 3644/6902/6408 7345/6905/6411 1595/6753/6263
面是由点构成的。一行有几个空格(n)区分,就有n+1个点。opengl允许绘制多边形,所以一行可以有多个点构成。
每个点又分为3项:顶点位置坐标索引、顶点纹理坐标索引、顶点法向量坐标索引。
注意:这里都是索引。为什么引入索引? --方便查找。
顶点位置坐标索引对应obj文件的v数据;
顶点纹理坐标索引对应obj文件的vt数据;
顶点法向量坐标索引对应obj文件的vn数据;
我们要根据索引一步一步找到obj文件中各个点对应的真实数据。这样才能进行绘制。