Подтвердить что ты не робот

Как загрузить и отобразить файл .obj в Android с OpenGL-ES 2

Я пытаюсь загрузить файл .obj в свое приложение для Android и отображать его с помощью OpenGL 2.

Вы можете найти файл здесь: EDIT: я удалил файл, вы можете использовать любой файл .obj, содержащий значения, указанные ниже для тестирования.

В stackoverflow есть много похожих вопросов, но я не нашел простого решения, которое не требует большой библиотеки.

Файл содержит только следующие типы значений:

  • г
  • v
  • В.Т.
  • уп
  • F

Я попробовал libgdx, который работал нормально, но это немного переборщик для того, что мне нужно.

Я попробовал oObjLoader https://github.com/seanrowens/oObjLoader без LWJGL. По-видимому, синтаксический анализ работает, но как я могу отображать значения в простой сцене?

Следующим шагом будет присоединение изображения к текстуре к объекту. Но пока я был бы рад отобразить файл как есть.

Я открыт для различных решений, таких как предварительная конвертация файла, потому что это будет только один из них в приложении.

Спасибо!

Обновление статуса Базовая загрузка и показ работ теперь, как показано в моем собственном ответе.

4b9b3361

Ответ 1

В конце концов я написал новый синтаксический анализатор, его можно использовать для создания FloatBuffers для использования в вашем 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);

и здесь синтаксический анализатор:

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<Float> vertices = new Vector<>();
        Vector<Float> normals = new Vector<>();
        Vector<Float> textures = new Vector<>();
        Vector<String> 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);
        }
    }
}

Ответ 2

Как вы можете разобрать файлы obj, обратитесь к этому сообщению , который может вам очень помочь.

Существует более простой способ: используйте tr.js objloader. Используйте XWalkView для добавления веб-страницы в приложение Android. XWalkView - это что-то вроде webview, здесь workview может не работать для рендеринга сложной сцены, пока есть XWalkView. Если вы не удалите веб-страницу, вы можете сделать ее локальной.