[英]How to separately texturize (with different texture files) a 3D model?
我有一个在Blender中制成的3D文件,并导出到Java(.OBJ文件),该文件的纹理分离成一些文件。 在此.obj文件中,它包含一些标定为USEMTL的字段及其部分名称(纹理文件)。 但是,当我在屏幕上绘制时,他仅显示USEMTL的最后一个名称。 我的问题是:我该如何继续使他以正确的方式阅读和构造? 没有重叠其他纹理?
public MLoader(String path, Model m) throws IOException {
@SuppressWarnings("resource")
BufferedReader reader = new BufferedReader(new FileReader(new File(path)));
String line;
while ((line = reader.readLine()) != null) {
if (line.startsWith("v ")) {
float
v1 = Float.valueOf(line.split(" ")[1]),
v2 = Float.valueOf(line.split(" ")[2]),
v3 = Float.valueOf(line.split(" ")[3]);
Vector3f v = new Vector3f (v1, v2, v3);
m.vertex.add(v);
} if (line.startsWith("usemtl ")){
String name = String.valueOf(line.split(" ")[1]);
m.nameTexture.add(name);
continue;
} if (line.startsWith("f ")) {
float
v1 = Float.valueOf(line.split(" ")[1].split("/")[0]),
v2 = Float.valueOf(line.split(" ")[2].split("/")[0]),
v3 = Float.valueOf(line.split(" ")[3].split("/")[0]),
n1 = Float.valueOf(line.split(" ")[1].split("/")[1]),
n2 = Float.valueOf(line.split(" ")[2].split("/")[1]),
n3 = Float.valueOf(line.split(" ")[3].split("/")[1]);
Vector3f
v = new Vector3f (v1, v2, v3),
n = new Vector3f (n1, n2, n3);
m.face.add(new Faces(v, n));
}if (line.startsWith("vt ")) {
float
vt1 = Float.valueOf(line.split(" ")[1]),
vt2 = Float.valueOf(line.split(" ")[2]);
Vector2f vt = new Vector2f (vt1, vt2);
m.vertexTexture.add(vt);
}
}
}
如您所见,我创建了一个IF语句,只是为了获得usemtl的东西(位于.obj文件中)-纹理名称(位于单独的文件中)只是为了查看是否可以单独绑定它们。 但是我很难做到这一点(也许逻辑不在我的身边)。 如何进行?
其他班:
public class Textures {
public Texture[] tx;
public void setNumTex(int i) {
tx = new Texture[i];
}
public void setTexture(String format, String name, int i) {
try {
tx[i] = TextureLoader.getTexture(format, new FileInputStream(new File("res/Textures/" + name + format)));
} catch (IOException e) {
e.printStackTrace();
}
}
public void texturing(Vector2f ft1, Vector2f ft2, int indexx) {
for (int i=0; i<indexx; i++) {
tx[i].bind();
}
glTexCoord2f(ft1.x, ft1.y);
glTexCoord2f(ft2.x, ft2.y);
}
}
public class Renderer {
Model m;
public void loadContent(String objPath) {
//Everithing that is loading is been putting here
m = Model.getModel("res/Models/" + objPath);
m.loadTex();
}
public void render() {
glEnable(GL_SMOOTH);
m.renderModel();
}
}
public class Model {
Textures tx;
List<Vector3f> vertex, norms;
List<Vector2f> vertexTexture;
List<Faces> face;
List<String> nameTexture;
String name[];
private int numTex = 0;
Vector2f
t1 = new Vector2f(), t2 = new Vector2f();
Vector3f
v1 = new Vector3f(), v2 = new Vector3f(), v3 = new Vector3f(),
n1 = new Vector3f(), n2 = new Vector3f(), n3 = new Vector3f(),
public Model(String path)throws
LWJGLException, FileNotFoundException, IOException {
vertex = new ArrayList<Vector3f>();
norms = new ArrayList<Vector3f>();
vertexTexture = new ArrayList<Vector2f>();
face = new ArrayList<Faces>();
nameTexture = new ArrayList<String>();
tx = new Textures();
new MLoader(path, this);
}
public static Model getModel(String path, Vector3f position, Vector3f rotation) {
try {
return new Model(path, position, rotation);
} catch (LWJGLException | IOException e) {
e.printStackTrace();
}
return null;
}
public void loadTex() {
name = new String[nameTexture.toArray().length];
tx.setNumTex(nameTexture.toArray().length);
for (int i=0; i<name.length; i++) {
name[i] = nameTexture.get(i);
numTex += 1;
tx.setTexture(".TGA", name[i], i);
}
}
public void renderModel() {
glPushMatrix();
glPolygonMode(GL_FRONT_AND_BACK, GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_2D);
glBegin(GL_TRIANGLES);
{
for (Faces f : face) {
v1 = vertex.get((int) f.v.x - 1);
v2 = vertex.get((int) f.v.y - 1);
v3 = vertex.get((int) f.v.z - 1);
n1 = vertex.get((int) f.n.x - 1);
n2 = vertex.get((int) f.n.y - 1);
n3 = vertex.get((int) f.n.z - 1);
t1 = vertexTexture.get((int) f.n.x - 1); //
t2 = vertexTexture.get((int) f.n.y - 1); //
//Vertexes
glVertex3f(v1.x, v1.y-3.4f, v1.z-0.53f);
glVertex3f(v2.x, v2.y-3.4f, v2.z-0.53f);
glVertex3f(v3.x, v3.y-3.4f, v3.z-0.53f);
//Normals
glNormal3f(n1.x, n1.y-3.4f, n1.z-0.53f);
glNormal3f(n2.x, n2.y-3.4f, n2.z-0.53f);
glNormal3f(n3.x, n3.y-3.4f, n3.z-0.53f);
//Texture
tx.texturing(t1, t2, numTex);
//tx.texturing(n1, n2, n3);
}
}
glEnd();
glDisable(GL_TEXTURE_2D);
glPopMatrix();
}
}
我不会放置任何代码,因为您的问题对于2行解决方案而言相当复杂,但是在这里它通常是如何在简单的3D引擎中工作的,对网格进行多次纹理化处理意味着将网格分成2个或更多个子网格。我不是搅拌器专家,但我确定它能够像使用Autodesk 3D Studio max一样导出带有其子网格树的网格。现在,将此类网格导入程序时,您应该能够解析所有这些子网格。网格划分为单独的实体。每个此类子网格都有其自己的顶点,纹理坐标和法线。 发出draw调用时,您将一个一个地遍历所有子网格,并在其自己的draw调用中绘制每个子网格。因此在每个draw调用上,您还应该能够附加一个唯一的纹理以用于该特定对象现在就由您来设计这种系统了。 希望能帮助到你。
好的,我发现了问题所在。 解决方案如下:在类MLoader上,我只需要在“ usemtl”部分放置一个“ distinguisher”。 有了它,当他在“ F SECTION”上时,当他返回并将脸添加到“ faceArray”中时,他所添加的就比他需要的更多。
例:face.add(4, 5, 6);
faceArray.add(face); //But, this time, when he adds the face, it already had 1, 2, 3,
//so, he's with '1, 2, 3, 4, 5, 6' into him
当他再次转到“ f”时,他添加
public MLoader(String path, Model m) throws IOException {
...
while ((line = reader.readLine()) != null) {
...
} if (line.contains("g ")) {
index = 0;
} if (line.startsWith("usemtl ") && index == 0){
String name = String.valueOf(line.split(" ")[1]);
m.nameTexture.add(name);
m.faceArray.add(m.face);
m.face = new ArrayList<Faces>();
index = 1;
} if (line.contains("f ") && index == 1) {
...
}
这是我所做的更改(只是更改):
public MLoader(String path, Model m) throws IOException { ... while ((line = reader.readLine()) != null) { ... } if (line.contains("g ")) { index = 0; } if (line.startsWith("usemtl ") && index == 0){ String name = String.valueOf(line.split(" ")[1]); m.nameTexture.add(name); m.faceArray.add(m.face); m.face = new ArrayList<Faces>(); index = 1; } if (line.contains("f ") && index == 1) { ... }
int numTex = 0; List<List <Faces>> faceArray; ... public void loadTex() { for (String n : nameTexture) { tx.loadTexture("TGA", n); numTex ++; } } ... public void renderModel() { ... glEnable(GL_TEXTURE_2D); for (int i = 0; i < numTex; i++) { tx.tx.get(i).bind(); glBegin(GL_TRIANGLES); { for (Faces f : faceArray.get(i)) { ... } } glEnd(); } glDisable(GL_TEXTURE_2D); ... }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.