如何正确加载和绘制这个* .obj?

我有一个*.obj文件(称为GLModel )的加载器类,它有2个主要的方法 –

 public GLModel(BufferedReader ref, boolean centerit, GL gl,Texture texture) 

用于*.obj加载和

 public void opengldraw(GL gl) 

用于绘制在gl

到目前为止,我成功地加载和绘制单个*.obj纹理(如*.png*jpg等)的对象

但是我怎么能画出一个有多个纹理的物体?

例如 – 这个对象包含多个纹理,我试图用合适的*.obj和其中一个纹理来绘制它,并得到与上面的链接相同的形状,但是它的纹理不完全相同。

你能给我一个例子如何正确地工作吗?

编辑:

我从这里下载了这个模型,没有注册。

我到目前为止的绘图是 –

(面前) –

在这里输入图像说明

(背部) –

在这里输入图像说明

我所讲的装载机类是 –

 import java.io.BufferedReader; import java.io.IOException; import java.util.ArrayList; import java.util.StringTokenizer; import javax.media.opengl.GL; import com.sun.opengl.util.texture.Texture; // This class reads Wavefront .obj files public class GLModel { private ArrayList<float[]> vertexsets; private ArrayList<float[]> vertexsetsnorms; private ArrayList<float[]> vertexsetstexs; private ArrayList<int[]> faces; private ArrayList<int[]> facestexs; private ArrayList<int[]> facesnorms; private int objectlist; private int numpolys; public float toppoint; public float bottompoint; public float leftpoint; public float rightpoint; public float farpoint; public float nearpoint; Texture texture; public GLModel(BufferedReader ref, boolean centerit, GL gl, Texture texture){ this.texture=texture; vertexsets = new ArrayList<float[]>(); vertexsetsnorms = new ArrayList<float[]>(); vertexsetstexs = new ArrayList<float[]>(); faces = new ArrayList<int[]>(); facestexs = new ArrayList<int[]>(); facesnorms = new ArrayList<int[]>(); numpolys = 0; toppoint = 0.0F; bottompoint = 0.0F; leftpoint = 0.0F; rightpoint = 0.0F; farpoint = 0.0F; nearpoint = 0.0F; loadobject(ref); if(centerit) centerit(); opengldrawtolist(gl); numpolys = faces.size(); cleanup(); } public GLModel(BufferedReader ref, boolean centerit, GL gl){ vertexsets = new ArrayList<float[]>(); vertexsetsnorms = new ArrayList<float[]>(); vertexsetstexs = new ArrayList<float[]>(); faces = new ArrayList<int[]>(); facestexs = new ArrayList<int[]>(); facesnorms = new ArrayList<int[]>(); numpolys = 0; toppoint = 0.0F; bottompoint = 0.0F; leftpoint = 0.0F; rightpoint = 0.0F; farpoint = 0.0F; nearpoint = 0.0F; loadobject(ref); if(centerit) centerit(); numpolys = faces.size(); cleanup(); } private void cleanup(){ vertexsets.clear(); vertexsetsnorms.clear(); vertexsetstexs.clear(); faces.clear(); facestexs.clear(); facesnorms.clear(); } @SuppressWarnings("unused") private void loadobject(BufferedReader br){ int linecounter = 0; int facecounter = 0; try{ boolean firstpass = true; String newline; while((newline = br.readLine()) != null){ linecounter++; if(newline.length() > 0){ newline = newline.trim(); //LOADS VERTEX COORDINATES if(newline.startsWith("v ")){ float coords[] = new float[4]; newline = newline.substring(2, newline.length()); StringTokenizer st = new StringTokenizer(newline, " "); for(int i = 0; st.hasMoreTokens(); i++) coords[i] = Float.parseFloat(st.nextToken()); if(firstpass){ rightpoint = coords[0]; leftpoint = coords[0]; toppoint = coords[1]; bottompoint = coords[1]; nearpoint = coords[2]; farpoint = coords[2]; firstpass = false; } if(coords[0] > rightpoint) rightpoint = coords[0]; if(coords[0] < leftpoint) leftpoint = coords[0]; if(coords[1] > toppoint) toppoint = coords[1]; if(coords[1] < bottompoint) bottompoint = coords[1]; if(coords[2] > nearpoint) nearpoint = coords[2]; if(coords[2] < farpoint) farpoint = coords[2]; vertexsets.add(coords); } else //LOADS VERTEX TEXTURE COORDINATES if(newline.startsWith("vt")){ float coords[] = new float[4]; newline = newline.substring(3, newline.length()); StringTokenizer st = new StringTokenizer(newline, " "); for(int i = 0; st.hasMoreTokens(); i++) coords[i] = Float.parseFloat(st.nextToken()); vertexsetstexs.add(coords); } else //LOADS VERTEX NORMALS COORDINATES if(newline.startsWith("vn")){ float coords[] = new float[4]; newline = newline.substring(3, newline.length()); StringTokenizer st = new StringTokenizer(newline, " "); for(int i = 0; st.hasMoreTokens(); i++) coords[i] = Float.parseFloat(st.nextToken()); vertexsetsnorms.add(coords); } else //LOADS FACES COORDINATES if(newline.startsWith("f ")){ facecounter++; newline = newline.substring(2, newline.length()); StringTokenizer st = new StringTokenizer(newline, " "); int count = st.countTokens(); int v[] = new int[count]; int vt[] = new int[count]; int vn[] = new int[count]; for(int i = 0; i < count; i++){ char chars[] = st.nextToken().toCharArray(); StringBuffer sb = new StringBuffer(); char lc = 'x'; for(int k = 0; k < chars.length; k++){ if(chars[k] == '/' && lc == '/') sb.append('0'); lc = chars[k]; sb.append(lc); } StringTokenizer st2 = new StringTokenizer (sb.toString(), "/"); int num = st2.countTokens(); v[i] = Integer.parseInt(st2.nextToken()); if(num > 1) vt[i] = Integer.parseInt(st2.nextToken()); else vt[i] = 0; if(num > 2) vn[i] = Integer.parseInt(st2.nextToken()); else vn[i] = 0; } faces.add(v); facestexs.add(vt); facesnorms.add(vn); } else //LOADS MATERIALS if (newline.charAt(0) == 'm' && newline.charAt(1) == 't' && newline.charAt(2) == 'l' && newline.charAt(3) == 'l' && newline.charAt(4) == 'i' && newline.charAt(5) == 'b') {} else //USES MATERIALS if (newline.charAt(0) == 'u' && newline.charAt(1) == 's' && newline.charAt(2) == 'e' && newline.charAt(3) == 'm' && newline.charAt(4) == 't' && newline.charAt(5) == 'l') {} } } } catch(IOException e){ System.out.println("Failed to read file: " + br.toString()); } catch(NumberFormatException e){ System.out.println("Malformed OBJ file: " + br.toString() + "\r \r"+ e.getMessage()); } } private void centerit(){ float xshift = (rightpoint - leftpoint) / 2.0F; float yshift = (toppoint - bottompoint) / 2.0F; float zshift = (nearpoint - farpoint) / 2.0F; for(int i = 0; i < vertexsets.size(); i++){ float coords[] = new float[4]; coords[0] = ((float[])vertexsets.get(i))[0] - leftpoint - xshift; coords[1] = ((float[])vertexsets.get(i))[1] - bottompoint - yshift; coords[2] = ((float[])vertexsets.get(i))[2] - farpoint - zshift; vertexsets.set(i, coords); } } public float getXWidth(){ float returnval = 0.0F; returnval = rightpoint - leftpoint; return returnval; } public float getYHeight(){ float returnval = 0.0F; returnval = toppoint - bottompoint; return returnval; } public float getZDepth(){ float returnval = 0.0F; returnval = nearpoint - farpoint; return returnval; } public int numpolygons(){ return numpolys; } public void opengldrawtolist(GL gl){ // retrieving object list this.objectlist = gl.glGenLists(1); gl.glNewList(objectlist, GL.GL_COMPILE); texture.enable(); texture.bind(); gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T, GL.GL_REPEAT); gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S, GL.GL_REPEAT); gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR); gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR); for (int i=0;i<faces.size();i++) { int[] tempfaces = (int[])(faces.get(i)); int[] tempfacesnorms = (int[])(facesnorms.get(i)); int[] tempfacestexs = (int[])(facestexs.get(i)); //// Quad Begin Header //// int polytype; if (tempfaces.length == 3) { polytype = GL.GL_TRIANGLES; } else if (tempfaces.length == 4) { polytype = GL.GL_QUADS; } else { polytype = GL.GL_POLYGON; } gl.glBegin(polytype); for (int w=0;w<tempfaces.length;w++) { if (tempfacesnorms[w] != 0) { float normtempx = ((float[])vertexsetsnorms.get(tempfacesnorms[w] - 1))[0]; float normtempy = ((float[])vertexsetsnorms.get(tempfacesnorms[w] - 1))[1]; float normtempz = ((float[])vertexsetsnorms.get(tempfacesnorms[w] - 1))[2]; gl.glNormal3f(normtempx, normtempy, normtempz); } if (tempfacestexs[w] != 0) { float textempx = ((float[])vertexsetstexs.get(tempfacestexs[w] - 1))[0]; float textempy = ((float[])vertexsetstexs.get(tempfacestexs[w] - 1))[1]; float textempz = ((float[])vertexsetstexs.get(tempfacestexs[w] - 1))[2]; gl.glTexCoord3f(textempx,1f-textempy,textempz); } float tempx = ((float[])vertexsets.get(tempfaces[w] - 1))[0]; float tempy = ((float[])vertexsets.get(tempfaces[w] - 1))[1]; float tempz = ((float[])vertexsets.get(tempfaces[w] - 1))[2]; gl.glVertex3f(tempx,tempy,tempz); } // Quad End gl.glEnd(); } gl.glEndList(); } public void opengldraw(GL gl) { gl.glCallList(objectlist); } public boolean collision(float[] position) { return false; } public void setTexature(Texture tex) { this.texture = tex; } } 

我使用的*.obj是 – Zero.obj (将其转换为BufferedReader ),我使用的图像是 – AssassinBody_Dif.jpg (将其转换为Texture )。

我在寻找的是 – 如何使用附加的GLModel类完全绘制该模型?

Wavefront obj文件通常与定义所用纹理的材质文件(.mat)结合使用。 模型的网格划分为不同的材质组。 每种材料都会告诉您要使用哪些纹理以及网格的其他信息。

在你的情况下,模型上有单独的网格。 这些网格是头部,身体和手部。 他们都有自己的纹理,你需要将它们应用到正确的网格上才能看起来正确。 网格很可能在网格组,材质组或光照组的.obj文件中分开。 您需要在单独的网格实例中读取它们才能使用不同的纹理渲染它们。

您也遇到了一种称为法线贴图的问题 ,这实质上是将一些高多边形模型的网格数据保存为纹理,以便与低多边形模型一起使用。