我一直在为openGl编写.obj加载程序。几何加载很好,但法线总是搞砸了。我试图在2个不同的程序中导出模型,似乎没有任何工作。据我所知,这就是你如何处理GL_TRIANGLES
的法线 glNormal3fv(norm1);
glVertex3fv(vert1);
glNormal3fv(norm2);
glVertex3fv(vert2);
glNormal3fv(norm3);
glVertex3fv(vert3);
(法线在其余代码中引用了GLfloats。)
编辑:这是一张破损法线
的等面体图片这是完整的obj加载器代码和文件:
void loadOBJFromFile(NSString *path,float movex,float movey)
{
NSString *contentns = [[NSString alloc]initWithContentsOfFile:path encoding:NSASCIIStringEncoding error:NULL];
NSArray *pieces = [contentns componentsSeparatedByString:@"#"];
//creating the arrays to read the vertecies and normals from.
NSArray *normals = [[pieces objectAtIndex:3]componentsSeparatedByString:@"\n"];
NSArray *vertecies = [[pieces objectAtIndex:2]componentsSeparatedByString:@"\n"];
//The +1 is to make sure we ignore the texture/ material definition that vomes before the faces.
int normalCount = [[normals objectAtIndex:0]intValue]+2;
int faceCount = [[normals objectAtIndex:normalCount]intValue];
//glTranslatef(movex, 0, movey);
glBegin(GL_TRIANGLES);
{
for (int i = 0; i < faceCount;i++)
{
//aquires all the numbers in thye current face.
NSArray *currentFace = [[normals objectAtIndex:normalCount+i+1]componentsSeparatedByString:@" "];
NSArray *v1 = [[currentFace objectAtIndex:1]componentsSeparatedByString:@"//"];
NSArray *v2 = [[currentFace objectAtIndex:2]componentsSeparatedByString:@"//"];
NSArray *v3 = [[currentFace objectAtIndex:3]componentsSeparatedByString:@"//"];
//crewatres the arrays to contain the vertecies
NSArray *vertex1 = [[vertecies objectAtIndex:[[v1 objectAtIndex:1]intValue]]componentsSeparatedByString:@" "];
NSArray *vertex2 = [[vertecies objectAtIndex:[[v2 objectAtIndex:1]intValue]]componentsSeparatedByString:@" "];
NSArray *vertex3 = [[vertecies objectAtIndex:[[v3 objectAtIndex:1]intValue]]componentsSeparatedByString:@" "];
//creates all the arrays for the normals
NSArray *normal1 = [[normals objectAtIndex:[[v1 objectAtIndex:1]intValue]]componentsSeparatedByString:@" "];
NSArray *normal2 = [[normals objectAtIndex:[[v2 objectAtIndex:1]intValue]]componentsSeparatedByString:@" "];
NSArray *normal3 = [[normals objectAtIndex:[[v3 objectAtIndex:1]intValue]]componentsSeparatedByString:@" "];
//creates the vertecies coordinates
GLfloat vert1[] = {[[vertex1 objectAtIndex:1]floatValue],[[vertex1 objectAtIndex:2]floatValue],[[vertex1 objectAtIndex:3]floatValue]};
GLfloat vert2[] = {[[vertex2 objectAtIndex:1]floatValue],[[vertex2 objectAtIndex:2]floatValue],[[vertex2 objectAtIndex:3]floatValue]};
GLfloat vert3[] = {[[vertex3 objectAtIndex:1]floatValue],[[vertex3 objectAtIndex:2]floatValue],[[vertex3 objectAtIndex:3]floatValue]};
//creates the normals coordinates
GLfloat norm1[] = {[[normal1 objectAtIndex:1]floatValue],[[normal1 objectAtIndex:2]floatValue],[[normal1 objectAtIndex:3]floatValue]};
GLfloat norm2[] = {[[normal2 objectAtIndex:1]floatValue],[[normal2 objectAtIndex:2]floatValue],[[normal2 objectAtIndex:3]floatValue]};
GLfloat norm3[] = {[[normal3 objectAtIndex:1]floatValue],[[normal3 objectAtIndex:2]floatValue],[[normal3 objectAtIndex:3]floatValue]};
glNormal3fv(norm1);
glVertex3fv(vert1);
glNormal3fv(norm2);
glVertex3fv(vert2);
glNormal3fv(norm3);
glVertex3fv(vert3);
}}
glEnd();
}
obj文件:
#Wavefront OBJ file created by Hexagon 2
mtllib object.mtl
g Form0
usemtl def_surf_mat
# 12
v -12.533 4.78719 0
v -12.533 20.2788 0
v -7.74583 12.533 -12.533
v -7.74583 12.533 12.533
v 0 0 -7.74583
v 0 0 7.74583
v 0 25.066 -7.74583
v 0 25.066 7.74583
v 7.74583 12.533 -12.533
v 7.74583 12.533 12.533
v 12.533 4.78719 0
v 12.533 20.2788 0
# 12
vn -0.850651 -0.525731 0
vn -0.850651 0.525731 1.50014e-08
vn -0.525731 -1.50014e-08 -0.850651
vn -0.525731 0 0.850651
vn 1.50014e-08 -0.850651 -0.525731
vn -1.50014e-08 -0.850651 0.525731
vn -1.50014e-08 0.850651 -0.525731
vn 1.50014e-08 0.850651 0.525731
vn 0.525731 0 -0.850651
vn 0.525731 7.5007e-09 0.850651
vn 0.850651 -0.525731 1.50014e-08
vn 0.850651 0.525731 -1.50014e-08
usemtl def_surf_mat
20
f 7//7 8//8 12//12
f 7//7 2//2 8//8
f 8//8 4//4 10//10
f 6//6 10//10 4//4
f 7//7 9//9 3//3
f 5//5 3//3 9//9
f 6//6 5//5 11//11
f 6//6 1//1 5//5
f 1//1 4//4 2//2
f 1//1 2//2 3//3
f 12//12 11//11 9//9
f 12//12 10//10 11//11
f 2//2 4//4 8//8
f 10//10 12//12 8//8
f 12//12 9//9 7//7
f 3//3 2//2 7//7
f 3//3 5//5 1//1
f 4//4 1//1 6//6
f 9//9 11//11 5//5
f 11//11 10//10 6//6
答案 0 :(得分:1)
有了你在问题中添加的额外信息,我的想法已经不多了。我也不能真正阅读Objective-C,但我建议仔细检查你所有的数组索引和行计数代码(也许打印出来看看它们是否真的是你所期望的),因为解析基于信任确切的布局和注释一个出口商创造看起来很毛茸茸。
原始答案:
如果没有看到您的加载程序代码或.obj文件,请查看以下几点:
答案 1 :(得分:1)
tl; dr但是 - 检查你的法线符号是否正确。在计算中很容易使法线指向与您预期相反的方向。例如。它们沿着正确的线,但指向内部而不是外部。您的图像与该类型或错误一致。
据我记得计算法线时,你必须采用两条边的矢量交叉积。计算的顺序决定了法线是否进入或退出。因此,请确保按正确的顺序进行计算。
答案 2 :(得分:1)
在我看来,OBJ文件是有效的,并且您的OBJ解析器正确读取顶点位置和法线。所以,我认为渲染问题来自不同的原因。
图像中的视觉瑕疵看起来像是不正确的深度测试。 (仅绘制三角形的一半)我猜你在IB(Interface Builder)中使用了NSOpenGLView的子类。确保您在IB 属性检查器中启用NSOpenGLView的深度缓冲区(默认情况下,它是无)。深度缓冲区的公共值是24位,加上Stencil缓冲区的8位。
并且,以下是一些改进程序的建议;
绘图和解析必须在单独的函数中执行。因为您只需要加载一次文件,但您可以多次绘制模型。
对顶点,法线和面使用NSMutableArray。
您的OBJ加载程序不是解析OBJ文件的最佳方法,因为它取决于注释行(以#开头)。我愿意:
答案 3 :(得分:0)
答案很简单。正在从目标文件中正确加载对象。加载器代码可以进行更多优化。打电话后,
glEnable(GL_CULL_FACE | GL_CULL_FACE_MODE);
修改强> 我不敢相信我当时犯了这样一个新手的错误。剔除的脸有所帮助,但只有一点点。真正的问题是我忘记清除深度缓冲区。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
如果其他人也遇到同样的事情,那应该解决问题。
一些问题已修复,我实际上需要清除另一个缓冲区或弹出矩阵或其他东西。现在,照明几何体正好加载它在编辑器和建模程序中的显示方式。谢谢大家的帮助。