2012-12-14 32 views
0

編輯:我已經回答了問題,代碼已更改,因此它可用,隨意在自己的項目中使用代碼。親切的問候,利亞姆LWJGL的顯示問題

我目前正在LWJGL的3D模型渲染工作,我遇到了一個問題,當我運行該程序的顯示器出現,一切工作與模型分開。我測試了三維空間代碼,並繪製了一些隨機點,我可以看到它們並四處走動,所以我的3D​​空間代碼正在工作,但不是模型代碼。

我的問題是folows,是有什麼錯我的顯示代碼還是我的模型加載代碼,下面是我的源代碼(我的長代碼量抱歉,但我不能縮短它)。

主要遊戲線程:

public class GameThread implements Runnable { 

private boolean running; 
private Camera cam = new Camera(0, 0, 0, 0, 0.25f, 25, new int[] {Keyboard.KEY_W, Keyboard.KEY_S, Keyboard.KEY_A, Keyboard.KEY_D}); 
private Model testModel; 

@Override 
public void run() 
{ 
    initialize(); 

    while(running) 
    { 
     if(Display.isCloseRequested()) 
      tryClose(); 

     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
     tick(); 
     Display.update(); 
    } 

    close(); 
} 

private void initialize() 
{ 
    try 
    { 
     Display.setTitle("Test Game"); 
     Display.setDisplayMode(new DisplayMode(1280, 768)); 
     Display.setVSyncEnabled(true); 
     Display.create(); 

     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     gluPerspective((float) 30, 1024f/768f, 0.001f, 100); 
     glMatrixMode(GL_MODELVIEW); 

     glEnable(GL_DEPTH_TEST); 
     glEnable(GL_TEXTURE_2D); 
     glEnable(GL_BLEND); 
     glEnable(GL_ALPHA_TEST); 
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 

     testModel = new Model(this.getClass().getClassLoader().getResource("res\\untitled.obj"), new Vector3f(0, 0, 0), new Vector3f(0, 0, 0)); 
     cam.setPosition(new Vector3f(0, 0, -10)); 

     running = true; 
    } 
    catch(Exception e) 
    { 
     Display.destroy(); 
     e.printStackTrace(); 
     System.exit(1); 
    } 
} 

private void tick() 
{ 
    cam.update(); 

    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 
    testModel.draw(); 
} 

private void tryClose() 
{ 
    running = false; 
} 

private void close() 
{ 
    Display.destroy(); 
} 

模型加載/渲染代碼:

public class Model { 

private HashMap<String, ModelGroup> groups = new HashMap<String, ModelGroup>(); 
private Vector3f position, rotation; 

public Model(URL modelLocation, Vector3f position, Vector3f rotation) 
{ 
    this.setPosition(position); 
    this.setRotation(rotation); 

    try 
    { 
     BufferedReader in = new BufferedReader(new InputStreamReader(modelLocation.openStream())); 

     String line; 
     ModelGroup group = new ModelGroup("default"); 

     while((line = in.readLine()) != null) 
     { 
      if(line.startsWith("g ")) 
      { 
       String newGroupName = (new StringTokenizer(line)).nextToken(); 

       if(newGroupName.equals(group.getGroupName())) 
        continue; 

       groups.put(group.getGroupName(), group); 
       group = new ModelGroup(newGroupName); 
      } 
      else if(line.startsWith("v ")) 
      { 
       StringTokenizer vertices = new StringTokenizer(line); 

       vertices.nextToken(); // Skips 'v' 

       float x, y, z, w = 1; 

       x = Float.valueOf(vertices.nextToken()); 
       y = Float.valueOf(vertices.nextToken()); 
       z = Float.valueOf(vertices.nextToken()); 

       if(vertices.hasMoreTokens()) 
        w = Float.valueOf(vertices.nextToken()); 
       else 
        w = 1; 

       group.addVertice(new Vector4f(x, y, z, w));     
      } 
      else if(line.startsWith("vn ")) 
      { 
       StringTokenizer normalVertices = new StringTokenizer(line); 

       normalVertices.nextToken(); // Skips 'vn' 

       float x, y, z; 

       x = Float.valueOf(normalVertices.nextToken()); 
       y = Float.valueOf(normalVertices.nextToken()); 
       z = Float.valueOf(normalVertices.nextToken()); 

       group.addNormal(new Vector3f(x, y, z)); 
      } 
      else if(line.startsWith("vt ")) 
      { 
       StringTokenizer textureVertices = new StringTokenizer(line); 

       textureVertices.nextToken(); // Skips 'vt' 

       float u, v, w; 

       u = Float.valueOf(textureVertices.nextToken()); 

       if(textureVertices.hasMoreTokens()) 
        v = Float.valueOf(textureVertices.nextToken()); 
       else 
        v = 0; 

       if(textureVertices.hasMoreTokens()) 
        w = Float.valueOf(textureVertices.nextToken()); 
       else 
        w = 0; 

       group.addTextureCoordinate(new Vector3f(u, v, w)); 
      } 
      else if(line.startsWith("f ")) 
      { 
       StringTokenizer token = new StringTokenizer(line.replace('f', ' ')); 
       String[] indices = new String[token.countTokens()]; 

       int polygon_type = (indices.length == 3 ? GL_TRIANGLES : GL_QUADS); 

       for(int i = 0; i < indices.length; i++) 
        indices[i] = token.nextToken(); 

       int mode = 0; 

       if(line.contains("//")) 
        mode = 3; 

       if(mode != 3) 
        if(indices[0].split("/").length == 2) 
         mode = 1; 
        else if(indices[0].split("/").length == 3) 
         mode = 2; 

       if(mode == 0) 
       { 
        Vector4f vertices = new Vector4f(); 
        vertices.set(Float.valueOf(indices[0]), Float.valueOf(indices[1]), Float.valueOf(indices[2]), (indices.length == 4 ? Float.valueOf(indices[3]) : -1)); 

        group.addFace(new ModelFace(vertices).setPolygonType(polygon_type)); 
       } 
       else if(mode == 1) 
       { 
        float x, y, z, vw; 
        float u, v, tw; 

        x = Float.valueOf(indices[0].split("/")[0]); 
        y = Float.valueOf(indices[1].split("/")[0]); 
        z = Float.valueOf(indices[2].split("/")[0]); 

        if(indices.length == 4) 
         vw = Float.valueOf(indices[3].split("/")[0]); 
        else 
         vw = -1; 

        u = Float.valueOf(indices[0].split("/")[1]); 
        v = Float.valueOf(indices[1].split("/")[1]); 
        tw = Float.valueOf(indices[2].split("/")[1]); 

        group.addFace(new ModelFace(new Vector4f(x, y, z, vw), new Vector3f(u, v, tw), new Vector3f(-1, 0, 0)).setPolygonType(polygon_type)); 
       } 
       else if(mode == 2) 
       { 
        float vx, vy, vz, vw; 
        float u, v, tw; 
        float nx, ny, nz; 

        vx = Float.valueOf(indices[0].split("/")[0]); 
        vy = Float.valueOf(indices[1].split("/")[0]); 
        vz = Float.valueOf(indices[2].split("/")[0]); 

        if(indices.length == 4) 
         vw = Float.valueOf(indices[3].split("/")[0]); 
        else 
         vw = -1; 

        u = Float.valueOf(indices[0].split("/")[1]); 
        v = Float.valueOf(indices[1].split("/")[1]); 
        tw = Float.valueOf(indices[2].split("/")[1]); 

        nx = Float.valueOf(indices[0].split("/")[2]); 
        ny = Float.valueOf(indices[1].split("/")[2]); 
        nz = Float.valueOf(indices[2].split("/")[2]); 

        group.addFace(new ModelFace(new Vector4f(vx, vy, vz, vw), new Vector3f(u, v, tw), new Vector3f(nx, ny, nz)).setPolygonType(polygon_type)); 
       } 
       else if(mode == 3) 
       { 
        float vx, vy, vz, vw; 
        float nx, ny, nz; 

        System.out.println(indices[0]); 

        vx = Float.valueOf(indices[0].split("//")[0]); 
        vy = Float.valueOf(indices[1].split("//")[0]); 
        vz = Float.valueOf(indices[2].split("//")[0]); 

        if(indices.length == 4) 
         vw = Float.valueOf(indices[3].split("//")[0]); 
        else 
         vw = -1; 

        nx = Float.valueOf(indices[0].split("//")[1]); 
        ny = Float.valueOf(indices[1].split("//")[1]); 
        nz = Float.valueOf(indices[2].split("//")[1]); 

        group.addFace(new ModelFace(new Vector4f(vx, vy, vz, vw), new Vector3f(-1, 0, 0), new Vector3f(nx, ny, nz)).setPolygonType(polygon_type)); 
       } 
      } 
     } 

     groups.put(group.getGroupName(), group); 
     in.close(); 
    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 
} 

public Vector3f getPosition() { 
    return position; 
} 

public void setPosition(Vector3f position) { 
    this.position = position; 
} 

public Vector3f getRotation() { 
    return rotation; 
} 

public void setRotation(Vector3f rotation) { 
    this.rotation = rotation; 
} 

public void draw() 
{ 
    ArrayList<ModelGroup> groups = new ArrayList<ModelGroup>(this.groups.values()); 

    for(int i = 0; i < groups.size(); i++) 
     drawGroup(groups.get(i).getGroupName()); 
} 

public void drawGroup(String name) 
{ 
    ModelGroup group = groups.get(name); 

    if(group == null) 
     return; 

    glPushMatrix(); 
    { 
     glRotatef(rotation.x, 1, 0, 0); 
     glRotatef(rotation.y, 0, 1, 0); 
     glRotatef(rotation.z, 0, 0, 1); 
     glTranslatef(position.x, position.y, position.z); 

     for(ModelFace face : group.getFaces()) 
     { 
      glBegin(face.getPolygonType()); 
      { 
       for(int id = 0; id < 3; id++) 
       { 
        Vector4f vertex = group.getVertices().get(face.getVerticeIndex(id)); 
        glVertex4f(vertex.x, vertex.y, vertex.z, vertex.w); 

        if(face.hasTextureCoordinates()) 
        { 
         Vector3f textureCoordinate = group.getTextureCoordinates().get(face.getTextureCoordinateIndex(id)); 
         glTexCoord3f(textureCoordinate.x, textureCoordinate.y, textureCoordinate.z); 
        } 

        if(face.hasNormals()) 
        { 
         Vector3f normal = group.getNormals().get(face.getNormalIndex(id)); 
         glNormal3f(normal.x, normal.y, normal.z); 
        } 
       } 

       if(face.getPolygonType() == GL_QUADS) 
       { 
        Vector4f vertex = group.getVertices().get(face.getVerticeIndex(3)); 
        glVertex4f(vertex.x, vertex.y, vertex.z, vertex.w); 
       } 
      } 
      glEnd(); 
     } 
    } 
    glPopMatrix(); 
} 

//====================================================================================================// 

private class ModelGroup 
{ 
    private final String groupName; 

    private ArrayList<Vector4f> vertices = new ArrayList<Vector4f>(); 
    private ArrayList<Vector3f> normals = new ArrayList<Vector3f>(); 
    private ArrayList<Vector3f> textureCoordinates = new ArrayList<Vector3f>(); 
    private ArrayList<ModelFace> faces = new ArrayList<ModelFace>(); 

    public ModelGroup(String name) { 
     this.groupName = name; 
    } 

    public String getGroupName() { 
     return this.groupName; 
    } 

    public void addVertice(Vector4f vertice) { 
     this.vertices.add(vertice); 
    } 

    public ArrayList<Vector4f> getVertices() { 
     return this.vertices; 
    } 

    public void addNormal(Vector3f normal) { 
     this.normals.add(normal); 
    } 

    public ArrayList<Vector3f> getNormals() { 
     return this.normals; 
    } 

    public void addTextureCoordinate(Vector3f coordinate) { 
     this.textureCoordinates.add(coordinate); 
    } 

    public ArrayList<Vector3f> getTextureCoordinates() { 
     return this.textureCoordinates; 
    } 

    public void addFace(ModelFace face) { 
     this.faces.add(face); 
    } 

    public ArrayList<ModelFace> getFaces() { 
     return this.faces; 
    } 
} 

private class ModelFace { 

    private Vector4f vertices; 
    private Vector3f textureCoordinates, normals; 
    private int POLYGON_TYPE = 0; 

    private boolean hasTextureCoords = true, hasNormals = true; 

    public ModelFace(Vector4f vertices) { 
     this(vertices, new Vector3f(-1, 0, 0), new Vector3f(-1, 0, 0)); 
    } 

    public ModelFace(Vector4f vertices, Vector3f textureCoordinates, Vector3f normals) 
    { 
     this.vertices = vertices; 
     this.textureCoordinates = textureCoordinates; 
     this.normals = normals; 

     if(this.textureCoordinates.x == -1) 
      this.hasTextureCoords = false; 

     if(this.normals.x == -1) 
      this.hasNormals = false; 
    } 

    public boolean hasTextureCoordinates() { 
     return this.hasTextureCoords; 
    } 

    public boolean hasNormals() { 
     return this.hasNormals; 
    } 

    public int getVerticeIndex(int id) 
    { 
     if(id == 0) 
      return (int)vertices.x - 1; 
     else if(id == 1) 
      return (int)vertices.y - 1; 
     else if(id == 2) 
      return (int)vertices.z - 1; 
     else if(id == 3) 
      return (int)vertices.w - 1; 
     else 
      return -1; 
    } 

    public int getTextureCoordinateIndex(int id) 
    { 
     if(id == 0) 
      return (int)textureCoordinates.x - 1; 
     else if(id == 1) 
      return (int)textureCoordinates.y - 1; 
     else if(id == 2) 
      return (int)textureCoordinates.z - 1; 
     else 
      return -1; 
    } 

    public int getNormalIndex(int id) 
    { 
     if(id == 0) 
      return (int)textureCoordinates.x - 1; 
     else if(id == 1) 
      return (int)textureCoordinates.y - 1; 
     else if(id == 2) 
      return (int)textureCoordinates.z - 1; 
     else 
      return -1; 
    } 

    public ModelFace setPolygonType(int type) { 
     this.POLYGON_TYPE = type; 
     return this; 
    } 

    public int getPolygonType() { 
     return this.POLYGON_TYPE; 
    } 
} 
} 

感謝, 利亞姆。

回答

0

好的,我解決了這個問題。

它在模型構造函數代碼中,while循環完成時它沒有將最後一個組添加到列表中。這意味着如果只有一個組(或沒有),它不會被添加到列表中,也不會被渲染。

我已經在這個問題改變了型號代碼,以便它是可用的,隨意使用它在你的項目

親切的問候, 利亞姆