2 Stimmen

Ein in LWJGL geladenes OBJ-Modell hat einen schwarzen Bereich ohne Textur

Ich habe ein Problem mit dem Laden einer .obj-Datei in LWJGL und deren Texturen. Das Objekt ist ein Baum (es ist ein bezahltes Modell von TurboSquid, also kann ich es hier nicht posten, aber hier ist der Link, wenn Sie sehen wollen, wie es aussehen sollte): http://www.turbosquid.com/FullPreview/Index.cfm/ID/701294

Ich habe einen benutzerdefinierten OBJ-Lader geschrieben und dabei das LWJGL-Tutorial aus dem Wiki verwendet. Es sieht wie folgt aus:

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;
}
}

Dann erstelle ich mit diesem Code eine Anzeigeliste für mein Modell:

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 ist ein int - er enthält die ID der aktuell verwendeten Textur.

Mein Modell sieht also ohne Texturen absolut gut aus: 1

Aber schauen Sie, was passiert, wenn ich GL_TEXTURE_2D aktiviere:
2
3
4

Wie Sie sehen können, scheint eine ganze Seite des Baumes zu fehlen - und sie ist nicht transparent, da sie nicht in der Farbe des Hintergrunds ist - sie ist schwarz dargestellt.

Es ist kein Problem mit dem Modell - wenn ich es mit Kanjis OBJ-Loader lade, funktioniert es gut (aber die Sache ist, dass ich meinen eigenen OBJ-Loader schreiben muss) 5

Dies ist mein OpenGL-Init-Abschnitt:

//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);

Ich habe auch ein anderes Modell desselben Baums - viel detaillierter, direkt aus Blender exportiert - tut das Gleiche.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X