OBJ model loaded in LWJGL has a black area with no texture

Posted by gambiting on Stack Overflow See other posts from Stack Overflow or by gambiting
Published on 2012-12-09T23:02:46Z Indexed on 2012/12/09 23:03 UTC
Read the original article Hit count: 560

Filed under:
|
|
|
|

I have a problem with loading an .obj file in LWJGL and its textures. The object is a tree(it's a paid model from TurboSquid, so I can't post it here,but here's the link if you want to see how it should look like): http://www.turbosquid.com/FullPreview/Index.cfm/ID/701294

I wrote a custom OBJ loader using the LWJGL tutorial from their wiki. It looks like this:

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

Then I create a display list for my model using this code:

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

The currentTexture is an int - it contains the ID of the currently used texture.

So my model looks absolutely fine without textures: (sorry I cannot post hyperlinks since I am a new user) i.imgur.com/VtoK0.png

But look what happens if I enable GL_TEXTURE_2D:
i.imgur.com/z8Kli.png
i.imgur.com/5e9nn.png
i.imgur.com/FAHM9.png

As you can see an entire side of the tree appears to be missing - and it's not transparent, since it's not in the colour of the background - it's rendered black.

It's not a problem with the model - if I load it using Kanji's OBJ loader it works fine(but the thing is,that I need to write my own OBJ loader) i.imgur.com/YDATo.png

this is my OpenGL init section:

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

Could somebody please help me?

© Stack Overflow or respective owner

OBJ model loaded in LWJGL has a black area with no texture

Posted by gambiting on Game Development See other posts from Game Development or by gambiting
Published on 2012-12-09T21:41:27Z Indexed on 2012/12/09 23:45 UTC
Read the original article Hit count: 560

Filed under:
|
|
|

I have a problem with loading an .obj file in LWJGL and its textures. The object is a tree(it's a paid model from TurboSquid, so I can't post it here,but here's the link if you want to see how it should look like): http://www.turbosquid.com/FullPreview/Index.cfm/ID/701294

I wrote a custom OBJ loader using the LWJGL tutorial from their wiki. It looks like this:

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

Then I create a display list for my model using this code:

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

The currentTexture is an int - it contains the ID of the currently used texture.

So my model looks absolutely fine without textures: (sorry I cannot post hyperlinks since I am a new user) i.imgur.com/VtoK0.png

But look what happens if I enable GL_TEXTURE_2D:
i.imgur.com/z8Kli.png
i.imgur.com/5e9nn.png
i.imgur.com/FAHM9.png

As you can see an entire side of the tree appears to be missing - and it's not transparent, since it's not in the colour of the background - it's rendered black.

It's not a problem with the model - if I load it using Kanji's OBJ loader it works fine(but the thing is,that I need to write my own OBJ loader) i.imgur.com/YDATo.png

this is my OpenGL init section:

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

Could somebody please help me?

© Game Development or respective owner

Related posts about java

Related posts about opengl