1

我最近开始学习 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;
}
4

1 回答 1

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;


}
于 2013-04-21T16:28:32.457 回答