2012-12-09 2 views
2

LWJGL 및 그 텍스처에 .obj 파일을로드하는 데 문제가 있습니다. 목적은 나무이다 (이것은 터보 스퀴드에서 유료 모델, 그래서 난 여기를 게시 할 수 없습니다, 그러나 여기 당신이 그것을 같이하는 방법을보고 싶다면 링크의) : http://www.turbosquid.com/FullPreview/Index.cfm/ID/701294LWJGL에로드 된 OBJ 모델에 텍스처가없는 검은 색 영역이 있습니다.

내가 정의 OBJ를 썼다 로더는 위키에서 LWJGL 자습서를 사용합니다. 그것은 다음과 같습니다

public class OBJLoader { 
public static Model loadModel(File f) throws FileNotFoundException, IOException 
{ 
    BufferedReader reader = new BufferedReader(new FileReader(f)); 

    Model m = new Model(); 
    String line; 
    Texture currentTexture = null; 
    while((line=reader.readLine()) != null) 
    { 
     if(line.startsWith("v ")) 
     { 
      float x = Float.valueOf(line.split(" ")[1]); 
      float y = Float.valueOf(line.split(" ")[2]); 
      float z = Float.valueOf(line.split(" ")[3]); 
      m.verticies.add(new Vector3f(x,y,z)); 
     }else if(line.startsWith("vn ")) 
     { 
      float x = Float.valueOf(line.split(" ")[1]); 
      float y = Float.valueOf(line.split(" ")[2]); 
      float z = Float.valueOf(line.split(" ")[3]); 
      m.normals.add(new Vector3f(x,y,z)); 
     }else if(line.startsWith("vt ")) 
     { 
      float x = Float.valueOf(line.split(" ")[1]); 
      float y = Float.valueOf(line.split(" ")[2]); 
      m.texVerticies.add(new Vector2f(x,y)); 
     }else if(line.startsWith("f ")) 
     { 
      Vector3f vertexIndicies = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[0]), 
        Float.valueOf(line.split(" ")[2].split("/")[0]), 
        Float.valueOf(line.split(" ")[3].split("/")[0])); 
      Vector3f textureIndicies = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[1]), 
        Float.valueOf(line.split(" ")[2].split("/")[1]), 
        Float.valueOf(line.split(" ")[3].split("/")[1])); 
      Vector3f normalIndicies = new Vector3f(Float.valueOf(line.split(" ")[1].split("/")[2]), 
        Float.valueOf(line.split(" ")[2].split("/")[2]), 
        Float.valueOf(line.split(" ")[3].split("/")[2])); 

      m.faces.add(new Face(vertexIndicies,textureIndicies,normalIndicies,currentTexture.getTextureID())); 
     }else if(line.startsWith("g ")) 
     { 
      if(line.length()>2) 
      { 
       String name = line.split(" ")[1]; 
       currentTexture = TextureLoader.getTexture("PNG", ResourceLoader.getResourceAsStream("res/" + name + ".png")); 
       System.out.println(currentTexture.getTextureID()); 
      } 
     } 
    } 


    reader.close(); 

    System.out.println(m.verticies.size() + " verticies"); 
    System.out.println(m.normals.size() + " normals"); 
    System.out.println(m.texVerticies.size() + " texture coordinates"); 
    System.out.println(m.faces.size() + " faces"); 
    return m; 
} 
} 

그런 다음이 코드를 사용하여 내 모델의 표시 목록을 만들 :

objectDisplayList = GL11.glGenLists(1); 
    GL11.glNewList(objectDisplayList, GL11.GL_COMPILE); 
    Model m = null; 
    try { 
     m = OBJLoader.loadModel(new File("res/untitled4.obj")); 
    } catch (Exception e1) { 
     e1.printStackTrace(); 
    } 

    int currentTexture=0; 
    for(Face face: m.faces) 
    { 
     if(face.texture!=currentTexture) 
     { 
      currentTexture = face.texture; 
      GL11.glBindTexture(GL11.GL_TEXTURE_2D, currentTexture); 
     } 


     GL11.glColor3f(1f, 1f, 1f); 
     GL11.glBegin(GL11.GL_TRIANGLES); 

     Vector3f n1 = m.normals.get((int) face.normal.x - 1); 
     GL11.glNormal3f(n1.x, n1.y, n1.z); 
     Vector2f t1 = m.texVerticies.get((int) face.textures.x -1); 
     GL11.glTexCoord2f(t1.x, t1.y); 
     Vector3f v1 = m.verticies.get((int) face.vertex.x - 1); 
     GL11.glVertex3f(v1.x, v1.y, v1.z); 



     Vector3f n2 = m.normals.get((int) face.normal.y - 1); 
     GL11.glNormal3f(n2.x, n2.y, n2.z); 
     Vector2f t2 = m.texVerticies.get((int) face.textures.y -1); 
     GL11.glTexCoord2f(t2.x, t2.y); 
     Vector3f v2 = m.verticies.get((int) face.vertex.y - 1); 
     GL11.glVertex3f(v2.x, v2.y, v2.z); 


     Vector3f n3 = m.normals.get((int) face.normal.z - 1); 
     GL11.glNormal3f(n3.x, n3.y, n3.z); 
     Vector2f t3 = m.texVerticies.get((int) face.textures.z -1); 
     GL11.glTexCoord2f(t3.x, t3.y); 
     Vector3f v3 = m.verticies.get((int) face.vertex.z - 1); 
     GL11.glVertex3f(v3.x, v3.y, v3.z); 

     GL11.glEnd(); 
    } 
    GL11.glEndList(); 

currentTexture은 INT - 그것은 현재 사용되는 텍스처의 ID가 포함되어 있습니다. 1

하지만 GL_TEXTURE_2D 사용하도록 설정하면 어떻게되는지 살펴 :

그래서 내 모델은 텍스처없이 절대적으로 잘 보이는 당신의 전체면을 볼 수 있듯이
2
3
4

트리가 누락 된 것처럼 보입니다. 투명하지 않습니다. 배경색이 아니기 때문에 투명하지 않습니다. 검은 색으로 렌더링됩니다.

이 모델에 문제가 아니에요 - 나는 5

이 내 OpenGL을 초기화이다 (나는 내 ​​자신의 OBJ 로더를 작성할 필요하지만 것입니다) 그것이 잘 작동 한자의 OBJ 로더를 사용하여로드하는 경우 섹션 :

//init display 
    try { 
     Display.setDisplayMode(new DisplayMode(Support.SCREEN_WIDTH, Support.SCREEN_HEIGHT)); 
     Display.create(); 
     Display.setVSyncEnabled(true); 
    } catch (LWJGLException e) { 
     e.printStackTrace(); 
     System.exit(0); 
    } 
    GL11.glLoadIdentity(); 
    GL11.glEnable(GL11.GL_TEXTURE_2D);    
    GL11.glClearColor(1.0f, 0.0f, 0.0f, 1.0f);   

    GL11.glShadeModel(GL11.GL_SMOOTH); 
    GL11.glEnable(GL11.GL_DEPTH_TEST); 
    GL11.glDepthFunc(GL11.GL_LESS); 
    GL11.glDepthMask(true); 
    GL11.glEnable(GL11.GL_NORMALIZE); 



    GL11.glMatrixMode(GL11.GL_PROJECTION); 

    GLU.gluPerspective (90.0f,800f/600f, 1f, 500.0f); 
    GL11.glMatrixMode(GL11.GL_MODELVIEW); 

    GL11.glEnable(GL11.GL_CULL_FACE); 
    GL11.glCullFace(GL11.GL_BACK); 

    //enable lighting 
    GL11.glEnable(GL11.GL_LIGHTING); 

    ByteBuffer temp = ByteBuffer.allocateDirect(16); 
    temp.order(ByteOrder.nativeOrder()); 

    GL11.glMaterial(GL11.GL_FRONT, GL11.GL_DIFFUSE, (FloatBuffer)temp.asFloatBuffer().put(lightDiffuse).flip()); 
    GL11.glMaterialf(GL11.GL_FRONT, GL11.GL_SHININESS,(int)material_shinyness); 

    GL11.glLight(GL11.GL_LIGHT2, GL11.GL_DIFFUSE, (FloatBuffer)temp.asFloatBuffer().put(lightDiffuse2).flip());    // Setup The Diffuse Light 
    GL11.glLight(GL11.GL_LIGHT2, GL11.GL_POSITION,(FloatBuffer)temp.asFloatBuffer().put(lightPosition2).flip()); 
    GL11.glLight(GL11.GL_LIGHT2, GL11.GL_AMBIENT,(FloatBuffer)temp.asFloatBuffer().put(lightAmbient).flip()); 
    GL11.glLight(GL11.GL_LIGHT2, GL11.GL_SPECULAR,(FloatBuffer)temp.asFloatBuffer().put(lightDiffuse2).flip()); 

    GL11.glLightf(GL11.GL_LIGHT2, GL11.GL_CONSTANT_ATTENUATION, 0.1f); 
    GL11.glLightf(GL11.GL_LIGHT2, GL11.GL_LINEAR_ATTENUATION, 0.0f); 
    GL11.glLightf(GL11.GL_LIGHT2, GL11.GL_QUADRATIC_ATTENUATION, 0.0f); 
    GL11.glEnable(GL11.GL_LIGHT2); 

나는 같은 나무의 다른 모델을 가지고 있습니다 - 더 자세한 방법, 믹서기에서 똑바로 내 보낸 것도 똑같습니다.

+0

너무 많은 코드입니다. – OmniOwl

+2

Obj 파일의 UV와 파서의 UV를 비교하십시오. 파서가 파손될 수 있습니다. –

+0

좋아, 내가 그것을 개선 할 수 있었다 .... 텍스처에 대한 V 매개 변수는 모델에 적용되기 전에 1에서 빼야한다. 따라서 OBJ 로더의 코드는 다음과 같습니다. m.texVerticies.add (새 Vector2f (x, 1-y)); 이렇게하면 나무 꼭대기가 올바르게 나타납니다. 그러나 측면은 여전히 ​​검은 색이어서 트리의 아래쪽도 검은 색입니다. – gambiting

답변

1

내가 대답 할 수 없기 때문에 여기에 대답하고 있습니다.

코드를 읽지 않았으므로 얼굴의 방향 (즉, 정점이 인덱싱 된 순서)에 신경 쓰지 않는 것처럼 들리는군요. 방향이 잘못되면 텍스처 좌표도 뒤집어 져야합니다.

0

objet를 읽고 표시 목록을 만들 때 점을 적어 놓으면 텍스처 좌표가 계산되지 않습니다. 모든 꼭지점이 텍스처 좌표를 갖는 것은 아니라는 것이 문제 일 수 있습니다. 또는 texure의 크기가 양방향으로 2^x 크기인지 확인하십시오. 그것은 도움이 될 것입니다.