我最近开始学习OpenGL,我想从手动编写的立方体开始,并希望使用从Blender导出的模型。最简单的方法似乎是通过解析.obj文件,所以我做了一个解析器。
它有效但不太好,当我想了解灯光时,我偶然发现了一个问题。反射和阴影根本不对。他们对光的位置毫无意义。所以我在线框模式下呈现并且令我惊讶,还有一些额外的面孔不应该在那里。
屏幕截图:http://img5.imageshack.us/img5/5937/582ff91c155b466495b2b02.png
然后我使用我解析的数据生成.obj文件,并使用diff工具将其与原始.obj文件进行比较,似乎没有任何错误。有一些缺失的零,如0.01而不是0.0100,但没有别的。
这是我的解析器:http://pastebin.com/Aw8mdhJ9
以下是我使用解析数据的地方:pastebin.com/5Grt1WGf
这是我的toFloatBuffer:
public static FloatBuffer makeFloatBuffer(float[] arr) {
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
答案 0 :(得分:1)
在互联网上询问后,我发现了很多不同的意见。通过更多的研究,我发现了问题所在。问题是法线是每个面,而对于OpenGL,它们需要是每个顶点。
为了解决这个问题,我重新安排了解析后的数据并制作了新的索引。问题是我现在使用更多索引,并且在OpenGL ES中使用GL_UNSIGNED_SHORT限制,我的顶点数量变得更加有限。
以下是我用来修复数组的代码:
private static void makeThingsWork() {
int n_points = faces.length * 3;
short count = 0;
int j = 0;
float[] fixedvertices = new float[n_points];
float[] fixednormals = new float[n_points];
short[] fixedfaces = new short[faces.length];
for(int i = 0; i < n_points; i+=3)
{
j = i/3;
fixedvertices[i] = vertices[faces[j]*3];
fixedvertices[i+1] = vertices[faces[j]*3 + 1];
fixedvertices[i+2] = vertices[faces[j]*3 + 2];
fixednormals[i] = normals[normalIndices[j]*3];
fixednormals[i+1] = normals[normalIndices[j]*3 + 1];
fixednormals[i+2] = normals[normalIndices[j]*3 + 2];
fixedfaces[i/3] = count;
count++;
}
vertices = fixedvertices;
normals = fixednormals;
faces = fixedfaces;
}