How to load and display .obj file in Android with OpenGL-ES 2

前端 未结 3 2010
无人及你
无人及你 2020-12-29 05:49

I am trying to load an .obj file into my Android application and display it using OpenGL 2.

You can find the file here: EDIT: I removed the file, yo

3条回答
  •  攒了一身酷
    2020-12-29 06:23

    I ended up writing a new parser, it can be used like this to build FloatBuffers to use in your Renderer:

    ObjLoader objLoader = new ObjLoader(context, "Mug.obj");
    
    numFaces = objLoader.numFaces;
    
    // Initialize the buffers.
    positions = ByteBuffer.allocateDirect(objLoader.positions.length * mBytesPerFloat)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    positions.put(objLoader.positions).position(0);
    
    normals = ByteBuffer.allocateDirect(objLoader.normals.length * mBytesPerFloat)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    normals.put(objLoader.normals).position(0);
    
    textureCoordinates = ByteBuffer.allocateDirect(objLoader.textureCoordinates.length * mBytesPerFloat)
            .order(ByteOrder.nativeOrder()).asFloatBuffer();
    textureCoordinates.put(objLoader.textureCoordinates).position(0);
    

    and here's the parser:

    public final class ObjLoader {
    
        public final int numFaces;
    
        public final float[] normals;
        public final float[] textureCoordinates;
        public final float[] positions;
    
        public ObjLoader(Context context, String file) {
    
            Vector vertices = new Vector<>();
            Vector normals = new Vector<>();
            Vector textures = new Vector<>();
            Vector faces = new Vector<>();
    
            BufferedReader reader = null;
            try {
                InputStreamReader in = new InputStreamReader(context.getAssets().open(file));
                reader = new BufferedReader(in);
    
                // read file until EOF
                String line;
                while ((line = reader.readLine()) != null) {
                    String[] parts = line.split(" ");
                    switch (parts[0]) {
                        case "v":
                            // vertices
                            vertices.add(Float.valueOf(parts[1]));
                            vertices.add(Float.valueOf(parts[2]));
                            vertices.add(Float.valueOf(parts[3]));
                            break;
                        case "vt":
                            // textures
                            textures.add(Float.valueOf(parts[1]));
                            textures.add(Float.valueOf(parts[2]));
                            break;
                        case "vn":
                            // normals
                            normals.add(Float.valueOf(parts[1]));
                            normals.add(Float.valueOf(parts[2]));
                            normals.add(Float.valueOf(parts[3]));
                            break;
                        case "f":
                            // faces: vertex/texture/normal
                            faces.add(parts[1]);
                            faces.add(parts[2]);
                            faces.add(parts[3]);
                            break;
                    }
                }
            } catch (IOException e) {
                // cannot load or read file
            } finally {
                if (reader != null) {
                    try {
                        reader.close();
                    } catch (IOException e) {
                        //log the exception
                    }
                }
            }
    
            numFaces = faces.size();
            this.normals = new float[numFaces * 3];
            textureCoordinates = new float[numFaces * 2];
            positions = new float[numFaces * 3];
            int positionIndex = 0;
            int normalIndex = 0;
            int textureIndex = 0;
            for (String face : faces) {
                String[] parts = face.split("/");
    
                int index = 3 * (Short.valueOf(parts[0]) - 1);
                positions[positionIndex++] = vertices.get(index++);
                positions[positionIndex++] = vertices.get(index++);
                positions[positionIndex++] = vertices.get(index);
    
                index = 2 * (Short.valueOf(parts[1]) - 1);
                textureCoordinates[normalIndex++] = textures.get(index++);
                // NOTE: Bitmap gets y-inverted
                textureCoordinates[normalIndex++] = 1 - textures.get(index);
    
                index = 3 * (Short.valueOf(parts[2]) - 1);
                this.normals[textureIndex++] = normals.get(index++);
                this.normals[textureIndex++] = normals.get(index++);
                this.normals[textureIndex++] = normals.get(index);
            }
        }
    }
    

提交回复
热议问题