2010-09-24 18 views
1

我是OpenGL的新手。我正在使用JOGL。我下載了model。它有一堆紋理。我試圖在這裏應用「truck_color-blue.jpg」,但我不確定我是否正確。這是我所看到的:OpenGL:我是否弄錯了這個錯誤?

Side by side: by texture and the site's demo

從本質上講,我做的是記錄所有vtv,並且vn條目,那麼f線指標使用到它們。這是使glTexCoord*()調用的代碼:我懷疑我是不是正確匹配了紋理COORDS到頂點

  if (facePoint.textureIndex != null) { 
       Vector2f texCoords = getTexture(facePoint.textureIndex); 
       gl.glTexCoord2f(texCoords.x, texCoords.y); 
      } 

      // ... 

      Point3f vertex = getVertex(facePoint.vertexIndex); 
      gl.glVertex3f(vertex.x, vertex.y, vertex.z); 

。該模型說它是UV映射的。這是否意味着我需要做不同的紋理?

我的代碼讀取.obj文件:

public class ObjModel extends WorldEntity { 

    // ... 

    @Override 
    protected void buildDrawList() { 
     startDrawList(); 

     for (Polygon poly : polygons) { 

      if (poly.getFaces().size() == 4) { 
       gl.glBegin(GL2.GL_QUADS); 
      } else { 
       gl.glBegin(GL2.GL_POLYGON); 
      } 

      for (FacePoint facePoint : poly.getFaces()) { 
       if (facePoint.vertexIndex == null) { 
        throw new RuntimeException("Why was there a face with no vertex?"); 
       } 

       if (facePoint.textureIndex != null) { 
        Vector2f texCoords = getTexture(facePoint.textureIndex); 
        gl.glTexCoord2f(texCoords.x, texCoords.y); 
       } 

       if (facePoint.normalIndex != null) { 
        // why use both Vector3f and Point3f? 
        Vector3f normal = getNormal(facePoint.normalIndex); 
        gl.glNormal3f(normal.x, normal.y, normal.z); 
       } 

       Point3f vertex = getVertex(facePoint.vertexIndex); 
       gl.glVertex3f(vertex.x, vertex.y, vertex.z); 
      } 
      gl.glEnd(); 
     } 

     endDrawList(); 
    } 

    private Point3f getVertex(int index) { 
     if (index >= 0) { 
      // -1 is necessary b/c .obj is 1 indexed, but vertices is 0 indexed. 
      return vertices.get(index - 1); 
     } else { 
      return vertices.get(vertices.size() + index); 
     } 
    } 

    private Vector3f getNormal(int index) { 
     if (index >= 0) { 
      return normals.get(index - 1); 
     } else { 
      return normals.get(normals.size() + index); 
     } 
    } 

    private Vector2f getTexture(int index) { 
     if (index >= 0) { 
      return textures.get(index - 1); 
     } else { 
      return textures.get(textures.size() + index); 
     } 
    } 

    private void readFile(String fileName) { 
     try { 
      BufferedReader input = new BufferedReader(new FileReader(fileName)); 
      try { 
       String currLine = null; 
       while ((currLine = input.readLine()) != null) { 

        int indVn = currLine.indexOf("vn "); 
        if (indVn != -1) { 
         readNormal(currLine); 
         continue; 
        } 

        int indV = currLine.indexOf("v "); 
        if (indV != -1) { 
         readVertex(currLine); 
         continue; 
        } 

        int indF = currLine.indexOf("f "); 
        if (indF != -1) { 
         readPolygon(currLine); 
         continue; 
        } 

        int indVt = currLine.indexOf("vt "); 
        if (indVt != -1) { 
         readTexture(currLine); 
         continue; 
        } 
       } 
      } finally { 
       input.close(); 
      } 
     } catch (IOException ex) { 
      ex.printStackTrace(); 
     } 
    } 

    private void readVertex(String newLine) { 
     String pieces[] = newLine.split("\\s+"); 
     Point3f vertex = new Point3f(Float.parseFloat(pieces[1]), Float.parseFloat(pieces[2]), Float.parseFloat(pieces[3])); 
     vertices.add(vertex); 
    } 

    private void readNormal(String newLine) { 
     String pieces[] = newLine.split("\\s+"); 
     Vector3f norm = new Vector3f(Float.parseFloat(pieces[1]), Float.parseFloat(pieces[2]), Float.parseFloat(pieces[3])); 
     normals.add(norm); 
    } 

    private void readTexture(String newLine) { 
     String pieces[] = newLine.split("\\s+"); 
     Vector2f tex = new Vector2f(Float.parseFloat(pieces[1]), Float.parseFloat(pieces[2])); 
     textures.add(tex); 
    } 

    private void readPolygon(String newLine) { 
     polygons.add(new Polygon(newLine)); 
    } 
} 

類多邊形代表像f 1/2/3 4/5/6 7/8/9線。

公共類多邊形私人List faces = new ArrayList();

public Polygon(String line) { 
    if (line.charAt(0) != 'f') { 
     throw new IllegalArgumentException(String.format("Line must be a face definition, but was: '%s'", line)); 
    } 

    String[] facePointDefs = line.split("\\s+"); 

    // ignore the first piece - it will be "f ". 
    for (int i = 1; i < facePointDefs.length; i++) { 
     faces.add(new FacePoint(facePointDefs[i])); 
    } 
} 

public List<FacePoint> getFaces() { 
    return Collections.unmodifiableList(faces); 
} 

}

類FacePoint表示麪點,像21/342/231

public class FacePoint { 

    private static final String FACE_POINT_REGEX = "^(\\d+)\\/(\\d+)?(\\/(\\d+))?$"; 

    public Integer vertexIndex; 
    public Integer textureIndex; 
    public Integer normalIndex; 

    public FacePoint(String facePointDef) { 
     Matcher matcher = Pattern.compile(FACE_POINT_REGEX).matcher(facePointDef); 

     if (!matcher.find()) { 
      throw new IllegalArgumentException(String.format("facePointDef is invalid: '%s'", facePointDef)); 
     } 

     String vertexMatch = matcher.group(1); 
     if (vertexMatch == null) { 
      throw new IllegalArgumentException(String.format("The face point definition didn't contain a vertex: '%s'", 
        facePointDef)); 
     } 
     vertexIndex = Integer.parseInt(vertexMatch); 

     String texMatch = matcher.group(2); 
     if (texMatch != null) { 
      textureIndex = Integer.parseInt(texMatch); 
     } 

     String normalMatch = matcher.group(4); 
     if (normalMatch != null) { 
      normalIndex = Integer.parseInt(normalMatch); 
     } 
    } 
} 
+0

紋理看起來不像是太可怕的錯誤。你有嘗試在glTexCoord調用中交換texCoords.x/texCoords.y嗎? – dave 2010-09-24 21:47:20

+0

是的,我嘗試過,但它仍然看起來很搞亂。 – 2010-09-24 22:44:59

+0

好吧,看了看實際的紋理,看起來你已經將紋理數據垂直翻轉了。嘗試在glTexCoord調用中將texCoords.y更改爲(1.0f - texCoords.y) – dave 2010-09-24 23:42:05

回答

0

在OpenGL中,紋理原點位於左下角,而不是左上角。這可能會搞亂你的紋理。如果這是問題,一個簡單的解決方法是從1:glTexCoord2f(texCoords.x, 1.0f - texCoords.y)減去y紋理座標。 (這與垂直翻轉紋理的效果相同。)

相關問題