web-dev-qa-db-ja.com

OpenGL-ES 2でAndroidに.objファイルをロードして表示する方法

.objファイルをAndroid=アプリケーションにロードし、OpenGL 2を使用して表示しようとしています。

ここでファイルを見つけることができます:編集:ファイルを削除しました、以下のテストを含む値を含む.objファイルを使用できます。

Stackoverflowにも同様の質問がたくさんありますが、大きなライブラリを必要としない簡単な解決策は見つかりませんでした。

ファイルには、次の値タイプのみが含まれています。

  • g
  • v
  • vt
  • vn
  • f

私はlibgdxを試しましたが、うまくいきましたが、私が必要とするものには少々やり過ぎです。

LWJGLなしでoObjLoader https://github.com/seanrowens/oObjLoader を試しました。解析は機能しているようですが、単純なシーンで値を表示するにはどうすればよいですか?

次のステップは、画像をテクスチャとしてオブジェクトに添付することです。しかし、今のところ、ファイルをそのまま表示させていただければ幸いです。

これはアプリケーション内ではこれだけであるため、ファイルの事前変換などのさまざまなソリューションを利用できます。

ありがとう!

Status update基本的な読み込みと表示が動作するようになりました。

19
Björn Kechel

私は新しいパーサーを作成することになりました。レンダラーで使用するFloatBufferを構築するために、次のように使用できます。

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);
        }
    }
}
7
Björn Kechel

Objファイルを解析できるので、これを参照してください post が非常に役立ちます。

より簡単な方法は、three.js objloader を使用することです。 XWalkViewを使用してWebページを追加するAndroid app。XWalkViewはwebviewのようなものです。ここでは、XWalkViewがレンダリングしている間、workviewが複雑なシーンのレンダリングに機能しない可能性があります。Webページをリモートにしないと、ローカルにすることができます。

0
Kris Roofe