未正确加载LWJGL中的.obj文件

时间:2014-02-23 14:27:45

标签: java opengl lwjgl

我的.obj文件阅读器有问题。 .obj-File如下所示:

# Blender3D v249 OBJ File: untitled.blend
# www.blender3d.org
mtllib cube.mtl
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vt 0.748573 0.750412
vt 0.749279 0.501284
vt 0.999110 0.501077
vt 0.999455 0.750380
vt 0.250471 0.500702
vt 0.249682 0.749677
vt 0.001085 0.750380
vt 0.001517 0.499994
vt 0.499422 0.500239
vt 0.500149 0.750166
vt 0.748355 0.998230
vt 0.500193 0.998728
vt 0.498993 0.250415
vt 0.748953 0.250920
vn 0.000000 0.000000 -1.000000
vn -1.000000 -0.000000 -0.000000
vn -0.000000 -0.000000 1.000000
vn -0.000001 0.000000 1.000000
vn 1.000000 -0.000000 0.000000
vn 1.000000 0.000000 0.000001
vn 0.000000 1.000000 -0.000000
vn -0.000000 -1.000000 0.000000
usemtl Material_ray.png
s off
f 5/1/1 1/2/1 4/3/1
f 5/1/1 4/3/1 8/4/1
f 3/5/2 7/6/2 8/7/2
f 3/5/2 8/7/2 4/8/2
f 2/9/3 6/10/3 3/5/3
f 6/10/4 7/6/4 3/5/4
f 1/2/5 5/1/5 2/9/5
f 5/1/6 6/10/6 2/9/6
f 5/1/7 8/11/7 6/10/7
f 8/11/7 7/12/7 6/10/7
f 1/2/8 2/9/8 3/13/8
f 1/2/8 3/13/8 4/14/8

模型 - 装载机级:

package com.crystalcode.lwjgl;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

import org.lwjgl.util.vector.Vector3f;

public class Model
{
    private ArrayList <Vector3f> vertexList;
    private ArrayList <Vector3f> textureList;
    private ArrayList <Vector3f> normalList;

    public Model(String obj)
    {
        vertexList = new ArrayList<>();
        textureList = new ArrayList<>();
        normalList = new ArrayList<>();

        try
        {           
            BufferedReader bufferedReader = new BufferedReader(new FileReader(obj));
            String line = "";

            while ((line = bufferedReader.readLine()) != null)
            {
                if (line.startsWith("f "))
                {
                    // Split the line
                        String[] values = line.split(" ");

                    // Parse the vertex indices
                        float v1 = Float.parseFloat(values[1].split("/")[0]);
                        float v2 = Float.parseFloat(values[2].split("/")[0]);
                        float v3 = Float.parseFloat(values[3].split("/")[0]);

                        Vector3f vertex = new Vector3f(v1, v2, v3);
                        vertexList.add(vertex);

                    // Parse the texture indices
                        float vt1 = Float.parseFloat(values[1].split("/")[1]);
                        float vt2 = Float.parseFloat(values[2].split("/")[1]);
                        float vt3 = Float.parseFloat(values[3].split("/")[1]);

                        Vector3f texture = new Vector3f(vt1, vt2, vt3);
                        textureList.add(texture);

                    // Parse the normal indices
                        float vn1 = Float.parseFloat(values[1].split("/")[2]);
                        float vn2 = Float.parseFloat(values[2].split("/")[2]);
                        float vn3 = Float.parseFloat(values[3].split("/")[2]);

                        Vector3f normal = new Vector3f(vn1, vn2, vn3);
                        normalList.add(normal);

                    // Debug
                        System.out.println ("Vertex: " + vertex.toString() + "\t\tTexture: " + texture.toString() + "\tNormal: " + normal.toString());

                }
            }
        } catch (FileNotFoundException e)
        {
            e.printStackTrace();
        } catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public float[] getVertex()
    {       
        int counter = 0;

        float[] vertexArray;
        vertexArray = new float[vertexList.size() * 3];

        for (Vector3f vertex : vertexList)
        {
            vertexArray[counter + 0] = vertex.x;
            vertexArray[counter + 1] = vertex.y;
            vertexArray[counter + 2] = vertex.z;

            counter += 3;
        }

        return vertexArray;
    }

    public float[] getColor()
    {       
        int counter = 0;

        float[] colorArray;
        colorArray = new float[vertexList.size() * 3];

        for (Vector3f vertex : vertexList)
        {
            colorArray[counter + 0] = (float) Math.random();
            colorArray[counter + 1] = (float) Math.random();
            colorArray[counter + 2] = (float) Math.random();

            counter += 3;
        }

        return colorArray;
    }
}

将按以下方式读出面孔:

Vertex: Vector3f[5.0, 1.0, 4.0]     Texture: Vector3f[1.0, 2.0, 3.0]    Normal: Vector3f[1.0, 1.0, 1.0]
Vertex: Vector3f[5.0, 4.0, 8.0]     Texture: Vector3f[1.0, 3.0, 4.0]    Normal: Vector3f[1.0, 1.0, 1.0]
Vertex: Vector3f[3.0, 7.0, 8.0]     Texture: Vector3f[5.0, 6.0, 7.0]    Normal: Vector3f[2.0, 2.0, 2.0]
Vertex: Vector3f[3.0, 8.0, 4.0]     Texture: Vector3f[5.0, 7.0, 8.0]    Normal: Vector3f[2.0, 2.0, 2.0]
Vertex: Vector3f[2.0, 6.0, 3.0]     Texture: Vector3f[9.0, 10.0, 5.0]   Normal: Vector3f[3.0, 3.0, 3.0]
Vertex: Vector3f[6.0, 7.0, 3.0]     Texture: Vector3f[10.0, 6.0, 5.0]   Normal: Vector3f[4.0, 4.0, 4.0]
Vertex: Vector3f[1.0, 5.0, 2.0]     Texture: Vector3f[2.0, 1.0, 9.0]    Normal: Vector3f[5.0, 5.0, 5.0]
Vertex: Vector3f[5.0, 6.0, 2.0]     Texture: Vector3f[1.0, 10.0, 9.0]   Normal: Vector3f[6.0, 6.0, 6.0]
Vertex: Vector3f[5.0, 8.0, 6.0]     Texture: Vector3f[1.0, 11.0, 10.0]  Normal: Vector3f[7.0, 7.0, 7.0]
Vertex: Vector3f[8.0, 7.0, 6.0]     Texture: Vector3f[11.0, 12.0, 10.0] Normal: Vector3f[7.0, 7.0, 7.0]
Vertex: Vector3f[1.0, 2.0, 3.0]     Texture: Vector3f[2.0, 9.0, 13.0]   Normal: Vector3f[8.0, 8.0, 8.0]
Vertex: Vector3f[1.0, 3.0, 4.0]     Texture: Vector3f[2.0, 13.0, 14.0]  Normal: Vector3f[8.0, 8.0, 8.0]

但如果我渲染VBO,它看起来如下:

纹理被忽略,四边形用随机颜色填充。

我错了什么?

2 个答案:

答案 0 :(得分:0)

根据您的代码,顶点颜色似乎是使用Math.random()在getColor()中生成的。您是否也在其他代码中上传图像纹理?

答案 1 :(得分:0)

哦,现在我明白了。您正在使用纹理坐标的索引作为坐标本身。你应该看一下specs of the OBJ file format。通过将顶点,法线和纹理坐标链接在一起来制作面。