Question

I'm trying to write a basic Wavefront OBJ loader for my Android OpenGL ES 2.0 program. For now, I'm ignoring everything in an OBJ file except for vertices, normals, and faces. Here's what I've written so far:

InputStream inputStream = context.getResources().openRawResource(resourceID);

BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));

String line;

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]);
        verticesArrayList.add(x);
        verticesArrayList.add(y);
        verticesArrayList.add(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]);
        normalsArrayList.add(x);
        normalsArrayList.add(y);
        normalsArrayList.add(z);
    }
    else if(line.startsWith("f "))
    {
        // Loop 3 times for the 3 vertices/textures/normals associated with each face
        for(int i = 1; i <= 3; i++)
        {
            Short vertex = (short) (Short.valueOf(line.split(" ")[i].split("/")[0]) - 1);
            indicesArrayList.add(vertex);

            // Make a copy of my normals array list
            if(normalsArrayList2.size() == 0)
                normalsArrayList2 = new ArrayList<Float>(normalsArrayList);

            // Attempt to re-arrange the normals to match the order of the vertices
            int normal = Integer.valueOf(line.split(" ")[i].split("/")[2]) - 1;
            normalsArrayList2.add(vertex * 3, normalsArrayList.get(normal * 3));
            normalsArrayList2.add((vertex * 3) + 1, normalsArrayList.get((normal * 3) + 1));
            normalsArrayList2.add((vertex * 3) + 2, normalsArrayList.get((normal * 3) + 2));
        }
    }
}
reader.close();

However, I'm not sure if I'm setting my normals correctly. You see what I'm doing there at the bottom of my code? I'm trying to re-arrange the normals so that they match the order of the vertices. I'm doing this because I'm using the GLES20.glDrawElements() method like so:

// Get handle to vertex shader's aPosition member, enable the handle, and prepare the vertex data
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "aPosition");
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(mPositionHandle, COORDINATES_PER_VERTEX, GLES20.GL_FLOAT, false, VERTEX_STRIDE, verticesBuffer);

// Get handle to vertex shader's aNormal member, enable the handle, and prepare the vertex data
mNormalHandle = GLES20.glGetAttribLocation(mProgram, "aNormal");
GLES20.glEnableVertexAttribArray(mNormalHandle);
GLES20.glVertexAttribPointer(mNormalHandle, COORDINATES_PER_VERTEX, GLES20.GL_FLOAT, false, VERTEX_STRIDE, normalsBuffer);

// Draw the cube
GLES20.glDrawElements(GLES20.GL_TRIANGLES, numberOfIndices, GLES20.GL_UNSIGNED_SHORT, indicesBuffer);

I got the idea for this re-arranging from this site, after countless hours of Googling this subject.

However, something isn't going right. The lighting in my shader works for all the shapes I created manually with OpenGL, just not for the models I read in using my OBJ parser, so I don't think my lighting calculations are the problem, just how the normals are being calculated in my OBJ parser. Also, I opened my test OBJ files with Maya and used the "Vertex Normal Edit Tool" to visually verify that all of the normals are pointing the right way. Are there any glaring problems you can see with any of my code?

Was it helpful?

Solution

Use ArrayList's set() method instead of add()

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top