所以我正在与LWJGL进行“游戏”,我开始加载3D模型(使用Wavefront .obj文件)。我已成功加载模型,但我没有使用纹理,而是想尝试.mtl文件,以指定材质。我“有点”做到了,但似乎并没有完全奏效。这是我的代码,以及我试图渲染的Tree模型的图片: Tree Model
现在这是我的代码:
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);
}
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]));
}
Material类只包含 RGB 值。
如果你能找到一些东西,请告诉我;我一直在寻找几周(不开玩笑!)。谢谢
答案 0 :(得分:0)
OpenGL期望所有顶点属性都是每顶点的。你现在填充colorArray
的方式表明你只是这样做。改变这一点,它应该给出正确的结果。