在 LWJGL 中加载 MTL 文件



所以我正在用LWJGL做一个"游戏",我开始加载3D模型(使用Wavefront .obj文件(。我已经成功加载了模型,但我想尝试 .mtl 文件来指定材质,而不是纹理。我"有点"做到了,但它似乎没有完全工作。这是我的代码,以及我尝试渲染的树模型的图片:树模型

现在这是我的代码:

    private static OBJMesh mesh;
public static Mesh load3DModel(String objFileName)
{
    mesh = new OBJMesh();
    BufferedReader reader = null;
    try
    {
        reader = new BufferedReader(new FileReader(new File(objFileName)));
    }
    catch (FileNotFoundException e)
    {
        System.err.println("Could not locate OBJ File at " + objFileName);
        e.printStackTrace();
    }
    String mtlFileName = null;
    String line = null;
    String currentFaceMat = null;
    try
    {
        while ((line = reader.readLine()) != null)
        {
            String[] lineParts = line.split(" ");
            switch (line.substring(0, 2))
            {
            case "v ":
                Vertex v = new Vertex(lineParts[1], lineParts[2], lineParts[3]);
                mesh.addVertex(v);
                break;
            case "vn":
                Normal n = new Normal(lineParts[1], lineParts[2], lineParts[3]);
                mesh.addNormal(n);
                break;
            case "mt":
                mtlFileName = FileHelper.getDirectory(objFileName) + lineParts[1];
                break;
            case "us":
                currentFaceMat = lineParts[1];
                break;
            case "f ":
                Face face = createFace(currentFaceMat, lineParts);
                mesh.addFace(face);
                break;
            }
        }
        reader = new BufferedReader(new FileReader(mtlFileName));
        Material mat = null;
        while ((line = reader.readLine()) != null)
        {
            String[] lineParts = line.split(" ");
            if (line.length() > 1)
            {
                switch (line.substring(0, 2))
                {
                case "ne":
                    mat = new Material(lineParts[1]);
                    mesh.addMaterial(lineParts[1], mat);
                    break;
                case "Ka":
                    mat.setKa(createVector(lineParts));
                    break;
                case "Kd":
                    mat.setKd(createVector(lineParts));
                    break;
                case "Ks":
                    mat.setKs(createVector(lineParts));
                    break;
                case "Ns":
                    mat.setNs(Float.parseFloat(lineParts[1]));
                    break;
                case "d ":
                    mat.setD(Float.parseFloat(lineParts[1]));
                    break;
                case "il":
                    mat.setIllum(Integer.parseInt(lineParts[1]));
                    break;
                }
            }
        }
        reader.close();
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
    mesh.normalArray = new float[mesh.vertices.size() * 3];
    for (Face face : mesh.faces)
    {
        decodeNormals(face.indices1);
        decodeNormals(face.indices2);
        decodeNormals(face.indices3);
    }
    mesh.vertexArray = new float[mesh.vertices.size() * 3];
    mesh.indexArray = new int[mesh.indices.size() * 3];
    mesh.colorArray = new float[mesh.faces.size() * 3];
    int vertexPointer = 0;
    for (Vertex vertex : mesh.vertices)
    {
        mesh.vertexArray[vertexPointer++] = vertex.x;
        mesh.vertexArray[vertexPointer++] = vertex.y;
        mesh.vertexArray[vertexPointer++] = vertex.z;
    }
    for (int i = 0; i < mesh.indices.size(); i++)
    {
        mesh.indexArray[i] = mesh.indices.get(i);
    }
    int colorPointer = 0;
    for (Face face : mesh.faces)
    {
        mesh.colorArray[colorPointer++] = mesh.materials.get(face.material).Kd.x;
        mesh.colorArray[colorPointer++] = mesh.materials.get(face.material).Kd.y;
        mesh.colorArray[colorPointer++] = mesh.materials.get(face.material).Kd.z;
    }
    return MeshLoader.genVertexModel(mesh.vertexArray, mesh.indexArray, mesh.colorArray);
}
private static Face createFace(String materialName, String[] lineData)
{
    String[] indices1 = General.replaceEmptySlashes(lineData[1]).split("/");
    String[] indices2 = General.replaceEmptySlashes(lineData[2]).split("/");
    String[] indices3 = General.replaceEmptySlashes(lineData[3]).split("/");
    return new Face(materialName, indices1, indices2, indices3);
}
private static Vector3f createVector(String[] lineData)
{
    float x = Float.parseFloat(lineData[1]);
    float y = Float.parseFloat(lineData[2]);
    float z = Float.parseFloat(lineData[3]);
    return new Vector3f(x, y, z);
}
private static void decodeNormals(Vector3f vertex)
{
    int vertexPointer = (int) vertex.x - 1;
    mesh.indices.add(vertexPointer);
    Normal normal = mesh.normals.get((int) vertex.z - 1);
    mesh.normalArray[vertexPointer * 3] = normal.x;
    mesh.normalArray[vertexPointer * 3 + 1] = normal.y;
    mesh.normalArray[vertexPointer * 3 + 2] = normal.z;
}

OBJMesh 类:

    public List<Vertex> vertices = new ArrayList<Vertex>();
public List<Normal> normals = new ArrayList<Normal>();
public List<Integer> indices = new ArrayList<Integer>();
public List<Face> faces = new ArrayList<Face>();
public Map<String, Material> materials = new HashMap<String, Material>();
public float[] vertexArray;
public float[] normalArray;
public float[] colorArray;
public int[] indexArray;
public void addVertex(Vertex vertex)
{
    vertices.add(vertex);
}
public void addNormal(Normal normal)
{
    normals.add(normal);
}
public void addMaterial(String name, Material material)
{
    materials.put(name, material);
}
public void addFace(Face face)
{
    faces.add(face);
}

人脸类:

    public Vector3f indices1;
public Vector3f indices2;
public Vector3f indices3;
public String material;
public Face(String material, String[] v1, String[] v2, String[] v3)
{
    this.material = material;
    this.indices1 = new Vector3f(Float.parseFloat(v1[0]), Float.parseFloat(v1[1]), Float.parseFloat(v1[2]));
    this.indices2 = new Vector3f(Float.parseFloat(v2[0]), Float.parseFloat(v2[1]), Float.parseFloat(v2[2]));
    this.indices3 = new Vector3f(Float.parseFloat(v3[0]), Float.parseFloat(v3[1]), Float.parseFloat(v3[2]));
}

材料类仅包含 RGB 值。

如果你能找到什么,请告诉我;我已经搜索了几个星期(不是开玩笑!谢谢

OpenGL希望所有顶点属性都是每个顶点。您目前填充colorArray的方式表明您只是在每张脸上这样做。更改此设置,它应该给出正确的结果。

最新更新