سؤال

Here is my problem. Im trying to read a wavefront obj file from assets and apparently it reads properly but when I try to draw the object on to the glsurfaceview 2 of the 8 triangles don't get draw and i don't know why.

This is the obj file (an octahedron):

# Blender v2.63 (sub 0) OBJ File: ''
# www.blender.org
mtllib octahedron.mtl
o Mesh_Object001.001
v 0.000000 -1.000000 -0.000000
v 1.000000 0.000000 0.000000
v 0.000000 -0.000000 1.000000
v -1.000000 0.000000 0.000000
v 0.000000 1.000000 0.000000
v 0.000000 0.000000 -1.000000
usemtl 
s off
f 1 2 3
f 4 1 3
f 5 4 3
f 2 5 3
f 2 1 6
f 1 4 6
f 4 5 6
f 5 2 6

this is the code to read the file:

public WaveFrontObj(InputStream file) throws IOException, WaveFrontObjExeption {
    color = new float[] { 1f, 0f, 0f, 1.0f };

    Log.i(MyApp_Tag, "WaveFrontObj: Starting to read file");

    BufferedReader br = new BufferedReader(new InputStreamReader(file));

    ArrayList<Float> vertexinfoarraylist = new ArrayList<Float>();
    ArrayList<Short> indexinfoarraylist = new ArrayList<Short>();

    while (br.ready()) {
        // Some string fixes
        String line = br.readLine().trim();

        while (line.contains("  ")) {
            line = line.replace("  ", " ");
        }
        // End string fixes

        // Comments lines should be avoided.
        if (line.startsWith("#"))
            continue;

        // Wavefront file body
        if (line.startsWith("v")) {
            String[] point_value = line.split(" ");

            Log.i(MyApp_Tag, "Vertex array lentth: " + point_value.length
                    + " at line " + line);

            for (int i = 1; i < point_value.length; i++) {
                try {
                    vertexinfoarraylist.add(Float
                            .parseFloat(point_value[i]));
                } catch (Exception ex) {
                    throw new WaveFrontObjExeption("Unrecognized string \""
                            + point_value[i] + "\" ant line \"" + line
                            + "\"");
                }
            }
        } else if (line.startsWith("f")) {
            String[] face_value = line.split(" ");

            Log.i(MyApp_Tag, "Index array length: " + face_value.length
                    + " at line " + line);

            for (int i = 1; i < face_value.length; i++) {
                try {
                    indexinfoarraylist.add(Short.parseShort(face_value[i]));
                } catch (Exception ex) {
                    throw new WaveFrontObjExeption("Unrecognized string \""
                            + face_value[i] + "\" ant line \"" + line
                            + "\"");
                }
            }
        } else {
            // avoid this lines for now
            // the end result should be a exception for
            // Unrecognized command.
            continue;
        }
    }

    if (!(vertexinfoarraylist.size() > 0 && indexinfoarraylist.size() > 0)) {
        throw new WaveFrontObjExeption("Object has no vertex or index inf.");
    } else {

        float[] vertexarrary = new float[vertexinfoarraylist.size()];
        short[] indexarrary = new short[indexinfoarraylist.size()];

        for (int i = 0; i < vertexinfoarraylist.size(); i++) {
            vertexarrary[i] = ((Float) vertexinfoarraylist.get(i));
            Log.i(MyApp_Tag, "Vertex Info #" + (i + 1) + ": "
                    + vertexinfoarraylist.get(i));
        }

        for (int i = 0; i < indexinfoarraylist.size(); i++) {
            indexarrary[i] = ((Short) indexinfoarraylist.get(i));
            Log.i(MyApp_Tag, "Index Info #" + (i + 1) + ": "
                    + indexinfoarraylist.get(i));
        }

        vertexCount = vertexinfoarraylist.size();
        vertexBuffer = ByteBuffer
                .allocateDirect(
                        BYTES_PER_FLOAT * COORDS_PER_VERTEX * vertexCount)
                .order(ByteOrder.nativeOrder()).asFloatBuffer();
        vertexBuffer.put(vertexarrary).position(0);

        indexCount = vertexinfoarraylist.size();
        indexBuffer = ByteBuffer
                .allocateDirect(
                        BYTES_PER_SHORT * COORDS_PER_VERTEX * indexCount)
                .order(ByteOrder.nativeOrder()).asShortBuffer();
        indexBuffer.put(indexarrary).position(0);

        int vertexShader = GameRenderer.loadShader(GLES20.GL_VERTEX_SHADER,
                vertexShaderCode);
        int fragmentShader = GameRenderer.loadShader(
                GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);

        // create empty OpenGL ES  Program
        mProgram = GLES20.glCreateProgram(); 

        // add the vertex shader to the opengl program
        GLES20.glAttachShader(mProgram, vertexShader); 

        // add the fragment shader to the opengl program
        GLES20.glAttachShader(mProgram, fragmentShader); 

        // creates an executable OpenGL ES program
        GLES20.glLinkProgram(mProgram); 
    }
}

And this is the code to draw the object into opengl GLES20:

public void draw(float[] mvpMatrix) {
    // Add program to OpenGL ES environment
    GLES20.glUseProgram(mProgram);

    // get handle to vertex shader's vPosition member
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");

    // Enable a handle to the triangle vertices
    GLES20.glEnableVertexAttribArray(mPositionHandle);

    // Prepare the vertex coordinate data
    GLES20.glVertexAttribPointer(mPositionHandle,
            COORDS_PER_VERTEX,
            GLES20.GL_FLOAT,
            false,
            0,  // No space between vertex
            vertexBuffer);


    GLES20.glEnableVertexAttribArray(mPositionHandle);

    // get handle to fragment shader's vColor member
    mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");

    // Set color for drawing the triangle
    GLES20.glUniform4fv(mColorHandle, 1, color, 0);

    // get handle to shape's transformation matrix
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");

    // Apply the projection and view transformation
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);

    // Draw the object
    GLES20.glDrawElements(GLES20.GL_TRIANGLE_FAN, indexBuffer.capacity(), GLES20.GL_UNSIGNED_SHORT, indexBuffer);
    //GLES20.glDrawElements(GLES20.GL_TRIANGLE_STRIP, indexBuffer.capacity(), GLES20.GL_UNSIGNED_SHORT, indexBuffer);
    //GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

    // Disable vertex array
    GLES20.glDisableVertexAttribArray(mPositionHandle);
}
هل كانت مفيدة؟

المحلول

This content is contained upstairs on the comments:

One other note is that the format specifies indecies as 1-based, but in your code they are probably 0-based, so you should subtract one when parsing faces.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top