ChibiSun
ChibiSun

Reputation: 21

Objects exported from Blender don't render properly

I recently started learning OpenGL, I wanted to advance from the manually written cube and wanted to use models exported from Blender. The easiest way seemed to be by parsing .obj files so I made a parser.

It works but not quite well, I stumbled upon a problem when I wanted to learn about lights. The reflections and shadows weren't right at all. They made no sense in relation to where the light was. So I rendered in wireframe mode and to my surprize, there were some extra faces that weren't supposed to be there.

Screenshot: http://img5.imageshack.us/img5/5937/582ff91c155b466495b2b02.png

I then generated the .obj file using the data I parsed and compared it using a diff tool to the original .obj file and nothing seems to be wrong. There are some missing zeros like 0.01 instead of 0.0100 but nothing else.

Here is my parser: http://pastebin.com/Aw8mdhJ9

Here is where I use the parsed data: pastebin.com/5Grt1WGf

And this is my toFloatBuffer:

public static FloatBuffer makeFloatBuffer(float[] arr) {
    ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);
    bb.order(ByteOrder.nativeOrder());
    FloatBuffer fb = bb.asFloatBuffer();
    fb.put(arr);
    fb.position(0);
    return fb;
}

Upvotes: 1

Views: 209

Answers (1)

ChibiSun
ChibiSun

Reputation: 21

After asking around the internet I found lots of different opinions. With a bit more study I figured out what was the problem. The problem was that the normals were per face and for OpenGL they need to be per vertex.

To fix this I rearranged the parsed data and made new indices. The problem is I am using more indices now and with the GL_UNSIGNED_SHORT limitation in OpenGL ES, my vertex count gets more limited.

Here is the code I used to fix the arrays:

private static void makeThingsWork() {
    int n_points = faces.length * 3;
    short count = 0;
    int j = 0;

    float[] fixedvertices = new float[n_points];
    float[] fixednormals = new float[n_points];
    short[] fixedfaces = new short[faces.length];

    for(int i = 0; i < n_points; i+=3)
    {
        j = i/3;
        fixedvertices[i] = vertices[faces[j]*3];
        fixedvertices[i+1] = vertices[faces[j]*3 + 1];
        fixedvertices[i+2] = vertices[faces[j]*3 + 2];

        fixednormals[i] = normals[normalIndices[j]*3];
        fixednormals[i+1] = normals[normalIndices[j]*3 + 1];
        fixednormals[i+2] = normals[normalIndices[j]*3 + 2];

        fixedfaces[i/3] = count;
        count++;
    }

    vertices = fixedvertices;
    normals = fixednormals;
    faces = fixedfaces;


}

Upvotes: 1

Related Questions